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 5a445252120111..8d1c9d46bc551d 100644 --- a/playground/js-sourcemap/__tests__/js-sourcemap.spec.ts +++ b/playground/js-sourcemap/__tests__/js-sourcemap.spec.ts @@ -44,6 +44,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 @@