Skip to content

Commit 2f6be01

Browse files
committed
feat: support import.meta.url shim for CJS
1 parent 057cd87 commit 2f6be01

File tree

8 files changed

+114
-1
lines changed

8 files changed

+114
-1
lines changed

e2e/cases/shims/cjs/package.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"name": "shims-cjs-test",
3+
"version": "1.0.0",
4+
"private": true,
5+
"type": "module"
6+
}

e2e/cases/shims/cjs/rslib.config.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import { generateBundleCjsConfig } from '@e2e/helper';
2+
import { defineConfig } from '@rslib/core';
3+
4+
export default defineConfig({
5+
lib: [generateBundleCjsConfig()],
6+
output: {
7+
target: 'node',
8+
},
9+
source: {
10+
entry: {
11+
index: './src/index.ts',
12+
},
13+
},
14+
});

e2e/cases/shims/cjs/src/index.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export const foo = () => {
2+
console.log(import.meta.url);
3+
};

e2e/cases/shims/index.test.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,15 @@ test('shims for __dirname and __filename in ESM', async () => {
1616
}
1717
});
1818

19-
test.todo('shims for import.meta.url in CJS', async () => {});
19+
test('shims for import.meta.url in CJS', async () => {
20+
const fixturePath = join(__dirname, 'cjs');
21+
const { entries } = await buildAndGetResults(fixturePath);
22+
for (const shim of [
23+
`var __rslib_import_meta_url__ = /*#__PURE__*/ function() {
24+
'undefined' == typeof document ? new (require('url'.replace('', ''))).URL('file:' + __filename).href : document.currentScript && document.currentScript.src || new URL('main.js', document.baseURI).href;
25+
}();`,
26+
'console.log(__rslib_import_meta_url__);',
27+
]) {
28+
expect(entries.cjs).toContain(shim);
29+
}
30+
});

packages/core/src/config.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import {
1515
DEFAULT_EXTENSIONS,
1616
SWC_HELPERS,
1717
} from './constant';
18+
import { pluginCjsShim } from './plugins/cjsShim';
1819
import type {
1920
AutoExternal,
2021
BannerAndFooter,
@@ -456,8 +457,16 @@ const composeFormatConfig = (format: Format): RsbuildConfig => {
456457
};
457458
case 'cjs':
458459
return {
460+
plugins: [pluginCjsShim()],
459461
tools: {
460462
rspack: {
463+
module: {
464+
parser: {
465+
javascript: {
466+
importMeta: false,
467+
},
468+
},
469+
},
461470
output: {
462471
iife: false,
463472
chunkFormat: 'commonjs',
@@ -472,6 +481,13 @@ const composeFormatConfig = (format: Format): RsbuildConfig => {
472481
return {
473482
tools: {
474483
rspack: {
484+
module: {
485+
parser: {
486+
javascript: {
487+
importMeta: false,
488+
},
489+
},
490+
},
475491
output: {
476492
library: {
477493
type: 'umd',

packages/core/src/plugins/cjsShim.ts

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import { type RsbuildPlugin, rspack } from '@rsbuild/core';
2+
3+
const importMetaUrlShim = `var __rslib_import_meta_url__ = /*#__PURE__*/ (function () {
4+
typeof document === 'undefined'
5+
? new (require('url'.replace('', '')).URL)('file:' + __filename).href
6+
: (document.currentScript && document.currentScript.src) ||
7+
new URL('main.js', document.baseURI).href;
8+
})();
9+
`;
10+
11+
// This Rsbuild plugin will shim `import.meta.url` for CommonJS modules.
12+
// - Replace `import.meta.url` with `importMetaUrl`.
13+
// - Inject `importMetaUrl` to the end of the module (can't inject at the beginning because of `"use strict";`).
14+
// This is a short-term solution, and we hope to provide built-in polyfills like `node.__filename` on Rspack side.
15+
export const pluginCjsShim = (): RsbuildPlugin => ({
16+
name: 'rsbuild-plugin-cjs-shim',
17+
18+
setup(api) {
19+
api.modifyRsbuildConfig((config) => {
20+
config.source ||= {};
21+
config.source.define = {
22+
...config.source.define,
23+
'import.meta.url': '__rslib_import_meta_url__',
24+
};
25+
});
26+
27+
api.modifyRspackConfig((config) => {
28+
config.plugins ??= [];
29+
config.plugins.push(
30+
new rspack.BannerPlugin({
31+
banner: importMetaUrlShim,
32+
// Just before minify stage, to perform tree shaking.
33+
stage: rspack.Compilation.PROCESS_ASSETS_STAGE_OPTIMIZE - 1,
34+
raw: true,
35+
footer: true,
36+
include: /\.(js|cjs)$/,
37+
}),
38+
);
39+
});
40+
},
41+
});

packages/core/tests/__snapshots__/config.test.ts.snap

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,12 @@ exports[`Should compose create Rsbuild config correctly > Merge Rsbuild config 1
191191
"not dead",
192192
],
193193
},
194+
"plugins": [
195+
{
196+
"name": "rsbuild-plugin-cjs-shim",
197+
"setup": [Function],
198+
},
199+
],
194200
"source": {
195201
"alias": {
196202
"bar": "bar/cjs",
@@ -243,6 +249,13 @@ exports[`Should compose create Rsbuild config correctly > Merge Rsbuild config 1
243249
},
244250
{
245251
"externalsType": "commonjs",
252+
"module": {
253+
"parser": {
254+
"javascript": {
255+
"importMeta": false,
256+
},
257+
},
258+
},
246259
"output": {
247260
"chunkFormat": "commonjs",
248261
"iife": false,
@@ -373,6 +386,13 @@ exports[`Should compose create Rsbuild config correctly > Merge Rsbuild config 1
373386
},
374387
{
375388
"externalsType": "umd",
389+
"module": {
390+
"parser": {
391+
"javascript": {
392+
"importMeta": false,
393+
},
394+
},
395+
},
376396
"output": {
377397
"library": {
378398
"type": "umd",

pnpm-lock.yaml

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)