diff --git a/packages/core/src/config.ts b/packages/core/src/config.ts index a4fc97f78..e1a357a65 100644 --- a/packages/core/src/config.ts +++ b/packages/core/src/config.ts @@ -3,6 +3,7 @@ import path, { dirname, extname, isAbsolute, join } from 'node:path'; import { type EnvironmentConfig, type RsbuildConfig, + type RsbuildPlugin, defineConfig as defineRsbuildConfig, loadConfig as loadRsbuildConfig, mergeRsbuildConfig, @@ -612,6 +613,19 @@ const composeFormatConfig = ({ } }; +const formatRsbuildPlugin = (): RsbuildPlugin => ({ + name: 'rsbuild:format', + setup(api) { + api.modifyBundlerChain((config, { CHAIN_ID }) => { + // Fix for https://github.com/web-infra-dev/rslib/issues/499. + // Prevent parsing and try bundling `new URL()` in ESM format. + config.module.rule(CHAIN_ID.RULE.JS).parser({ + url: false, + }); + }); + }, +}); + const composeShimsConfig = ( format: Format, shims?: Shims, @@ -657,9 +671,10 @@ const composeShimsConfig = ( }, }, }, - plugins: [resolvedShims.esm.require && pluginEsmRequireShim()].filter( - Boolean, - ), + plugins: [ + resolvedShims.esm.require && pluginEsmRequireShim(), + formatRsbuildPlugin(), + ].filter(Boolean), }; break; } diff --git a/packages/core/tests/__snapshots__/config.test.ts.snap b/packages/core/tests/__snapshots__/config.test.ts.snap index 3959432da..c7de92413 100644 --- a/packages/core/tests/__snapshots__/config.test.ts.snap +++ b/packages/core/tests/__snapshots__/config.test.ts.snap @@ -108,6 +108,10 @@ exports[`Should compose create Rsbuild config correctly > Merge Rsbuild config 1 }, }, "plugins": [ + { + "name": "rsbuild:format", + "setup": [Function], + }, { "name": "rsbuild:lib-entry-chunk", "setup": [Function], diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f68c7bb7f..853fbb0d7 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -659,6 +659,8 @@ importers: tests/integration/externals/node: {} + tests/integration/format: {} + tests/integration/minify/config: {} tests/integration/minify/default: {} diff --git a/tests/integration/format/index.test.ts b/tests/integration/format/index.test.ts new file mode 100644 index 000000000..9e32f5529 --- /dev/null +++ b/tests/integration/format/index.test.ts @@ -0,0 +1,31 @@ +import { buildAndGetResults } from 'test-helper'; +import { expect, test } from 'vitest'; + +test('esm', async () => { + const fixturePath = __dirname; + const { files, entries, entryFiles } = await buildAndGetResults({ + fixturePath, + }); + expect(files).toMatchInlineSnapshot(` + { + "esm": [ + "/tests/integration/format/dist/esm/index.js", + ], + } + `); + expect(entries.esm).toMatchInlineSnapshot(` + "import * as __WEBPACK_EXTERNAL_MODULE_node_url__ from "node:url"; + const packageDirectory = __WEBPACK_EXTERNAL_MODULE_node_url__["default"].fileURLToPath(new URL('.', import.meta.url)); + const foo = 'foo'; + export { foo, packageDirectory }; + " + `); + + const result = await import(entryFiles.esm); + expect(result).toMatchInlineSnapshot(` + { + "foo": "foo", + "packageDirectory": "/tests/integration/format/dist/esm/", + } + `); +}); diff --git a/tests/integration/format/package.json b/tests/integration/format/package.json new file mode 100644 index 000000000..ce11e9b9d --- /dev/null +++ b/tests/integration/format/package.json @@ -0,0 +1,6 @@ +{ + "name": "format-test", + "version": "1.0.0", + "private": true, + "type": "module" +} diff --git a/tests/integration/format/rslib.config.ts b/tests/integration/format/rslib.config.ts new file mode 100644 index 000000000..0f085be28 --- /dev/null +++ b/tests/integration/format/rslib.config.ts @@ -0,0 +1,19 @@ +import { defineConfig } from '@rslib/core'; +import { generateBundleEsmConfig } from 'test-helper'; + +export default defineConfig({ + lib: [ + generateBundleEsmConfig({ + output: { + distPath: { + root: './dist/esm', + }, + }, + }), + ], + source: { + entry: { + index: './src/index.js', + }, + }, +}); diff --git a/tests/integration/format/src/index.js b/tests/integration/format/src/index.js new file mode 100644 index 000000000..83c2eb677 --- /dev/null +++ b/tests/integration/format/src/index.js @@ -0,0 +1 @@ +export { packageDirectory, foo } from './value.js'; diff --git a/tests/integration/format/src/value.js b/tests/integration/format/src/value.js new file mode 100644 index 000000000..f55a49a50 --- /dev/null +++ b/tests/integration/format/src/value.js @@ -0,0 +1,5 @@ +import url from 'node:url'; +export const packageDirectory = url.fileURLToPath( + new URL('.', import.meta.url), +); +export const foo = 'foo';