From 1927bc5fdb07ae12d7ce27a33b9cf2de2decb8d4 Mon Sep 17 00:00:00 2001 From: Timeless0911 <1604889533@qq.com> Date: Tue, 27 Aug 2024 15:18:06 +0800 Subject: [PATCH] fix: add extension when relative import already have an extension --- e2e/cases/bundle-false/index.test.ts | 19 +++++++++++++---- .../relative-import/src/baz.js.ts | 1 + .../bundle-false/relative-import/src/foo.js | 1 + .../bundle-false/relative-import/src/index.ts | 7 ++++++- .../bundle-false/relative-import/src/qux.cjs | 3 +++ packages/core/src/config.ts | 21 ++++++++++++------- 6 files changed, 39 insertions(+), 13 deletions(-) create mode 100644 e2e/cases/bundle-false/relative-import/src/baz.js.ts create mode 100644 e2e/cases/bundle-false/relative-import/src/foo.js create mode 100644 e2e/cases/bundle-false/relative-import/src/qux.cjs diff --git a/e2e/cases/bundle-false/index.test.ts b/e2e/cases/bundle-false/index.test.ts index ced06b290..96d1dd4f8 100644 --- a/e2e/cases/bundle-false/index.test.ts +++ b/e2e/cases/bundle-false/index.test.ts @@ -44,10 +44,21 @@ test('auto add extension for relative import', async () => { const fixturePath = join(__dirname, 'relative-import'); const { contents } = await buildAndGetResults(fixturePath); - expect(Object.values(contents.esm)[1]).toContain( + for (const importer of [ 'import * as __WEBPACK_EXTERNAL_MODULE__bar_js__ from "./bar.js";', - ); - expect(Object.values(contents.cjs)[1]).toContain( + 'import * as __WEBPACK_EXTERNAL_MODULE__baz_js__ from "./baz.js";', + 'import * as __WEBPACK_EXTERNAL_MODULE__foo_js__ from "./foo.js";', + 'import * as __WEBPACK_EXTERNAL_MODULE__qux_js__ from "./qux.js";', + ]) { + expect(Object.values(contents.esm)[3]).toContain(importer); + } + + for (const requirer of [ 'var external_bar_cjs_namespaceObject = require("./bar.cjs");', - ); + 'var external_baz_cjs_namespaceObject = require("./baz.cjs");', + 'var external_foo_cjs_namespaceObject = require("./foo.cjs");', + 'var external_qux_cjs_namespaceObject = require("./qux.cjs");', + ]) { + expect(Object.values(contents.cjs)[3]).toContain(requirer); + } }); diff --git a/e2e/cases/bundle-false/relative-import/src/baz.js.ts b/e2e/cases/bundle-false/relative-import/src/baz.js.ts new file mode 100644 index 000000000..6061cf077 --- /dev/null +++ b/e2e/cases/bundle-false/relative-import/src/baz.js.ts @@ -0,0 +1 @@ +export const baz = 'baz'; diff --git a/e2e/cases/bundle-false/relative-import/src/foo.js b/e2e/cases/bundle-false/relative-import/src/foo.js new file mode 100644 index 000000000..3329a7d97 --- /dev/null +++ b/e2e/cases/bundle-false/relative-import/src/foo.js @@ -0,0 +1 @@ +export const foo = 'foo'; diff --git a/e2e/cases/bundle-false/relative-import/src/index.ts b/e2e/cases/bundle-false/relative-import/src/index.ts index 56f92330f..0d4ae0087 100644 --- a/e2e/cases/bundle-false/relative-import/src/index.ts +++ b/e2e/cases/bundle-false/relative-import/src/index.ts @@ -1,3 +1,8 @@ import { bar } from './bar'; +import { baz } from './baz.js'; +// @ts-ignore +import { foo } from './foo.js'; +// @ts-ignore +import { qux } from './qux.cjs'; -export const foo = 'foo' + bar; +export const text = foo + bar + baz + qux; diff --git a/e2e/cases/bundle-false/relative-import/src/qux.cjs b/e2e/cases/bundle-false/relative-import/src/qux.cjs new file mode 100644 index 000000000..5d772419d --- /dev/null +++ b/e2e/cases/bundle-false/relative-import/src/qux.cjs @@ -0,0 +1,3 @@ +module.exports = { + qux: 'qux', +}; diff --git a/packages/core/src/config.ts b/packages/core/src/config.ts index 91e8ac73a..aad986f56 100644 --- a/packages/core/src/config.ts +++ b/packages/core/src/config.ts @@ -1,5 +1,5 @@ import fs from 'node:fs'; -import path, { dirname, isAbsolute, join } from 'node:path'; +import path, { dirname, extname, isAbsolute, join } from 'node:path'; import { type RsbuildConfig, type RsbuildInstance, @@ -475,13 +475,18 @@ const composeBundleConfig = ( // Prevent from externalizing entry modules here. if (data.contextInfo.issuer) { // Node.js ECMAScript module loader does no extension searching. - // So we add a file extension here when data.request is a relative path - return callback( - null, - data.request[0] === '.' - ? `${data.request}${jsExtension}` - : data.request, - ); + // Add a file extension according to autoExtension config + // when data.request is a relative path and do not have an extension. + // If data.request already have an extension, we replace it with new extension + // This may result in a change in semantics, + // user should use copy to keep origin file or use another separate entry to deal this + let request = data.request; + if (request[0] === '.') { + request = extname(request) + ? request.replace(/\.[^.]+$/, jsExtension) + : `${request}${jsExtension}`; + } + return callback(null, request); } callback(); },