Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 20 additions & 6 deletions packages/core/src/plugins/EntryChunkPlugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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)/);
Expand All @@ -32,6 +38,8 @@ const matchFirstLine = (source: string, regex: RegExp): string | false => {
class EntryChunkPlugin {
private reactDirectives: Record<string, string> = {};

private shimsInjectedAssets: Set<string> = new Set();

private shebangChmod = 0o755;
private shebangEntries: Record<string, string> = {};
private shebangInjectedAssets: Set<string> = new Set();
Expand Down Expand Up @@ -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;
Expand All @@ -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();
Expand All @@ -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;
Expand Down
9 changes: 0 additions & 9 deletions packages/core/src/plugins/shims.ts
Original file line number Diff line number Diff line change
@@ -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";`).
Expand Down
4 changes: 4 additions & 0 deletions packages/core/tests/__snapshots__/config.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,7 @@ exports[`Should compose create Rsbuild config correctly > Merge Rsbuild config i
"shebangChmod": 493,
"shebangEntries": {},
"shebangInjectedAssets": Set {},
"shimsInjectedAssets": Set {},
},
],
},
Expand Down Expand Up @@ -474,6 +475,7 @@ exports[`Should compose create Rsbuild config correctly > Merge Rsbuild config i
"shebangChmod": 493,
"shebangEntries": {},
"shebangInjectedAssets": Set {},
"shimsInjectedAssets": Set {},
},
],
},
Expand Down Expand Up @@ -695,6 +697,7 @@ exports[`Should compose create Rsbuild config correctly > Merge Rsbuild config i
"shebangChmod": 493,
"shebangEntries": {},
"shebangInjectedAssets": Set {},
"shimsInjectedAssets": Set {},
},
],
},
Expand Down Expand Up @@ -851,6 +854,7 @@ exports[`Should compose create Rsbuild config correctly > Merge Rsbuild config i
"shebangChmod": 493,
"shebangEntries": {},
"shebangInjectedAssets": Set {},
"shimsInjectedAssets": Set {},
},
],
},
Expand Down
2 changes: 2 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions tests/integration/shims/copy/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"name": "shims-copy-test",
"version": "1.0.0",
"private": true,
"type": "module"
}
13 changes: 13 additions & 0 deletions tests/integration/shims/copy/rslib.config.ts
Original file line number Diff line number Diff line change
@@ -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'],
},
});
3 changes: 3 additions & 0 deletions tests/integration/shims/copy/src/a/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/user/bin/env node

export default 'ok';
1 change: 1 addition & 0 deletions tests/integration/shims/copy/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const squared = (n: number): number => n * n;
16 changes: 16 additions & 0 deletions tests/integration/shims/index.test.ts
Original file line number Diff line number Diff line change
@@ -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';
Expand Down Expand Up @@ -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';
"
`);
});
});
Loading