diff --git a/e2e/cases/server/ssr/package.json b/e2e/cases/server/ssr/package.json index ecb7c000bb..9700e5c981 100644 --- a/e2e/cases/server/ssr/package.json +++ b/e2e/cases/server/ssr/package.json @@ -4,6 +4,6 @@ "version": "1.0.0", "scripts": { "dev": "npx rsbuild dev", - "dev:esm": "TEST_ESM_LIBRARY=true npx rsbuild dev" + "dev:esm": "cross-env NODE_OPTIONS=\"--experimental-vm-modules\" TEST_ESM_LIBRARY=true npx rsbuild dev" } } diff --git a/e2e/cases/server/ssr/src/assert.server.ts b/e2e/cases/server/ssr/src/assert.server.ts index a35557cb73..21615a3097 100644 --- a/e2e/cases/server/ssr/src/assert.server.ts +++ b/e2e/cases/server/ssr/src/assert.server.ts @@ -1,9 +1,8 @@ -function assertQueueMicroTask() { +export function assert() { if (typeof queueMicrotask !== 'function') { throw Error('not support queueMicrotask in this environment'); } -} - -export function assert() { - assertQueueMicroTask(); + if (typeof TextEncoder !== 'function') { + throw Error('not support TextEncoder in this environment'); + } } diff --git a/packages/core/src/server/runner/asModule.ts b/packages/core/src/server/runner/asModule.ts index 3061443f2f..cee68cb5f3 100644 --- a/packages/core/src/server/runner/asModule.ts +++ b/packages/core/src/server/runner/asModule.ts @@ -1,7 +1,5 @@ import vm from 'node:vm'; -const SYNTHETIC_MODULES_STORE = '__SYNTHETIC_MODULES_STORE'; - export const asModule = async ( something: Record, context: Record, @@ -10,20 +8,20 @@ export const asModule = async ( if (something instanceof vm.Module) { return something; } - context[SYNTHETIC_MODULES_STORE] = context[SYNTHETIC_MODULES_STORE] || []; - const i = context[SYNTHETIC_MODULES_STORE].length; - context[SYNTHETIC_MODULES_STORE].push(something); - const code = [...new Set(['default', ...Object.keys(something)])] - .map( - (name) => - `const _${name} = ${SYNTHETIC_MODULES_STORE}[${i}]${ - name === 'default' ? '' : `[${JSON.stringify(name)}]` - }; export { _${name} as ${name}};`, - ) - .join('\n'); - const m = new vm.SourceTextModule(code, { - context, - }); + + const exports = [...new Set(['default', ...Object.keys(something)])]; + + const m = new vm.SyntheticModule( + exports, + () => { + for (const name of exports) { + m.setExport(name, name === 'default' ? something : something[name]); + } + }, + { + context, + }, + ); if (unlinked) return m; await m.link((() => {}) as () => vm.Module); // @ts-expect-error copy from webpack diff --git a/packages/core/src/server/runner/esm.ts b/packages/core/src/server/runner/esm.ts index 8ffebdef54..6f2778bf01 100644 --- a/packages/core/src/server/runner/esm.ts +++ b/packages/core/src/server/runner/esm.ts @@ -35,9 +35,6 @@ export class EsmRunner extends CommonJsRunner { } protected createEsmRequirer(): RunnerRequirer { - const esmContext = vm.createContext(this.baseModuleScope!, { - name: 'context for esm', - }); const esmCache = new Map(); const esmIdentifier = this._options.name; return (currentDirectory, modulePath, context = {}) => { @@ -58,7 +55,7 @@ export class EsmRunner extends CommonJsRunner { identifier: `${esmIdentifier}-${file.path}`, // no attribute url: `${pathToFileURL(file.path).href}?${esmIdentifier}`, - context: esmContext, + // run in current execution context initializeImportMeta: (meta: { url: string }, _: any) => { meta.url = pathToFileURL(file!.path).href; },