diff --git a/packages/vite/src/node/plugins/importAnalysis.ts b/packages/vite/src/node/plugins/importAnalysis.ts index c33cd519fb4da7..620fa38175d19d 100644 --- a/packages/vite/src/node/plugins/importAnalysis.ts +++ b/packages/vite/src/node/plugins/importAnalysis.ts @@ -850,16 +850,17 @@ export function interopNamedImports( se: expEnd, d: dynamicIndex, } = importSpecifier + const exp = source.slice(expStart, expEnd) if (dynamicIndex > -1) { // rewrite `import('package')` to expose the default directly str.overwrite( expStart, expEnd, - `import('${rewrittenUrl}').then(m => m.default && m.default.__esModule ? m.default : ({ ...m.default, default: m.default }))`, + `import('${rewrittenUrl}').then(m => m.default && m.default.__esModule ? m.default : ({ ...m.default, default: m.default }))` + + getLineBreaks(exp), { contentOnly: true }, ) } else { - const exp = source.slice(expStart, expEnd) const rawUrl = source.slice(start, end) const rewritten = transformCjsImport( exp, @@ -870,14 +871,28 @@ export function interopNamedImports( config, ) if (rewritten) { - str.overwrite(expStart, expEnd, rewritten, { contentOnly: true }) + str.overwrite(expStart, expEnd, rewritten + getLineBreaks(exp), { + contentOnly: true, + }) } else { // #1439 export * from '...' - str.overwrite(start, end, rewrittenUrl, { contentOnly: true }) + str.overwrite( + start, + end, + rewrittenUrl + getLineBreaks(source.slice(start, end)), + { + contentOnly: true, + }, + ) } } } +// get line breaks to preserve line count for not breaking source maps +function getLineBreaks(str: string) { + return str.includes('\n') ? '\n'.repeat(str.split('\n').length - 1) : '' +} + type ImportNameSpecifier = { importedName: string; localName: string } /** diff --git a/playground/js-sourcemap/__tests__/js-sourcemap.spec.ts b/playground/js-sourcemap/__tests__/js-sourcemap.spec.ts index ce67f19e904521..2b8044f40fa32e 100644 --- a/playground/js-sourcemap/__tests__/js-sourcemap.spec.ts +++ b/playground/js-sourcemap/__tests__/js-sourcemap.spec.ts @@ -36,6 +36,32 @@ if (!isBuild) { `) }) + test('multiline import', async () => { + const res = await page.request.get( + new URL('./with-multiline-import.ts', page.url()).href, + ) + const multi = await res.text() + const map = extractSourcemap(multi) + expect(formatSourcemapForSnapshot(map)).toMatchInlineSnapshot(` + { + "mappings": "AACA;AAAA,EACE;AAAA,OACK;AAEP,QAAQ,IAAI,yBAAyB,GAAG;", + "sources": [ + "with-multiline-import.ts", + ], + "sourcesContent": [ + "// prettier-ignore + import { + foo + } from '@vitejs/test-importee-pkg' + + console.log('with-multiline-import', foo) + ", + ], + "version": 3, + } + `) + }) + test('should not output missing source file warning', () => { serverLogs.forEach((log) => { expect(log).not.toMatch(/Sourcemap for .+ points to missing source files/) diff --git a/playground/js-sourcemap/importee-pkg/index.js b/playground/js-sourcemap/importee-pkg/index.js new file mode 100644 index 00000000000000..a96b15202fba44 --- /dev/null +++ b/playground/js-sourcemap/importee-pkg/index.js @@ -0,0 +1,2 @@ +// eslint-disable-next-line import/no-commonjs +exports.foo = 'foo' diff --git a/playground/js-sourcemap/importee-pkg/package.json b/playground/js-sourcemap/importee-pkg/package.json new file mode 100644 index 00000000000000..2bc76d5bb50b39 --- /dev/null +++ b/playground/js-sourcemap/importee-pkg/package.json @@ -0,0 +1,6 @@ +{ + "name": "@vitejs/test-importee-pkg", + "private": true, + "version": "0.0.0", + "main": "./index.js" +} diff --git a/playground/js-sourcemap/index.html b/playground/js-sourcemap/index.html index bda409a5cc9693..f669bf4fc102aa 100644 --- a/playground/js-sourcemap/index.html +++ b/playground/js-sourcemap/index.html @@ -6,3 +6,4 @@

JS Sourcemap

+ diff --git a/playground/js-sourcemap/package.json b/playground/js-sourcemap/package.json index 6381b13c9b09e9..b002697756a24c 100644 --- a/playground/js-sourcemap/package.json +++ b/playground/js-sourcemap/package.json @@ -8,5 +8,8 @@ "build": "vite build", "debug": "node --inspect-brk ../../packages/vite/bin/vite", "preview": "vite preview" + }, + "dependencies": { + "@vitejs/test-importee-pkg": "file:importee-pkg" } } diff --git a/playground/js-sourcemap/with-multiline-import.ts b/playground/js-sourcemap/with-multiline-import.ts new file mode 100644 index 00000000000000..5bf8aa53214384 --- /dev/null +++ b/playground/js-sourcemap/with-multiline-import.ts @@ -0,0 +1,6 @@ +// prettier-ignore +import { + foo +} from '@vitejs/test-importee-pkg' + +console.log('with-multiline-import', foo) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e3ad26d4ccdb3e..f68bc2bd12eb42 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -692,7 +692,13 @@ importers: playground/import-assertion/import-assertion-dep: {} - playground/js-sourcemap: {} + playground/js-sourcemap: + dependencies: + '@vitejs/test-importee-pkg': + specifier: file:importee-pkg + version: file:playground/js-sourcemap/importee-pkg + + playground/js-sourcemap/importee-pkg: {} playground/json: devDependencies: @@ -10854,6 +10860,11 @@ packages: name: '@vitejs/test-import-assertion-dep' dev: false + file:playground/js-sourcemap/importee-pkg: + resolution: {directory: playground/js-sourcemap/importee-pkg, type: directory} + name: '@vitejs/test-importee-pkg' + dev: false + file:playground/json/json-module: resolution: {directory: playground/json/json-module, type: directory} name: '@vitejs/test-json-module'