From 0e1da89f256b0b7eb442b1d50ce7ac91362f9faa Mon Sep 17 00:00:00 2001 From: sapphi-red Date: Tue, 29 Aug 2023 17:45:43 +0900 Subject: [PATCH 1/2] fix: handle sourcemap correctly when multiple line import exists --- .../vite/src/node/plugins/importAnalysis.ts | 23 +++++++++++++--- .../__tests__/js-sourcemap.spec.ts | 26 +++++++++++++++++++ playground/js-sourcemap/importee-pkg/index.js | 2 ++ .../js-sourcemap/importee-pkg/package.json | 6 +++++ playground/js-sourcemap/index.html | 1 + playground/js-sourcemap/package.json | 3 +++ .../js-sourcemap/with-multiline-import.ts | 4 +++ pnpm-lock.yaml | 13 +++++++++- 8 files changed, 73 insertions(+), 5 deletions(-) create mode 100644 playground/js-sourcemap/importee-pkg/index.js create mode 100644 playground/js-sourcemap/importee-pkg/package.json create mode 100644 playground/js-sourcemap/with-multiline-import.ts 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..4d18bab167c75e 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 test multiline + 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..4f9f2ba290ee43 --- /dev/null +++ b/playground/js-sourcemap/with-multiline-import.ts @@ -0,0 +1,4 @@ +// prettier-ignore test multiline +import { foo } from '@vitejs/test-importee-pkg' + +console.log('with-multiline-import', foo) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9cf1f27d174515..297b1b411e03f1 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: @@ -10671,6 +10677,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' From 4a642c3fd97db87ddfa3980d0a9a40c3ecd9062d Mon Sep 17 00:00:00 2001 From: sapphi-red Date: Tue, 29 Aug 2023 18:03:00 +0900 Subject: [PATCH 2/2] chore: fix prettier-ignore --- playground/js-sourcemap/__tests__/js-sourcemap.spec.ts | 2 +- playground/js-sourcemap/with-multiline-import.ts | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/playground/js-sourcemap/__tests__/js-sourcemap.spec.ts b/playground/js-sourcemap/__tests__/js-sourcemap.spec.ts index 4d18bab167c75e..8d1c9d46bc551d 100644 --- a/playground/js-sourcemap/__tests__/js-sourcemap.spec.ts +++ b/playground/js-sourcemap/__tests__/js-sourcemap.spec.ts @@ -57,7 +57,7 @@ if (!isBuild) { "with-multiline-import.ts", ], "sourcesContent": [ - "// prettier-ignore test multiline + "// prettier-ignore import { foo } from '@vitejs/test-importee-pkg' diff --git a/playground/js-sourcemap/with-multiline-import.ts b/playground/js-sourcemap/with-multiline-import.ts index 4f9f2ba290ee43..5bf8aa53214384 100644 --- a/playground/js-sourcemap/with-multiline-import.ts +++ b/playground/js-sourcemap/with-multiline-import.ts @@ -1,4 +1,6 @@ -// prettier-ignore test multiline -import { foo } from '@vitejs/test-importee-pkg' +// prettier-ignore +import { + foo +} from '@vitejs/test-importee-pkg' console.log('with-multiline-import', foo)