From 75f850c81c5c65d8dd0c2dd89933939d52cc5252 Mon Sep 17 00:00:00 2001 From: fi3ework Date: Mon, 24 Feb 2025 14:45:49 +0800 Subject: [PATCH] fix(shims): CJS shims should only affect chunk assets --- packages/core/src/plugins/EntryChunkPlugin.ts | 26 ++++++++++++++----- packages/core/src/plugins/shims.ts | 9 ------- .../tests/__snapshots__/config.test.ts.snap | 4 +++ pnpm-lock.yaml | 2 ++ tests/integration/shims/copy/package.json | 6 +++++ tests/integration/shims/copy/rslib.config.ts | 13 ++++++++++ tests/integration/shims/copy/src/a/index.ts | 3 +++ tests/integration/shims/copy/src/index.ts | 1 + tests/integration/shims/index.test.ts | 16 ++++++++++++ 9 files changed, 65 insertions(+), 15 deletions(-) create mode 100644 tests/integration/shims/copy/package.json create mode 100644 tests/integration/shims/copy/rslib.config.ts create mode 100644 tests/integration/shims/copy/src/a/index.ts create mode 100644 tests/integration/shims/copy/src/index.ts diff --git a/packages/core/src/plugins/EntryChunkPlugin.ts b/packages/core/src/plugins/EntryChunkPlugin.ts index da20da844..727fb3f13 100644 --- a/packages/core/src/plugins/EntryChunkPlugin.ts +++ b/packages/core/src/plugins/EntryChunkPlugin.ts @@ -12,11 +12,17 @@ import { SHEBANG_PREFIX, SHEBANG_REGEX, } from '../constant'; -import { importMetaUrlShim } from './shims'; const require = createRequire(import.meta.url); const PLUGIN_NAME = 'rsbuild:lib-entry-chunk'; const LOADER_NAME = 'rsbuild:lib-entry-module'; +const IMPORT_META_URL_SHIM = `const __rslib_import_meta_url__ = /*#__PURE__*/ (function () { + return typeof document === 'undefined' + ? new (require('url'.replace('', '')).URL)('file:' + __filename).href + : (document.currentScript && document.currentScript.src) || + new URL('main.js', document.baseURI).href; +})(); +`; const matchFirstLine = (source: string, regex: RegExp): string | false => { const lineBreakPos = source.match(/(\r\n|\n)/); @@ -32,6 +38,8 @@ const matchFirstLine = (source: string, regex: RegExp): string | false => { class EntryChunkPlugin { private reactDirectives: Record = {}; + private shimsInjectedAssets: Set = new Set(); + private shebangChmod = 0o755; private shebangEntries: Record = {}; private shebangInjectedAssets: Set = new Set(); @@ -101,6 +109,8 @@ class EntryChunkPlugin { const name = chunk.name; if (!name) return; + this.shimsInjectedAssets.add(filename); + const shebangEntry = this.shebangEntries[name]; if (shebangEntry) { this.shebangEntries[filename] = shebangEntry; @@ -117,9 +127,13 @@ class EntryChunkPlugin { compilation.hooks.processAssets.tap(PLUGIN_NAME, (assets) => { if (!this.enabledImportMetaUrlShim) return; - const chunkAsset = Object.keys(assets).filter((name) => - JS_EXTENSIONS_PATTERN.test(name), - ); + const chunkAsset = Object.keys(assets).filter((name) => { + return ( + JS_EXTENSIONS_PATTERN.test(name) && + this.shimsInjectedAssets.has(name) + ); + }); + for (const name of chunkAsset) { compilation.updateAsset(name, (old) => { const oldSource = old.source().toString(); @@ -131,10 +145,10 @@ class EntryChunkPlugin { replaceSource.replace( 0, 11, // 'use strict;'.length, - `"use strict";\n${importMetaUrlShim}`, + `"use strict";\n${IMPORT_META_URL_SHIM}`, ); } else { - replaceSource.insert(0, importMetaUrlShim); + replaceSource.insert(0, IMPORT_META_URL_SHIM); } return replaceSource; diff --git a/packages/core/src/plugins/shims.ts b/packages/core/src/plugins/shims.ts index 3fb1b66df..3b094af8e 100644 --- a/packages/core/src/plugins/shims.ts +++ b/packages/core/src/plugins/shims.ts @@ -1,14 +1,5 @@ import { type RsbuildPlugin, rspack } from '@rsbuild/core'; -// The shim will be injected in PostEntryPlugin. -export const importMetaUrlShim = `const __rslib_import_meta_url__ = /*#__PURE__*/ (function () { - return typeof document === 'undefined' - ? new (require('url'.replace('', '')).URL)('file:' + __filename).href - : (document.currentScript && document.currentScript.src) || - new URL('main.js', document.baseURI).href; -})(); -`; - // This Rsbuild plugin will shim `import.meta.url` for CommonJS modules. // - Replace `import.meta.url` with `importMetaUrl`. // - Inject `importMetaUrl` to the end of the module (can't inject at the beginning because of `"use strict";`). diff --git a/packages/core/tests/__snapshots__/config.test.ts.snap b/packages/core/tests/__snapshots__/config.test.ts.snap index 5b9221534..223695372 100644 --- a/packages/core/tests/__snapshots__/config.test.ts.snap +++ b/packages/core/tests/__snapshots__/config.test.ts.snap @@ -231,6 +231,7 @@ exports[`Should compose create Rsbuild config correctly > Merge Rsbuild config i "shebangChmod": 493, "shebangEntries": {}, "shebangInjectedAssets": Set {}, + "shimsInjectedAssets": Set {}, }, ], }, @@ -474,6 +475,7 @@ exports[`Should compose create Rsbuild config correctly > Merge Rsbuild config i "shebangChmod": 493, "shebangEntries": {}, "shebangInjectedAssets": Set {}, + "shimsInjectedAssets": Set {}, }, ], }, @@ -695,6 +697,7 @@ exports[`Should compose create Rsbuild config correctly > Merge Rsbuild config i "shebangChmod": 493, "shebangEntries": {}, "shebangInjectedAssets": Set {}, + "shimsInjectedAssets": Set {}, }, ], }, @@ -851,6 +854,7 @@ exports[`Should compose create Rsbuild config correctly > Merge Rsbuild config i "shebangChmod": 493, "shebangEntries": {}, "shebangInjectedAssets": Set {}, + "shimsInjectedAssets": Set {}, }, ], }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ad88b41c8..0a3b3fde9 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -844,6 +844,8 @@ importers: tests/integration/shims/cjs: {} + tests/integration/shims/copy: {} + tests/integration/shims/esm: {} tests/integration/sourcemap/css: {} diff --git a/tests/integration/shims/copy/package.json b/tests/integration/shims/copy/package.json new file mode 100644 index 000000000..434599527 --- /dev/null +++ b/tests/integration/shims/copy/package.json @@ -0,0 +1,6 @@ +{ + "name": "shims-copy-test", + "version": "1.0.0", + "private": true, + "type": "module" +} diff --git a/tests/integration/shims/copy/rslib.config.ts b/tests/integration/shims/copy/rslib.config.ts new file mode 100644 index 000000000..4b87c1c0d --- /dev/null +++ b/tests/integration/shims/copy/rslib.config.ts @@ -0,0 +1,13 @@ +import { defineConfig } from '@rslib/core'; +import { generateBundleCjsConfig } from 'test-helper'; + +export default defineConfig({ + lib: [ + generateBundleCjsConfig({ + shims: { esm: { __dirname: true, __filename: true } }, + }), + ], + output: { + copy: ['./src/a/index.ts'], + }, +}); diff --git a/tests/integration/shims/copy/src/a/index.ts b/tests/integration/shims/copy/src/a/index.ts new file mode 100644 index 000000000..72c42580e --- /dev/null +++ b/tests/integration/shims/copy/src/a/index.ts @@ -0,0 +1,3 @@ +#!/user/bin/env node + +export default 'ok'; diff --git a/tests/integration/shims/copy/src/index.ts b/tests/integration/shims/copy/src/index.ts new file mode 100644 index 000000000..fdf0e1164 --- /dev/null +++ b/tests/integration/shims/copy/src/index.ts @@ -0,0 +1 @@ +export const squared = (n: number): number => n * n; diff --git a/tests/integration/shims/index.test.ts b/tests/integration/shims/index.test.ts index e6843ea5a..ce0669af3 100644 --- a/tests/integration/shims/index.test.ts +++ b/tests/integration/shims/index.test.ts @@ -1,3 +1,4 @@ +import fs from 'node:fs'; import path, { join } from 'node:path'; import { pathToFileURL } from 'node:url'; import vm from 'node:vm'; @@ -119,3 +120,18 @@ describe('CJS shims', () => { `); }); }); + +describe('shims with copy', () => { + test('the CJS shims should not affect files in `output.copy`', async () => { + const fixturePath = join(__dirname, 'copy'); + await buildAndGetResults({ fixturePath }); + const copiedFile = path.resolve(fixturePath, 'dist/cjs/index.ts'); + const copiedContent = fs.readFileSync(copiedFile, 'utf-8'); + expect(copiedContent).toMatchInlineSnapshot(` + "#!/user/bin/env node + + export default 'ok'; + " + `); + }); +});