From 6790746cee7bac5bea2a954a941d4b3390643a0c Mon Sep 17 00:00:00 2001 From: Timeless0911 <1604889533@qq.com> Date: Tue, 21 Oct 2025 16:08:15 +0800 Subject: [PATCH] fix: cjs `import.meta.url` shims in async chunks --- packages/core/src/plugins/EntryChunkPlugin.ts | 4 +- tests/integration/shims/cjs/rslib.config.ts | 10 +++- tests/integration/shims/cjs/src/dynamic.ts | 3 + tests/integration/shims/cjs/src/index.ts | 7 ++- tests/integration/shims/index.test.ts | 55 +++++++++++-------- 5 files changed, 52 insertions(+), 27 deletions(-) create mode 100644 tests/integration/shims/cjs/src/dynamic.ts diff --git a/packages/core/src/plugins/EntryChunkPlugin.ts b/packages/core/src/plugins/EntryChunkPlugin.ts index 5b8c153f6..8e9ed2185 100644 --- a/packages/core/src/plugins/EntryChunkPlugin.ts +++ b/packages/core/src/plugins/EntryChunkPlugin.ts @@ -109,11 +109,11 @@ class EntryChunkPlugin { const isJs = JS_EXTENSIONS_PATTERN.test(filename); if (!isJs) return; + this.shimsInjectedAssets.add(filename); + const name = chunk.name; if (!name) return; - this.shimsInjectedAssets.add(filename); - const shebangEntry = this.shebangEntries[name]; if (shebangEntry) { this.shebangEntries[filename] = shebangEntry; diff --git a/tests/integration/shims/cjs/rslib.config.ts b/tests/integration/shims/cjs/rslib.config.ts index 9e95a40ac..ca9722b3b 100644 --- a/tests/integration/shims/cjs/rslib.config.ts +++ b/tests/integration/shims/cjs/rslib.config.ts @@ -6,12 +6,18 @@ export default defineConfig({ generateBundleEsmConfig(), generateBundleCjsConfig({ shims: { - cjs: { 'import.meta.url': true }, + cjs: { + 'import.meta.url': true, + }, }, }), ], output: { - copy: [{ from: 'src/ok.cjs' }], + copy: [ + { + from: 'src/ok.cjs', + }, + ], }, source: { entry: { diff --git a/tests/integration/shims/cjs/src/dynamic.ts b/tests/integration/shims/cjs/src/dynamic.ts new file mode 100644 index 000000000..6ea8c389b --- /dev/null +++ b/tests/integration/shims/cjs/src/dynamic.ts @@ -0,0 +1,3 @@ +const dynamic = import.meta.url; + +export { dynamic }; diff --git a/tests/integration/shims/cjs/src/index.ts b/tests/integration/shims/cjs/src/index.ts index 0211ff87e..1585e186d 100644 --- a/tests/integration/shims/cjs/src/index.ts +++ b/tests/integration/shims/cjs/src/index.ts @@ -4,6 +4,11 @@ const importMetaUrl = import.meta.url; const require = createRequire(import.meta.url); const requiredModule = require('./ok.cjs'); +const dynamicImportMetaUrl = async () => { + const { dynamic } = await import('./dynamic'); + return dynamic; +}; + // https://github.com/web-infra-dev/rslib/issues/425 import { fileURLToPath } from 'url'; @@ -13,4 +18,4 @@ console.log(__filename); // https://github.com/web-infra-dev/rslib/pull/399 export const module = null; -export { importMetaUrl, requiredModule, __filename }; +export { importMetaUrl, requiredModule, dynamicImportMetaUrl, __filename }; diff --git a/tests/integration/shims/index.test.ts b/tests/integration/shims/index.test.ts index 058aaa60c..60a3ba4c0 100644 --- a/tests/integration/shims/index.test.ts +++ b/tests/integration/shims/index.test.ts @@ -1,9 +1,10 @@ import fs from 'node:fs'; +import { createRequire } from 'node:module'; import path, { join } from 'node:path'; import { pathToFileURL } from 'node:url'; import vm from 'node:vm'; import { describe, expect, test } from '@rstest/core'; -import { buildAndGetResults } from 'test-helper'; +import { buildAndGetResults, queryContent } from 'test-helper'; describe('ESM shims', async () => { const fixturePath = join(__dirname, 'esm'); @@ -107,42 +108,52 @@ describe('ESM shims disabled', async () => { describe('CJS shims', () => { test('import.meta.url', async () => { const fixturePath = join(__dirname, 'cjs'); - const { entryFiles, entries } = await buildAndGetResults({ fixturePath }); + const { entryFiles, entries, contents } = await buildAndGetResults({ + fixturePath, + }); // `module.require` is not available in Rstest runner context. Manually create a context to run the CJS code. // As a temporary solution, we use `module.require` to avoid potential collision with module scope variable `require`. const cjsCode = entries.cjs; + const req = createRequire(entryFiles.cjs); const context = vm.createContext({ - require, + require: req, exports, - module: { require }, + module: { require: req }, __filename: entryFiles.cjs, }); - const { importMetaUrl, requiredModule } = vm.runInContext(cjsCode, context); + const { importMetaUrl, dynamicImportMetaUrl, requiredModule } = + vm.runInContext(cjsCode, context); const fileUrl = pathToFileURL(entryFiles.cjs).href; + const dynamicUrl = await dynamicImportMetaUrl(); + const { content: dynamicContent } = queryContent( + contents.cjs!, + /cjs\/1~7\.cjs/, + ); + expect(importMetaUrl).toBe(fileUrl); + expect(dynamicUrl).toBe(fileUrl.replace('index.cjs', '1~7.cjs')); expect(requiredModule).toBe('ok'); - expect( - cjsCode.startsWith( - `"use strict";\nconst __rslib_import_meta_url__ = /*#__PURE__*/ function() {`, - ), - ).toBe(true); + + for (const code of [cjsCode, dynamicContent]) { + expect( + code.startsWith( + `"use strict";\nconst __rslib_import_meta_url__ = /*#__PURE__*/ function() {`, + ), + ).toBe(true); + } }); test('ESM should not be affected by CJS shims configuration', async () => { const fixturePath = join(__dirname, 'cjs'); const { entries } = await buildAndGetResults({ fixturePath }); - expect(entries.esm).toMatchInlineSnapshot(` - "import { createRequire } from "node:module"; - import { fileURLToPath } from "url"; - const importMetaUrl = import.meta.url; - const src_require = createRequire(import.meta.url); - const requiredModule = src_require('./ok.cjs'); - const src_filename = fileURLToPath(import.meta.url); - console.log(src_filename); - const src_module = null; - export { src_filename as __filename, importMetaUrl, src_module as module, requiredModule }; - " - `); + + for (const code of [ + 'const importMetaUrl = import.meta.url;', + 'const src_require = createRequire(import.meta.url);', + 'const src_filename = fileURLToPath(import.meta.url);', + ]) { + expect(entries.esm).toContain(code); + } }); });