diff --git a/.changeset/nasty-heads-check.md b/.changeset/nasty-heads-check.md new file mode 100644 index 00000000000..b3796b69bbb --- /dev/null +++ b/.changeset/nasty-heads-check.md @@ -0,0 +1,6 @@ +--- +'@qwik.dev/router': major +'@qwik.dev/core': major +--- + +BREAKING: Qwik and Qwik Router no longer provide .cjs builds. The tooling ecosystem can now handle ESM modules well. diff --git a/packages/docs/src/routes/docs/(qwik)/advanced/library/index.mdx b/packages/docs/src/routes/docs/(qwik)/advanced/library/index.mdx index 4d9f657bdd0..741cebd8f1e 100644 --- a/packages/docs/src/routes/docs/(qwik)/advanced/library/index.mdx +++ b/packages/docs/src/routes/docs/(qwik)/advanced/library/index.mdx @@ -74,7 +74,6 @@ The most important files of a library are a properly configured `package.json` a "exports": { ".": { "import": "./lib/index.qwik.mjs", - "require": "./lib/index.qwik.cjs", "types": "./lib-types/index.d.ts" } }, @@ -102,8 +101,8 @@ export default defineConfig(() => { target: 'es2020', lib: { entry: './src/index.ts', - formats: ['es', 'cjs'], - fileName: (format) => `index.qwik.${format === 'es' ? 'mjs' : 'cjs'}`, + formats: ['es'], + fileName: 'index.qwik.mjs', }, }, plugins: [qwikVite()], diff --git a/packages/qwik-router/package.json b/packages/qwik-router/package.json index a732509a81a..1f10e4c32f7 100644 --- a/packages/qwik-router/package.json +++ b/packages/qwik-router/package.json @@ -48,63 +48,51 @@ "exports": { ".": { "types": "./lib/index.d.ts", - "import": "./lib/index.qwik.mjs", - "require": "./lib/index.qwik.cjs" + "import": "./lib/index.qwik.mjs" }, "./adapters/azure-swa/vite": { "types": "./lib/adapters/azure-swa/vite/index.d.ts", - "import": "./lib/adapters/azure-swa/vite/index.mjs", - "require": "./lib/adapters/azure-swa/vite/index.cjs" + "import": "./lib/adapters/azure-swa/vite/index.mjs" }, "./adapters/cloudflare-pages/vite": { "types": "./lib/adapters/cloudflare-pages/vite/index.d.ts", - "import": "./lib/adapters/cloudflare-pages/vite/index.mjs", - "require": "./lib/adapters/cloudflare-pages/vite/index.cjs" + "import": "./lib/adapters/cloudflare-pages/vite/index.mjs" }, "./adapters/cloud-run/vite": { "types": "./lib/adapters/cloud-run/vite/index.d.ts", - "import": "./lib/adapters/cloud-run/vite/index.mjs", - "require": "./lib/adapters/cloud-run/vite/index.cjs" + "import": "./lib/adapters/cloud-run/vite/index.mjs" }, "./adapters/bun-server/vite": { "types": "./lib/adapters/bun-server/vite/index.d.ts", - "import": "./lib/adapters/bun-server/vite/index.mjs", - "require": "./lib/adapters/bun-server/vite/index.cjs" + "import": "./lib/adapters/bun-server/vite/index.mjs" }, "./adapters/deno-server/vite": { "types": "./lib/adapters/deno-server/vite/index.d.ts", - "import": "./lib/adapters/deno-server/vite/index.mjs", - "require": "./lib/adapters/deno-server/vite/index.cjs" + "import": "./lib/adapters/deno-server/vite/index.mjs" }, "./adapters/node-server/vite": { "types": "./lib/adapters/node-server/vite/index.d.ts", - "import": "./lib/adapters/node-server/vite/index.mjs", - "require": "./lib/adapters/node-server/vite/index.cjs" + "import": "./lib/adapters/node-server/vite/index.mjs" }, "./adapters/netlify-edge/vite": { "types": "./lib/adapters/netlify-edge/vite/index.d.ts", - "import": "./lib/adapters/netlify-edge/vite/index.mjs", - "require": "./lib/adapters/netlify-edge/vite/index.cjs" + "import": "./lib/adapters/netlify-edge/vite/index.mjs" }, "./adapters/shared/vite": { "types": "./lib/adapters/shared/vite/index.d.ts", - "import": "./lib/adapters/shared/vite/index.mjs", - "require": "./lib/adapters/shared/vite/index.cjs" + "import": "./lib/adapters/shared/vite/index.mjs" }, "./adapters/static/vite": { "types": "./lib/adapters/ssg/vite/index.d.ts", - "import": "./lib/adapters/ssg/vite/index.mjs", - "require": "./lib/adapters/ssg/vite/index.cjs" + "import": "./lib/adapters/ssg/vite/index.mjs" }, "./adapters/ssg/vite": { "types": "./lib/adapters/ssg/vite/index.d.ts", - "import": "./lib/adapters/ssg/vite/index.mjs", - "require": "./lib/adapters/ssg/vite/index.cjs" + "import": "./lib/adapters/ssg/vite/index.mjs" }, "./adapters/vercel-edge/vite": { "types": "./lib/adapters/vercel-edge/vite/index.d.ts", - "import": "./lib/adapters/vercel-edge/vite/index.mjs", - "require": "./lib/adapters/vercel-edge/vite/index.cjs" + "import": "./lib/adapters/vercel-edge/vite/index.mjs" }, "./middleware/azure-swa": { "types": "./lib/middleware/azure-swa/index.d.ts", @@ -136,13 +124,11 @@ }, "./middleware/node": { "types": "./lib/middleware/node/index.d.ts", - "import": "./lib/middleware/node/index.mjs", - "require": "./lib/middleware/node/index.cjs" + "import": "./lib/middleware/node/index.mjs" }, "./middleware/request-handler": { "types": "./lib/middleware/request-handler/index.d.ts", - "import": "./lib/middleware/request-handler/index.mjs", - "require": "./lib/middleware/request-handler/index.cjs" + "import": "./lib/middleware/request-handler/index.mjs" }, "./middleware/vercel-edge": { "types": "./lib/middleware/vercel-edge/index.d.ts", @@ -150,23 +136,19 @@ }, "./static": { "types": "./lib/ssg/index.d.ts", - "import": "./lib/ssg/index.mjs", - "require": "./lib/ssg/index.cjs" + "import": "./lib/ssg/index.mjs" }, "./ssg": { "types": "./lib/ssg/index.d.ts", - "import": "./lib/ssg/index.mjs", - "require": "./lib/ssg/index.cjs" + "import": "./lib/ssg/index.mjs" }, "./vite": { "types": "./lib/vite/index.d.ts", - "import": "./lib/vite/index.mjs", - "require": "./lib/vite/index.cjs" + "import": "./lib/vite/index.mjs" }, "./service-worker": { "types": "./service-worker.d.ts", - "import": "./lib/service-worker.mjs", - "require": "./lib/service-worker.cjs" + "import": "./lib/service-worker.mjs" }, "./package.json": "./package.json" }, diff --git a/packages/qwik-router/src/buildtime/vite/plugin.ts b/packages/qwik-router/src/buildtime/vite/plugin.ts index 926fb76232d..c0de5f9f31d 100644 --- a/packages/qwik-router/src/buildtime/vite/plugin.ts +++ b/packages/qwik-router/src/buildtime/vite/plugin.ts @@ -46,7 +46,6 @@ function qwikRouterPlugin(userOpts?: QwikRouterVitePluginOptions): any { let mdxTransform: MdxTransform | null = null; let rootDir: string | null = null; let qwikPlugin: QwikVitePlugin | null; - let ssrFormat: 'esm' | 'cjs' = 'esm'; let outDir: string | null = null; let viteCommand: string; let devServer: ViteDevServer | null = null; @@ -159,10 +158,6 @@ function qwikRouterPlugin(userOpts?: QwikRouterVitePluginOptions): any { return getRouteImports(ctx!.routes, manifest); }); - // @ts-ignore `format` removed in Vite 5 - if (config.ssr?.format === 'cjs') { - ssrFormat = 'cjs'; - } outDir = config.build?.outDir; }, @@ -331,7 +326,7 @@ function qwikRouterPlugin(userOpts?: QwikRouterVitePluginOptions): any { sequential: true, async handler() { if (ctx?.target === 'ssr' && outDir) { - await generateServerPackageJson(outDir, ssrFormat); + await generateServerPackageJson(outDir); } }, }, @@ -340,7 +335,7 @@ function qwikRouterPlugin(userOpts?: QwikRouterVitePluginOptions): any { return plugin; } -async function generateServerPackageJson(outDir: string, ssrFormat: 'esm' | 'cjs') { +async function generateServerPackageJson(outDir: string) { await fs.promises.mkdir(outDir, { recursive: true }); const serverPackageJsonPath = join(outDir, 'package.json'); @@ -357,7 +352,7 @@ async function generateServerPackageJson(outDir: string, ssrFormat: 'esm' | 'cjs packageJson = { ...packageJson, - type: ssrFormat == 'cjs' ? 'commonjs' : 'module', + type: 'module', }; const serverPackageJsonCode = JSON.stringify(packageJson, null, 2); diff --git a/packages/qwik-router/vite.config.mts b/packages/qwik-router/vite.config.mts index 684d04c65c4..0ba8e5922e5 100644 --- a/packages/qwik-router/vite.config.mts +++ b/packages/qwik-router/vite.config.mts @@ -48,15 +48,6 @@ export default defineConfig(() => { entryFileNames: (chunkInfo) => chunkInfo.name === 'index' ? '[name].qwik.mjs' : '[name]/index.mjs', }, - { - format: 'cjs', - chunkFileNames: (chunkInfo) => - chunkInfo.moduleIds.some((id) => id.includes('runtime')) - ? 'chunks/[name].qwik.cjs' - : 'chunks/[name].cjs', - entryFileNames: (chunkInfo) => - chunkInfo.name === 'index' ? '[name].qwik.cjs' : '[name]/index.cjs', - }, ], external: [ /node:.*/, diff --git a/packages/qwik/package.json b/packages/qwik/package.json index 5f75a83e52e..c1b17ea0ce4 100644 --- a/packages/qwik/package.json +++ b/packages/qwik/package.json @@ -35,11 +35,6 @@ "production": "./dist/core.prod.mjs", "min": "./dist/core.min.mjs", "default": "./dist/core.prod.mjs" - }, - "require": { - "development": "./dist/core.cjs", - "production": "./dist/core.prod.cjs", - "default": "./dist/core.prod.cjs" } }, "./cli": { @@ -53,11 +48,6 @@ "production": "./dist/core.prod.mjs", "min": "./dist/core.min.mjs", "default": "./dist/core.prod.mjs" - }, - "require": { - "development": "./dist/core.cjs", - "production": "./dist/core.prod.cjs", - "default": "./dist/core.prod.cjs" } }, "./jsx-runtime": { @@ -67,11 +57,6 @@ "production": "./dist/core.prod.mjs", "min": "./dist/core.min.mjs", "default": "./dist/core.prod.mjs" - }, - "require": { - "development": "./dist/core.cjs", - "production": "./dist/core.prod.cjs", - "default": "./dist/core.prod.cjs" } }, "./jsx-dev-runtime": { @@ -81,11 +66,6 @@ "production": "./dist/core.prod.mjs", "min": "./dist/core.min.mjs", "default": "./dist/core.mjs" - }, - "require": { - "development": "./dist/core.cjs", - "production": "./dist/core.prod.cjs", - "default": "./dist/core.cjs" } }, "./build": { @@ -94,50 +74,36 @@ "development": "./dist/build/index.dev.mjs", "production": "./dist/build/index.prod.mjs", "default": "./dist/build/index.mjs" - }, - "require": { - "development": "./dist/build/index.dev.cjs", - "production": "./dist/build/index.prod.cjs", - "default": "./dist/build/index.cjs" } }, "./loader": { "types": "./dist/loader/index.d.ts", - "import": "./dist/loader/index.mjs", - "require": "./dist/loader/index.cjs" + "import": "./dist/loader/index.mjs" }, "./insights": { "types": "./dist/insights.d.ts", - "import": "./dist/insights/index.qwik.mjs", - "require": "./dist/insights/index.qwik.cjs" + "import": "./dist/insights/index.qwik.mjs" }, "./insights/vite": { "types": "./dist/insights/vite.d.ts", - "import": "./dist/insights/vite/index.mjs", - "require": "./dist/insights/vite/index.cjs" + "import": "./dist/insights/vite/index.mjs" }, - "./optimizer.cjs": "./dist/optimizer.cjs", "./optimizer.mjs": "./dist/optimizer.mjs", "./optimizer": { "types": "./dist/optimizer.d.ts", - "import": "./dist/optimizer.mjs", - "require": "./dist/optimizer.cjs" + "import": "./dist/optimizer.mjs" }, "./preloader": { - "import": "./dist/preloader.mjs", - "require": "./dist/preloader.cjs" + "import": "./dist/preloader.mjs" }, - "./server.cjs": "./dist/server.cjs", "./server.mjs": "./dist/server.mjs", "./server": { "types": "./server.d.ts", - "import": "./dist/server.mjs", - "require": "./dist/server.cjs" + "import": "./dist/server.mjs" }, "./testing": { "types": "./dist/testing/index.d.ts", - "import": "./dist/testing/index.mjs", - "require": "./dist/testing/index.cjs" + "import": "./dist/testing/index.mjs" }, "./qwikloader.js": "./dist/qwikloader.js", "./qwikloader.debug.js": "./dist/qwikloader.debug.js", @@ -205,7 +171,9 @@ "url": "https://github.com/QwikDev/qwik.git", "directory": "packages/qwik" }, - "sideEffects": false, + "sideEffects": [ + "./src/testing/vdom-diff.unit-util.ts" + ], "scripts": { "build.insights": "cd src/insights && vite build --mode lib --emptyOutDir" }, diff --git a/packages/qwik/src/backpatch-executor.ts b/packages/qwik/src/backpatch-executor.ts index 23e8a7b46c7..23d25861bea 100644 --- a/packages/qwik/src/backpatch-executor.ts +++ b/packages/qwik/src/backpatch-executor.ts @@ -5,6 +5,9 @@ * same container and applying the patches to the DOM elements. */ +// needed to make this a module and make compiled-string-plugin work +export {}; + const BACKPATCH_DATA_SELECTOR = 'script[type="qwik/backpatch"]'; const executorScript = document.currentScript; diff --git a/packages/qwik/src/core/shared/platform/platform.ts b/packages/qwik/src/core/shared/platform/platform.ts index 5dc7b25da7c..14621d15155 100644 --- a/packages/qwik/src/core/shared/platform/platform.ts +++ b/packages/qwik/src/core/shared/platform/platform.ts @@ -1,4 +1,3 @@ -// keep this import from core/build so the cjs build works import { isServer } from '@qwik.dev/core/build'; import { QError, qError } from '../error/error'; import { getSymbolHash } from '../qrl/qrl-utils'; diff --git a/packages/qwik/src/core/shared/serdes/serialize.ts b/packages/qwik/src/core/shared/serdes/serialize.ts index 18bad847998..7161af8f64b 100644 --- a/packages/qwik/src/core/shared/serdes/serialize.ts +++ b/packages/qwik/src/core/shared/serdes/serialize.ts @@ -1,6 +1,6 @@ import { isDev } from '@qwik.dev/core/build'; -import { VNodeDataFlag } from 'packages/qwik/src/server/types'; -import type { VNodeData } from 'packages/qwik/src/server/vnode-data'; +import { VNodeDataFlag } from '../../../server/types'; +import type { VNodeData } from '../../../server/vnode-data'; import { vnode_isVNode } from '../../client/vnode'; import { _EFFECT_BACK_REF } from '../../internal'; import { AsyncComputedSignalImpl } from '../../reactive-primitives/impl/async-computed-signal-impl'; diff --git a/packages/qwik/src/optimizer/src/platform.ts b/packages/qwik/src/optimizer/src/platform.ts index 522a21288fb..399c881a508 100644 --- a/packages/qwik/src/optimizer/src/platform.ts +++ b/packages/qwik/src/optimizer/src/platform.ts @@ -6,7 +6,6 @@ import type { } from './types'; import { createPath } from './path'; import { QWIK_BINDING_MAP } from './qwik-binding-map'; -import { versions } from './versions'; export async function getSystem() { const sysEnv = getEnv(); @@ -30,37 +29,8 @@ export async function getSystem() { sys.path = createPath(sys); - if (globalThis.IS_ESM) { - sys.strictDynamicImport = sys.dynamicImport = (path) => import(path); - } - - if (globalThis.IS_CJS) { - if (sysEnv === 'node' || sysEnv === 'bun') { - // using this api object as a way to ensure bundlers - // do not try to inline or rewrite require() - sys.dynamicImport = (path) => require(path); - sys.strictDynamicImport = (path) => import(path); + sys.strictDynamicImport = sys.dynamicImport = (path) => import(path); - if (typeof TextEncoder === 'undefined') { - // TextEncoder/TextDecoder needs to be on the global scope for the WASM file - // https://nodejs.org/api/util.html#class-utiltextdecoder - const nodeUtil: typeof import('util') = await sys.dynamicImport('node:util'); - globalThis.TextEncoder = nodeUtil.TextEncoder; - globalThis.TextDecoder = nodeUtil.TextDecoder; - } - } else if (sysEnv === 'webworker' || sysEnv === 'browsermain') { - sys.strictDynamicImport = (path) => import(path); - sys.dynamicImport = async (path: string) => { - const cjsRsp = await fetch(path); - const cjsCode = await cjsRsp.text(); - const cjsModule: any = { exports: {} }; - // eslint-disable-next-line no-new-func - const cjsRun = new Function('module', 'exports', cjsCode); - cjsRun(cjsModule, cjsModule.exports); - return cjsModule.exports; - }; - } - } if (sysEnv !== 'webworker' && sysEnv !== 'browsermain') { try { sys.path = await sys.dynamicImport('node:path'); @@ -147,14 +117,10 @@ export async function loadPlatformBinding(sys: OptimizerSystem) { for (const triple of triples) { // Node.js - Native Binding try { - if (globalThis.IS_ESM) { - const module = await sys.dynamicImport('node:module'); - const mod = module.default.createRequire(import.meta.url)( - `../bindings/${triple.platformArchABI}` - ); - return mod; - } - const mod = await sys.dynamicImport(`../bindings/${triple.platformArchABI}`); + const module = await sys.dynamicImport('node:module'); + const mod = module.default.createRequire(import.meta.url)( + `../bindings/${triple.platformArchABI}` + ); return mod; } catch (e) { console.warn( @@ -167,83 +133,22 @@ export async function loadPlatformBinding(sys: OptimizerSystem) { } } - if (globalThis.IS_CJS) { - // CJS WASM - - if (sysEnv === 'node' || sysEnv === 'bun') { - // CJS WASM Node.js - const wasmPath = sys.path.join(__dirname, '..', 'bindings', 'qwik_wasm_bg.wasm'); - const mod = await sys.dynamicImport(`../bindings/qwik.wasm.cjs`); - const fs: typeof import('fs') = await sys.dynamicImport('node:fs'); - - const buf = await fs.promises.readFile(wasmPath); - const wasm = await WebAssembly.compile(buf as any); - await mod.default(wasm); - return mod; - } - - if (sysEnv === 'webworker' || sysEnv === 'browsermain') { - // CJS WASM Browser - let version = versions.qwik; - const cachedCjsCode = `qwikWasmCjs${version}`; - const cachedWasmRsp = `qwikWasmRsp${version}`; - - let cjsCode: string = (globalThis as any)[cachedCjsCode]; - let wasmRsp: Response = (globalThis as any)[cachedWasmRsp]; - - if (!cjsCode || !wasmRsp) { - version = versions.qwik.split('-dev')[0]; - const cdnUrl = `https://cdn.jsdelivr.net/npm/@qwik.dev/core@${version}/bindings/`; - const cjsModuleUrl = new URL(`./qwik.wasm.cjs`, cdnUrl).href; - const wasmUrl = new URL(`./qwik_wasm_bg.wasm`, cdnUrl).href; - - const rsps = await Promise.all([fetch(cjsModuleUrl), fetch(wasmUrl)]); - - for (const rsp of rsps) { - if (!rsp.ok) { - throw new Error(`Unable to fetch Qwik WASM binding from ${rsp.url}`); - } - } - - const cjsRsp = rsps[0]; - (globalThis as any)[cachedCjsCode] = cjsCode = await cjsRsp.text(); - (globalThis as any)[cachedWasmRsp] = wasmRsp = rsps[1]; - } - - const cjsModule: any = { exports: {} }; - // eslint-disable-next-line no-new-func - const cjsRun = new Function('module', 'exports', cjsCode); - cjsRun(cjsModule, cjsModule.exports); - const mod = cjsModule.exports; - - // init - await mod.default(wasmRsp.clone()); - - return mod; - } - } - - if (globalThis.IS_ESM) { - if (sysEnv === 'node' || sysEnv === 'bun') { - // ESM WASM Node.js - const url: typeof import('url') = await sys.dynamicImport('node:url'); - const __dirname = sys.path.dirname(url.fileURLToPath(import.meta.url)); - const wasmPath = sys.path.join(__dirname, '..', 'bindings', 'qwik_wasm_bg.wasm'); - const mod = await sys.dynamicImport(`../bindings/qwik.wasm.mjs`); - const fs: typeof import('fs') = await sys.dynamicImport('node:fs'); + if (sysEnv === 'node' || sysEnv === 'bun' || sysEnv === 'deno') { + const url: typeof import('url') = await sys.dynamicImport('node:url'); + const __dirname = sys.path.dirname(url.fileURLToPath(import.meta.url)); + const wasmPath = sys.path.join(__dirname, '..', 'bindings', 'qwik_wasm_bg.wasm'); + const mod = await sys.dynamicImport(`../bindings/qwik.wasm.mjs`); + const fs: typeof import('fs') = await sys.dynamicImport('node:fs'); - const buf = await fs.promises.readFile(wasmPath); - const wasm = await WebAssembly.compile(buf as any); - await mod.default(wasm); - return mod; - } else { - const module = await sys.dynamicImport(`../bindings/qwik.wasm.mjs`); - await module.default(); - return module; - } + const buf = await fs.promises.readFile(wasmPath); + const wasm = await WebAssembly.compile(buf as any); + await mod.default(wasm); + return mod; + } else { + const module = await sys.dynamicImport(`../bindings/qwik.wasm.mjs`); + await module.default(); + return module; } - - throw new Error(`Platform not supported`); } export interface PlatformBinding { @@ -302,7 +207,6 @@ const extensions: { [ext: string]: boolean } = { '.mjs': true, }; -declare const globalThis: { IS_CJS: boolean; IS_ESM: boolean; [key: string]: any }; declare const WorkerGlobalScope: any; declare const Deno: any; declare const Bun: any; diff --git a/packages/qwik/src/optimizer/src/plugins/plugin.ts b/packages/qwik/src/optimizer/src/plugins/plugin.ts index 1e0237c1d8b..a2f66aa6809 100644 --- a/packages/qwik/src/optimizer/src/plugins/plugin.ts +++ b/packages/qwik/src/optimizer/src/plugins/plugin.ts @@ -573,6 +573,7 @@ export function createQwikPlugin(optimizerOptions: OptimizerOptions = {}) { if (!key) { throw new Error('Failed to resolve @qwik.dev/core/handlers.mjs'); } + // handlers.mjs is to ensure these core exports don't get renamed ctx.emitFile({ id: key.id, type: 'chunk', diff --git a/packages/qwik/src/server/preload-strategy.ts b/packages/qwik/src/server/preload-strategy.ts index 128defd28cf..51c36c1aa86 100644 --- a/packages/qwik/src/server/preload-strategy.ts +++ b/packages/qwik/src/server/preload-strategy.ts @@ -8,17 +8,21 @@ import type { RenderToStringOptions } from './types'; const getBundles = (qrls: QRLInternal[]) => { const platform = getPlatform(); - return qrls - ?.map((qrl) => { - const symbol = qrl.$symbol$; - const chunk = qrl.$chunk$; - const result = platform.chunkForSymbol(symbol, chunk, qrl.dev?.file); - if (result) { - return result[1]; - } - return chunk; - }) - .filter(Boolean) as string[]; + return [ + ...new Set( + qrls + ?.map((qrl) => { + const symbol = qrl.$symbol$; + const chunk = qrl.$chunk$; + const result = platform.chunkForSymbol(symbol, chunk, qrl.dev?.file); + if (result) { + return result[1]; + } + return chunk; + }) + .filter(Boolean) as string[] + ), + ]; }; /** Returns paths to preload relative to the buildBase, with probabilities */ export function getPreloadPaths( diff --git a/packages/qwik/src/testing/rendering.unit-util.tsx b/packages/qwik/src/testing/rendering.unit-util.tsx index 4f5e1ebb730..4a82a460632 100644 --- a/packages/qwik/src/testing/rendering.unit-util.tsx +++ b/packages/qwik/src/testing/rendering.unit-util.tsx @@ -1,17 +1,14 @@ /* eslint-disable no-console */ import { Slot, componentQrl, render, type JSXOutput, type OnRenderFn } from '@qwik.dev/core'; -import { _getDomContainer } from '@qwik.dev/core/internal'; import type { _ContainerElement, _DomContainer, _VNode, _VirtualVNode, } from '@qwik.dev/core/internal'; -import { transformSync } from 'esbuild'; -import { readFileSync } from 'fs'; -import { join } from 'path'; -import { fileURLToPath } from 'url'; +import { _getDomContainer } from '@qwik.dev/core/internal'; import { expect } from 'vitest'; +import backpatcher from '../backpatch-executor?compiled-string'; import { vnode_getElementName, vnode_getFirstChild, @@ -279,25 +276,11 @@ export function emulateExecutionOfBackpatch(document: Document) { }; } - // we need esbuild to transpile from ts to js for the test environment - const __dirname = fileURLToPath(new URL('.', import.meta.url)); - const tsPath = join(__dirname, '../backpatch-executor.ts'); - const tsSource = readFileSync(tsPath, 'utf8'); - - const result = transformSync(tsSource, { - loader: 'ts', - target: 'es2020', - format: 'esm', - minify: false, - sourcemap: false, - }); - - const code = `try {${result.code}} catch (e) { console.error(e); }`; const script = document.createElement('script'); document.body.appendChild(script); (document as any).currentScript = script; try { - eval(code); + eval(`try {${backpatcher}} catch (e) { console.error(e); }`); } finally { (document as any).currentScript = null; document.body.removeChild(script); diff --git a/packages/supabase-auth-helpers-qwik/package.json b/packages/supabase-auth-helpers-qwik/package.json index e8195f32cfe..7ad737a5c28 100644 --- a/packages/supabase-auth-helpers-qwik/package.json +++ b/packages/supabase-auth-helpers-qwik/package.json @@ -13,8 +13,7 @@ "exports": { ".": { "types": "./lib/types/index.d.ts", - "import": "./lib/index.qwik.mjs", - "require": "./lib/index.qwik.cjs" + "import": "./lib/index.qwik.mjs" } }, "files": [ diff --git a/packages/supabase-auth-helpers-qwik/vite.config.mts b/packages/supabase-auth-helpers-qwik/vite.config.mts index cc61d20c191..bb4fc2b7ffe 100644 --- a/packages/supabase-auth-helpers-qwik/vite.config.mts +++ b/packages/supabase-auth-helpers-qwik/vite.config.mts @@ -2,31 +2,29 @@ import { qwikVite } from '@qwik.dev/core/optimizer'; import { defineConfig } from 'vite'; import pkg from './package.json'; -export default defineConfig((config) => { - return { - build: { - minify: false, - target: 'es2020', - outDir: 'lib', - lib: { - entry: ['./src/index.ts'], - formats: ['es', 'cjs'], - fileName: (format) => `index.qwik.${format === 'es' ? 'mjs' : 'cjs'}`, - }, - rollupOptions: { - external: [ - '@qwik.dev/core', - '@qwik.dev/router', - '@qwik.dev/core/build', - '@supabase/supabase-js', - '@supabase/auth-helpers-shared', - ], - }, +export default defineConfig({ + build: { + minify: false, + target: 'es2020', + outDir: 'lib', + lib: { + entry: ['./src/index.ts'], + formats: ['es'], + fileName: 'index.qwik.mjs', }, - define: { - PACKAGE_NAME: JSON.stringify(pkg.name), - PACKAGE_VERSION: JSON.stringify(pkg.version), + rollupOptions: { + external: [ + '@qwik.dev/core', + '@qwik.dev/router', + '@qwik.dev/core/build', + '@supabase/supabase-js', + '@supabase/auth-helpers-shared', + ], }, - plugins: [qwikVite()], - }; + }, + define: { + PACKAGE_NAME: JSON.stringify(pkg.name), + PACKAGE_VERSION: JSON.stringify(pkg.version), + }, + plugins: [qwikVite()], }) as any; diff --git a/scripts/binding-platform.ts b/scripts/binding-platform.ts index 107de966800..f66d3e70e14 100644 --- a/scripts/binding-platform.ts +++ b/scripts/binding-platform.ts @@ -128,7 +128,6 @@ export async function copyPlatformBindingWasm(config: BuildConfig) { 'qwik.darwin-arm64.node', 'qwik.darwin-x64.node', 'qwik.linux-x64-gnu.node', - 'qwik.wasm.cjs', 'qwik.wasm.mjs', 'qwik.win32-x64-msvc.node', 'qwik_wasm_bg.wasm', diff --git a/scripts/binding-wasm.ts b/scripts/binding-wasm.ts index bd1f98255aa..b4e2c67e66f 100644 --- a/scripts/binding-wasm.ts +++ b/scripts/binding-wasm.ts @@ -56,12 +56,6 @@ export async function buildWasmBinding(config: BuildConfig) { exports: 'named', }); - await build.write({ - format: 'cjs', - file: join(config.distBindingsDir, 'qwik.wasm.cjs'), - exports: 'named', - }); - await copyFile( join(tmpBuildDir, 'qwik_wasm_bg.wasm'), join(config.distBindingsDir, 'qwik_wasm_bg.wasm') diff --git a/scripts/build.ts b/scripts/build.ts index d7a1e3b3fc4..ed6b54be476 100644 --- a/scripts/build.ts +++ b/scripts/build.ts @@ -159,18 +159,10 @@ export async function build(config: BuildConfig) { await watchDirectories({ [join(config.srcQwikDir, 'core')]: async () => { await submoduleCore({ ...config, dev: true }); - await copyFile( - join(config.srcQwikDir, '..', 'dist', 'core.cjs'), - join(config.srcQwikDir, '..', 'dist', 'core.prod.cjs') - ); await copyFile( join(config.srcQwikDir, '..', 'dist', 'core.mjs'), join(config.srcQwikDir, '..', 'dist', 'core.prod.mjs') ); - console.log( - join(config.srcQwikDir, '..', 'dist', 'core.cjs'), - join(config.srcQwikDir, '..', 'dist', 'core.prod.cjs') - ); }, [join(config.srcQwikDir, 'cli')]: () => submoduleCli(config), [join(config.srcQwikDir, 'optimizer')]: () => submoduleOptimizer(config), diff --git a/scripts/submodule-backpatch.ts b/scripts/submodule-backpatch.ts index 2084ec2cfe0..bfea7db858b 100644 --- a/scripts/submodule-backpatch.ts +++ b/scripts/submodule-backpatch.ts @@ -14,6 +14,7 @@ import { /** Builds and minifies the backpatch executor javascript files. This is based off of the qwikloader */ export async function submoduleBackpatch(config: BuildConfig) { await build({ + clearScreen: false, build: { emptyOutDir: false, copyPublicDir: false, @@ -71,11 +72,6 @@ export async function generateBackpatchSubmodule(config: BuildConfig) { ...code, `export { QWIK_BACKPATCH_EXECUTOR_MINIFIED, QWIK_BACKPATCH_EXECUTOR_DEBUG };`, ]; - const cjsCode = [ - ...code, - `exports.QWIK_BACKPATCH_EXECUTOR_MINIFIED = QWIK_BACKPATCH_EXECUTOR_MINIFIED;`, - `exports.QWIK_BACKPATCH_EXECUTOR_DEBUG = QWIK_BACKPATCH_EXECUTOR_DEBUG;`, - ]; const dtsCode = [ `export declare const QWIK_BACKPATCH_EXECUTOR_MINIFIED: string;`, `export declare const QWIK_BACKPATCH_EXECUTOR_DEBUG: string;`, @@ -83,7 +79,6 @@ export async function generateBackpatchSubmodule(config: BuildConfig) { ensureDir(backpatchDistDir); await writeFile(join(backpatchDistDir, 'index.mjs'), esmCode.join('\n') + '\n'); - await writeFile(join(backpatchDistDir, 'index.cjs'), cjsCode.join('\n') + '\n'); await writeFile(join(backpatchDistDir, 'index.d.ts'), dtsCode.join('\n') + '\n'); const backpatchPkg: PackageJSON = { diff --git a/scripts/submodule-build.ts b/scripts/submodule-build.ts index 161e2bb4957..8d720920471 100644 --- a/scripts/submodule-build.ts +++ b/scripts/submodule-build.ts @@ -1,4 +1,4 @@ -import { build, type BuildOptions } from 'esbuild'; +import { build } from 'vite'; import { join } from 'node:path'; import { writePackageJson } from './package-json'; import { type BuildConfig, copyFile, ensureDir, type PackageJSON, target } from './util'; @@ -35,33 +35,25 @@ export async function bundleIndex(config: BuildConfig, entryName: string) { ensureDir(buildDestDir); - const opts: BuildOptions = { - entryPoints: [join(config.srcQwikDir, 'build', `${entryName}.ts`)], - entryNames: entryName, - outdir: buildDestDir, - bundle: true, - sourcemap: true, - target, - }; - - const esm = build({ - ...opts, - format: 'esm', - outExtension: { '.js': '.mjs' }, - }); - - const cjs = build({ - ...opts, - format: 'cjs', - - banner: { - js: `globalThis.qwikBuild = (function (module) {`, - }, - footer: { - js: `return module.exports; })(typeof module === 'object' && module.exports ? module : { exports: {} });`, + await build({ + clearScreen: false, + build: { + emptyOutDir: false, + lib: { + entry: join(config.srcQwikDir, 'build', `${entryName}.ts`), + name: 'qwikBuild', + }, + outDir: buildDestDir, + sourcemap: true, + target, + rollupOptions: { + output: [ + { + format: 'es', + entryFileNames: `${entryName}.mjs`, + }, + ], + }, }, - outExtension: { '.js': '.cjs' }, }); - - await Promise.all([esm, cjs]); } diff --git a/scripts/submodule-core.ts b/scripts/submodule-core.ts index 76b4e9312c8..b6604fd3eb6 100644 --- a/scripts/submodule-core.ts +++ b/scripts/submodule-core.ts @@ -56,23 +56,9 @@ async function submoduleCoreProd(config: BuildConfig) { banner: getBanner('@qwik.dev/core', config.distVersion), }; - const cjsOutput: OutputOptions = { - dir: join(config.distQwikPkgDir), - format: 'umd', - name: 'qwikCore', - entryFileNames: 'core.cjs', - sourcemap: true, - globals: { - '@qwik.dev/core/build': 'qwikBuild', - // not actually used - '@qwik.dev/core/preloader': 'qwikPreloader', - }, - banner: getBanner('@qwik.dev/core', config.distVersion), - }; - const build = await rollup(input); - await Promise.all([build.write(esmOutput), build.write(cjsOutput)]); + await build.write(esmOutput); console.log('🦊 core.mjs:', await fileSize(join(config.distQwikPkgDir, 'core.mjs'))); @@ -174,13 +160,8 @@ async function submoduleCoreProd(config: BuildConfig) { console.log('🐭 core.min.mjs:', await fileSize(join(config.distQwikPkgDir, 'core.min.mjs'))); let esmCode = await readFile(join(config.distQwikPkgDir, 'core.mjs'), 'utf-8'); - let cjsCode = await readFile(join(config.distQwikPkgDir, 'core.cjs'), 'utf-8'); - // fixup the Vite base url - cjsCode = cjsCode.replaceAll('undefined.BASE_URL', 'globalThis.BASE_URL||"/"'); - await writeFile(join(config.distQwikPkgDir, 'core.cjs'), cjsCode); await submoduleCoreProduction(config, esmCode, join(config.distQwikPkgDir, 'core.prod.mjs')); - await submoduleCoreProduction(config, cjsCode, join(config.distQwikPkgDir, 'core.prod.cjs')); } async function submoduleCoreProduction(config: BuildConfig, code: string, outPath: string) { @@ -222,6 +203,7 @@ async function submoduleCoreDev(config: BuildConfig) { const opts: BuildOptions = { entryPoints: [join(config.srcQwikDir, submodule, 'index.ts')], entryNames: submodule, + external: ['@qwik.dev/core/build', '@qwik.dev/core/preloader'], outdir: config.distQwikPkgDir, bundle: true, sourcemap: 'external', @@ -231,48 +213,15 @@ async function submoduleCoreDev(config: BuildConfig) { }, }; - const esm = await build({ + await build({ ...opts, - external: ['@qwik.dev/core/build', '@qwik.dev/core/preloader'], format: 'esm', outExtension: { '.js': '.mjs' }, }); - // We do a CJS build, only for the repl service worker - const cjs = build({ - ...opts, - // we don't externalize qwik build because then the repl service worker sees require() - define: { - ...opts.define, - // We need to get rid of the import.meta.env values - // Vite's base url - 'import.meta.env.BASE_URL': 'globalThis.BASE_URL', - // Vite's devserver mode - 'import.meta.env.DEV': 'false', - }, - format: 'cjs', - outExtension: { '.js': '.cjs' }, - banner: { - js: `globalThis.qwikCore = (function (module) {`, - }, - footer: { - js: `return module.exports; })(typeof module === 'object' && module.exports ? module : { exports: {} });`, - }, - }); - - await Promise.all([esm, cjs]); - // Point the minified and prod versions to the dev versions await writeFile(join(config.distQwikPkgDir, 'core.prod.mjs'), `export * from './core.mjs';\n`); - await writeFile( - join(config.distQwikPkgDir, 'core.prod.cjs'), - `module.exports = require('./core.cjs');\n` - ); await writeFile(join(config.distQwikPkgDir, 'core.min.mjs'), `export * from './core.mjs';\n`); - await writeFile( - join(config.distQwikPkgDir, 'core.min.cjs'), - `module.exports = require('./core.cjs');\n` - ); console.log('🐬', submodule, '(dev)'); } diff --git a/scripts/submodule-insights.ts b/scripts/submodule-insights.ts index c7231607f8f..08cc2adc1d8 100644 --- a/scripts/submodule-insights.ts +++ b/scripts/submodule-insights.ts @@ -17,8 +17,8 @@ async function buildComponents(config: BuildConfig) { build: { lib: { entry: entryPoint, - formats: ['es', 'cjs'], - fileName: (format) => `index.qwik.${format === 'es' ? 'mjs' : 'cjs'}`, + formats: ['es'], + fileName: 'index.qwik.mjs', }, outDir: distBase, emptyOutDir: false, @@ -39,8 +39,8 @@ async function buildVite(config: BuildConfig) { build: { lib: { entry: entryPoint, - formats: ['es', 'cjs'], - fileName: (format) => (format === 'es' ? 'index.mjs' : 'index.cjs'), + formats: ['es'], + fileName: 'index.mjs', }, outDir: distBase, emptyOutDir: false, diff --git a/scripts/submodule-optimizer.ts b/scripts/submodule-optimizer.ts index 0e46468599e..b1bf0cd7c42 100644 --- a/scripts/submodule-optimizer.ts +++ b/scripts/submodule-optimizer.ts @@ -1,7 +1,7 @@ import { platformArchTriples } from '@napi-rs/triples'; import { constants, existsSync } from 'node:fs'; import { join } from 'node:path'; -import { build as viteBuild, type UserConfig } from 'vite'; +import { build as viteBuild } from 'vite'; import { compiledStringPlugin } from './compiled-string-plugin'; import { inlineQwikScriptsEsBuild } from './submodule-qwikloader'; import { access, getBanner, target, writeFile, type BuildConfig } from './util'; @@ -16,23 +16,8 @@ export async function submoduleOptimizer(config: BuildConfig) { const entryPoint = join(config.optimizerDir, 'index.ts'); const qwikloaderScripts = await inlineQwikScriptsEsBuild(config); - // Common Vite configuration - const commonConfig = { + await viteBuild({ clearScreen: false, - build: { - emptyOutDir: false, - sourcemap: false, - target: target, - minify: !config.dev, // Minify in production builds - rollupOptions: { - external: ['node:fs', 'node:path', 'launch-editor'], - }, - lib: { - entry: entryPoint, - name: 'optimizer', - fileName: (format) => `optimizer.${format === 'es' ? 'mjs' : 'cjs'}`, - }, - }, define: { 'globalThis.QWIK_VERSION': JSON.stringify(config.distVersion), ...qwikloaderScripts, @@ -52,59 +37,26 @@ export async function submoduleOptimizer(config: BuildConfig) { }, }, ], - } as const satisfies UserConfig; - - // ESM Build - const esmConfig: UserConfig = { - ...commonConfig, build: { - ...commonConfig.build, + emptyOutDir: false, + sourcemap: false, + target: target, + minify: !config.dev, // Minify in production builds outDir: config.distQwikPkgDir, lib: { - ...commonConfig.build!.lib, + entry: entryPoint, + name: 'optimizer', + fileName: () => 'optimizer.mjs', formats: ['es'], }, rollupOptions: { - ...commonConfig.build?.rollupOptions, + external: ['node:fs', 'node:path', 'launch-editor'], output: { banner: getBanner('@qwik.dev/core/optimizer', config.distVersion), }, }, }, - define: { - ...commonConfig.define, - 'globalThis.IS_CJS': 'false', - 'globalThis.IS_ESM': 'true', - }, - }; - - // CJS Build - const cjsConfig: UserConfig = { - ...commonConfig, - build: { - ...commonConfig.build, - outDir: config.distQwikPkgDir, - lib: { - ...commonConfig.build!.lib, - formats: ['cjs'], - }, - rollupOptions: { - ...commonConfig.build?.rollupOptions, - output: { - banner: `globalThis.qwikOptimizer = (function (module) {\n${getBanner('@qwik.dev/core/optimizer', config.distVersion)}`, - footer: `return module.exports; })(typeof module === 'object' && module.exports ? module : { exports: {} });`, - }, - }, - }, - define: { - ...commonConfig.define, - 'globalThis.IS_CJS': 'true', - 'globalThis.IS_ESM': 'false', - }, - }; - - // Build both formats - await Promise.all([viteBuild(esmConfig), viteBuild(cjsConfig)]); + }); // Note: Minification is now handled automatically by Vite in production builds // The output files will be minified when config.dev is false diff --git a/scripts/submodule-preloader.ts b/scripts/submodule-preloader.ts index f0f6ef22bd5..41ff96c8be3 100644 --- a/scripts/submodule-preloader.ts +++ b/scripts/submodule-preloader.ts @@ -55,8 +55,8 @@ export async function submodulePreloader(config: BuildConfig) { copyPublicDir: false, lib: { entry: join(config.srcQwikDir, 'core/preloader'), - formats: ['es', 'cjs'], - fileName: (format) => (format === 'es' ? 'preloader.mjs' : 'preloader.cjs'), + formats: ['es'], + fileName: () => 'preloader.mjs', }, rollupOptions: { external: ['@qwik.dev/core/build'], diff --git a/scripts/submodule-qwikloader.ts b/scripts/submodule-qwikloader.ts index be62e23c670..a3416dc1321 100644 --- a/scripts/submodule-qwikloader.ts +++ b/scripts/submodule-qwikloader.ts @@ -83,7 +83,7 @@ export const getLoaderJsonString = async (config: BuildConfig, name: string) => return JSON.stringify(cleaned); }; -/** Load each of the qwik scripts to be inlined with esbuild "define" as const variables. */ +/** Load each of the qwik scripts to be inlined with "define" as const variables. */ export async function inlineQwikScriptsEsBuild(config: BuildConfig) { const variableToFileMap = [ ['QWIK_LOADER_DEFAULT_MINIFIED', 'qwikloader.js'], @@ -111,11 +111,6 @@ async function generateLoaderSubmodule(config: BuildConfig) { ]; const esmCode = [...code, `export { QWIK_LOADER, QWIK_LOADER_DEBUG };`]; - const cjsCode = [ - ...code, - `exports.QWIK_LOADER = QWIK_LOADER;`, - `exports.QWIK_LOADER_DEBUG = QWIK_LOADER_DEBUG;`, - ]; const dtsCode = [ `export declare const QWIK_LOADER: string;`, `export declare const QWIK_LOADER_DEBUG: string;`, @@ -123,7 +118,6 @@ async function generateLoaderSubmodule(config: BuildConfig) { ensureDir(loaderDistDir); await writeFile(join(loaderDistDir, 'index.mjs'), esmCode.join('\n') + '\n'); - await writeFile(join(loaderDistDir, 'index.cjs'), cjsCode.join('\n') + '\n'); await writeFile(join(loaderDistDir, 'index.d.ts'), dtsCode.join('\n') + '\n'); const loaderPkg: PackageJSON = { diff --git a/scripts/submodule-server.ts b/scripts/submodule-server.ts index 0fa7d60b720..127698f0249 100644 --- a/scripts/submodule-server.ts +++ b/scripts/submodule-server.ts @@ -1,9 +1,9 @@ -import { build, type BuildOptions, type Plugin } from 'esbuild'; import { join } from 'node:path'; +import { build as viteBuild, type Plugin } from 'vite'; import { readPackageJson } from './package-json'; -import { inlineQwikScriptsEsBuild } from './submodule-qwikloader'; import { inlineBackpatchScriptsEsBuild } from './submodule-backpatch'; -import { type BuildConfig, getBanner, importPath, nodeTarget, target } from './util'; +import { inlineQwikScriptsEsBuild } from './submodule-qwikloader'; +import { target, type BuildConfig } from './util'; /** * Builds @qwik.dev/core/server @@ -11,6 +11,32 @@ import { type BuildConfig, getBanner, importPath, nodeTarget, target } from './u * This is submodule for helping to generate server-side rendered pages, along with providing * utilities for prerendering and unit testing. */ + +// Vite plugin to forbid core imports +export const forbidCorePlugin = (): Plugin => { + return { + name: 'forbid-core', + enforce: 'pre', + load: { + order: 'pre', + handler(id) { + if (id.includes('src/core/')) { + if ( + id.includes('util') || + id.includes('shared') || + // we allow building preloader into server builds + id.includes('preloader') + ) { + return null; + } + console.error('forbid-core', id); + throw new Error('Import of core files is not allowed in server builds.'); + } + }, + }, + }; +}; + export async function submoduleServer(config: BuildConfig) { const submodule = 'server'; console.log('🐰 start', submodule); @@ -18,106 +44,40 @@ export async function submoduleServer(config: BuildConfig) { const qwikDomPlugin = await bundleQwikDom(config); const qwikDomVersion = await getQwikDomVersion(config); - const opts: BuildOptions = { - entryPoints: [join(config.srcQwikDir, submodule, 'index.ts')], - entryNames: 'server', - outdir: config.distQwikPkgDir, - sourcemap: config.dev, - bundle: true, - platform: 'node', - target, - external: [ - '@qwik.dev/dom', - '@qwik.dev/core', - '@qwik.dev/core/build', - '@qwik.dev/core/preloader', - '@qwik-client-manifest', - ], - }; - - const esm = build({ - ...opts, - format: 'esm', - banner: { js: getBanner('@qwik.dev/core/server', config.distVersion) }, - outExtension: { '.js': '.mjs' }, - plugins: [ - // uncomment this if you want to find what imports what - // so you can make sure client isn't being imported - // { - // name: 'spy-resolve', - // setup(build) { - // build.onResolve({ filter: /./ }, (args) => { - // console.log('spy-resolve', args); - // return undefined; - // }); - // }, - // }, - { - // throws an error if files from src/core are loaded, except for some allowed imports - name: 'forbid-core', - setup(build) { - build.onLoad({ filter: /src[\\/]core[\\/]/ }, (args) => { - if ( - args.path.includes('util') || - args.path.includes('shared') || - // we allow building preloader into server builds - args.path.includes('preloader') - ) { - return null; - } - console.error('forbid-core', args); - throw new Error('Import of core files is not allowed in server builds.'); - }); - }, + await viteBuild({ + clearScreen: false, + build: { + emptyOutDir: false, + lib: { + entry: join(config.srcQwikDir, submodule, 'index.ts'), + }, + outDir: config.distQwikPkgDir, + sourcemap: config.dev, + rollupOptions: { + external: [/@qwik.dev\/core/, '@qwik.dev/dom', '@qwik-client-manifest'], + output: [ + { + format: 'es', + entryFileNames: 'server.mjs', + }, + ], }, - importPath(/^@qwik\.dev\/core$/, '@qwik.dev/core'), + target, + }, + plugins: [ + forbidCorePlugin(), + // importPathPlugin(/^@qwik\.dev\/core$/, '@qwik.dev/core'), + // TODO why do we have this while it's also external? qwikDomPlugin, ], define: { ...(await inlineQwikScriptsEsBuild(config)), ...(await inlineBackpatchScriptsEsBuild(config)), - 'globalThis.IS_CJS': 'false', - 'globalThis.IS_ESM': 'true', 'globalThis.QWIK_VERSION': JSON.stringify(config.distVersion), 'globalThis.QWIK_DOM_VERSION': JSON.stringify(qwikDomVersion), }, }); - const cjsBanner = [ - getBanner('@qwik.dev/core/server', config.distVersion), - `globalThis.qwikServer = (function (module) {`, - browserCjsRequireShim, - ].join('\n'); - - const cjs = build({ - ...opts, - format: 'cjs', - banner: { - js: cjsBanner, - }, - footer: { - js: `return module.exports; })(typeof module === 'object' && module.exports ? module : { exports: {} });`, - }, - outExtension: { '.js': '.cjs' }, - plugins: [importPath(/^@qwik\.dev\/core$/, '@qwik.dev/core'), qwikDomPlugin], - target: nodeTarget, - define: { - ...(await inlineQwikScriptsEsBuild(config)), - ...(await inlineBackpatchScriptsEsBuild(config)), - 'globalThis.IS_CJS': 'true', - 'globalThis.IS_ESM': 'false', - 'globalThis.QWIK_VERSION': JSON.stringify(config.distVersion), - 'globalThis.QWIK_DOM_VERSION': JSON.stringify(qwikDomVersion), - // We need to get rid of the import.meta.env values - // Vite's base url - 'import.meta.env.BASE_URL': 'globalThis.BASE_URL', - // Vite's devserver mode - 'import.meta.env.DEV': 'false', - }, - }); - - await Promise.all([esm, cjs]); - console.log('🐰', submodule); } @@ -125,26 +85,34 @@ async function bundleQwikDom(config: BuildConfig) { const input = join(config.packagesDir, 'qwik-dom', 'lib', 'index.js'); const outfile = join(config.tmpDir, 'qwikdom.mjs'); - const opts: BuildOptions = { - entryPoints: [input], - sourcemap: false, - minify: !config.dev, - bundle: true, - target, - outfile, - format: 'esm', - }; - - await build(opts); + await viteBuild({ + clearScreen: false, + build: { + emptyOutDir: false, + lib: { + entry: input, + name: 'qwikDom', + }, + outDir: config.tmpDir, + sourcemap: false, + minify: !config.dev, + target, + rollupOptions: { + external: ['@qwik.dev/core'], + output: { + format: 'es', + entryFileNames: 'qwikdom.mjs', + }, + }, + }, + }); const qwikDomPlugin: Plugin = { name: 'qwikDomPlugin', - setup(build) { - build.onResolve({ filter: /@qwik.dev\/dom/ }, () => { - return { - path: outfile, - }; - }); + resolveId(id) { + if (id === '@qwik.dev/dom') { + return outfile; + } }, }; @@ -156,26 +124,3 @@ async function getQwikDomVersion(config: BuildConfig) { const pkgJson = await readPackageJson(pkgJsonPath); return pkgJson.version; } - -const browserCjsRequireShim = ` -if (typeof require !== 'function' && typeof location !== 'undefined' && typeof navigator !== 'undefined') { - // shim cjs require() for core.cjs within a browser - globalThis.require = function(path) { - if (path === './core.cjs' || path === '@qwik.dev/core') { - if (!self.qwikCore) { - throw new Error('Qwik Core global, "globalThis.qwikCore", must already be loaded for the Qwik Server to be used within a browser.'); - } - return self.qwikCore; - } - if (path === '@qwik.dev/core/build') { - if (!self.qwikBuild) { - throw new Error('Qwik Build global, "globalThis.qwikBuild", must already be loaded for the Qwik Server to be used within a browser.'); - } - return self.qwikBuild; - } - if (path === '@qwik-client-manifest') { - return {}; - } - throw new Error('Unable to require() path "' + path + '" from a browser environment.'); - }; -}`; diff --git a/scripts/submodule-testing.ts b/scripts/submodule-testing.ts index 206e55b3193..94d323a3466 100644 --- a/scripts/submodule-testing.ts +++ b/scripts/submodule-testing.ts @@ -1,71 +1,53 @@ -import { getBanner, importPath, nodeTarget, target, externalImportNoEffects } from './util'; -import { build, type BuildOptions } from 'esbuild'; -import { type BuildConfig, type PackageJSON } from './util'; import { join } from 'node:path'; +import { build } from 'vite'; +import { compiledStringPlugin } from './compiled-string-plugin'; import { writePackageJson } from './package-json'; +import { getBanner, nodeTarget, type BuildConfig, type PackageJSON } from './util'; /** Builds @qwik.dev/core/testing */ export async function submoduleTesting(config: BuildConfig) { const submodule = 'testing'; - const opts: BuildOptions = { - entryPoints: [join(config.srcQwikDir, submodule, 'index.ts')], - outdir: join(config.distQwikPkgDir, submodule), - sourcemap: config.dev, - bundle: true, - target, - external: [ - 'prettier', - 'vitest', - '@qwik.dev/core', - '@qwik.dev/core/build', - '@qwik.dev/core/preloader', - '@qwik-client-manifest', - ], - platform: 'node', - }; - - const esm = build({ - ...opts, - format: 'esm', - banner: { js: getBanner('@qwik.dev/core/testing', config.distVersion) }, - outExtension: { '.js': '.mjs' }, - plugins: [ - importPath(/^@qwik\.dev\/core$/, '../core.mjs'), - importPath(/^@qwik\.dev\/core\/optimizer$/, '../optimizer.mjs'), - importPath(/^@qwik\.dev\/core\/server$/, '../server.mjs'), - externalImportNoEffects(/^(@qwik\.dev\/core\/build|prettier|vitest)$/), - ], - define: { - 'globalThis.MODULE_EXT': `"mjs"`, - 'globalThis.RUNNER': `false`, + await build({ + clearScreen: false, + build: { + emptyOutDir: false, + lib: { + entry: join(config.srcQwikDir, submodule, 'index.ts'), + formats: ['es'], + fileName: '[name].mjs', + }, + outDir: join(config.distQwikPkgDir, submodule), + sourcemap: true, + target: 'es2020', + rollupOptions: { + external: [ + /node:/, + 'esbuild', + 'prettier', + 'vitest', + /@qwik.dev\/core/, + '@qwik-client-manifest', + ], + output: { + banner: getBanner('@qwik.dev/core/testing', config.distVersion), + }, + }, }, - target: 'es2020' /* needed for import.meta */, - }); - - const cjs = build({ - ...opts, - format: 'cjs', - outExtension: { '.js': '.cjs' }, - banner: { - js: getBanner('@qwik.dev/core/testing', config.distVersion), + plugins: [compiledStringPlugin()], + environments: { + ssr: { + build: { + target: nodeTarget, + }, + }, }, - plugins: [ - importPath(/^@qwik\.dev\/core$/, '../core.cjs'), - importPath(/^@qwik\.dev\/core\/optimizer$/, '../optimizer.cjs'), - importPath(/^@qwik\.dev\/core\/server$/, '../server.cjs'), - externalImportNoEffects(/^(@qwik\.dev\/core\/build|prettier|vitest)$/), - ], define: { - 'globalThis.MODULE_EXT': `"cjs"`, + 'globalThis.MODULE_EXT': `"mjs"`, 'globalThis.RUNNER': `false`, }, - platform: 'node', - target: nodeTarget, }); - await Promise.all([esm, cjs]); - await generateTestingPackageJson(config); console.log('🦁', submodule); diff --git a/scripts/validate-build.ts b/scripts/validate-build.ts index 4184bad403c..c870ea3113f 100644 --- a/scripts/validate-build.ts +++ b/scripts/validate-build.ts @@ -43,11 +43,8 @@ export async function validateBuild(config: BuildConfig) { switch (ext) { case '.cjs': - const f = basename(filePath); - if (f !== 'qwik.cjs') { - require(filePath); - console.log(`✅ ${filePath}`); - } + require(filePath); + console.log(`✅ ${filePath}`); break; case '.mjs': if (config.esmNode) { diff --git a/starters/apps/library/package.json b/starters/apps/library/package.json index 8d35f8c5e72..af21b475111 100644 --- a/starters/apps/library/package.json +++ b/starters/apps/library/package.json @@ -10,7 +10,6 @@ "exports": { ".": { "import": "./lib/index.qwik.mjs", - "require": "./lib/index.qwik.cjs", "types": "./lib-types/index.d.ts" } }, diff --git a/starters/apps/library/vite.config.mts b/starters/apps/library/vite.config.mts index 715e8af28c0..cc9a5c4b55e 100644 --- a/starters/apps/library/vite.config.mts +++ b/starters/apps/library/vite.config.mts @@ -13,10 +13,9 @@ export default defineConfig(() => { target: "es2020", lib: { entry: "./src/index", - formats: ["es", "cjs"] as const, + formats: ["es"] as const, // This adds .qwik so all files are processed by the optimizer - fileName: (format, entryName) => - `${entryName}.qwik.${format === "es" ? "mjs" : "cjs"}`, + fileName: (_format, entryName) => `${entryName}.qwik.mjs`, }, rollupOptions: { output: { diff --git a/vitest.config.mts b/vitest.config.mts index 8e2addf334a..21d5edc3a66 100644 --- a/vitest.config.mts +++ b/vitest.config.mts @@ -1,9 +1,11 @@ import { qwikVite } from '@qwik.dev/core/optimizer'; import tsconfigPaths from 'vite-tsconfig-paths'; import { defineConfig } from 'vitest/config'; +import { compiledStringPlugin } from './scripts/compiled-string-plugin'; export default defineConfig({ plugins: [ + compiledStringPlugin(), qwikVite({ debug: !true, srcDir: `./packages/qwik/src`,