diff --git a/packages/vite/src/node/ssr/__tests__/fixtures/multi-source-sourcemaps/dist.js b/packages/vite/src/node/ssr/__tests__/fixtures/multi-source-sourcemaps/dist.js new file mode 100644 index 00000000000000..270580dfd19fbe --- /dev/null +++ b/packages/vite/src/node/ssr/__tests__/fixtures/multi-source-sourcemaps/dist.js @@ -0,0 +1,11 @@ +// nested-directory/nested-file.js +var nested_file_default = + 'Nested file will trigger edge case that used to break sourcemaps' + +// entrypoint.js +function entrypoint() { + console.log(nested_file_default) + throw new Error('Hello world') +} +export { entrypoint } +//# sourceMappingURL=dist.js.map diff --git a/packages/vite/src/node/ssr/__tests__/fixtures/multi-source-sourcemaps/dist.js.map b/packages/vite/src/node/ssr/__tests__/fixtures/multi-source-sourcemaps/dist.js.map new file mode 100644 index 00000000000000..b7c04059a25172 --- /dev/null +++ b/packages/vite/src/node/ssr/__tests__/fixtures/multi-source-sourcemaps/dist.js.map @@ -0,0 +1,7 @@ +{ + "version": 3, + "sources": ["nested-directory/nested-file.js", "entrypoint.js"], + "sourcesContent": ["export default 'Nested file will trigger edge case that used to break sourcemaps'\n", "/*\n * You can rebuild this with:\n * - rm -f ./dist.js ./dist.js.map\n * - npx esbuild --bundle entrypoint.js --outfile=dist.js --sourcemap --format=esm\n */\n\nimport nested from './nested-directory/nested-file'\n\nexport function entrypoint() {\n console.log(nested)\n throw new Error('Hello world')\n}\n"], + "mappings": ";AAAA,IAAO,sBAAQ;;;ACQR,SAAS,aAAa;AAC3B,UAAQ,IAAI,mBAAM;AAClB,QAAM,IAAI,MAAM,aAAa;AAC/B;", + "names": [] +} diff --git a/packages/vite/src/node/ssr/__tests__/fixtures/multi-source-sourcemaps/entrypoint.js b/packages/vite/src/node/ssr/__tests__/fixtures/multi-source-sourcemaps/entrypoint.js new file mode 100644 index 00000000000000..296dbdcd39cfa0 --- /dev/null +++ b/packages/vite/src/node/ssr/__tests__/fixtures/multi-source-sourcemaps/entrypoint.js @@ -0,0 +1,12 @@ +/* + * You can rebuild this with: + * - rm -f ./dist.js ./dist.js.map + * - npx esbuild --bundle entrypoint.js --outfile=dist.js --sourcemap --format=esm + */ + +import nested from './nested-directory/nested-file' + +export function entrypoint() { + console.log(nested) + throw new Error('Hello world') +} diff --git a/packages/vite/src/node/ssr/__tests__/fixtures/multi-source-sourcemaps/nested-directory/nested-file.js b/packages/vite/src/node/ssr/__tests__/fixtures/multi-source-sourcemaps/nested-directory/nested-file.js new file mode 100644 index 00000000000000..83bb722b8fe67c --- /dev/null +++ b/packages/vite/src/node/ssr/__tests__/fixtures/multi-source-sourcemaps/nested-directory/nested-file.js @@ -0,0 +1 @@ +export default 'Nested file will trigger edge case that used to break sourcemaps' diff --git a/packages/vite/src/node/ssr/__tests__/ssrTransform.spec.ts b/packages/vite/src/node/ssr/__tests__/ssrTransform.spec.ts index 0bd938cdd46e0a..2106788de1b2b1 100644 --- a/packages/vite/src/node/ssr/__tests__/ssrTransform.spec.ts +++ b/packages/vite/src/node/ssr/__tests__/ssrTransform.spec.ts @@ -441,6 +441,31 @@ test('sourcemap with multiple sources', async () => { } }) +test('sourcemap with multiple sources and nested paths', async () => { + const code = readFixture('dist.js') + const map = readFixture('dist.js.map') + + const result = await ssrTransform(code, JSON.parse(map), '', code) + assert(result?.map) + + const { sources } = result.map as SourceMap + expect(sources).toMatchInlineSnapshot(` + [ + "nested-directory/nested-file.js", + "entrypoint.js", + ] + `) + + function readFixture(filename: string) { + const url = new URL( + `./fixtures/multi-source-sourcemaps/${filename}`, + import.meta.url, + ) + + return readFileSync(fileURLToPath(url), 'utf8') + } +}) + test('overwrite bindings', async () => { expect( await ssrTransformSimpleCode( diff --git a/packages/vite/src/node/ssr/ssrTransform.ts b/packages/vite/src/node/ssr/ssrTransform.ts index a03eb7266d9d18..f075c00368731c 100644 --- a/packages/vite/src/node/ssr/ssrTransform.ts +++ b/packages/vite/src/node/ssr/ssrTransform.ts @@ -346,6 +346,10 @@ async function ssrTransformScript( }) let map = s.generateMap({ hires: 'boundary' }) + map.sources = [path.basename(url)] + // needs to use originalCode instead of code + // because code might be already transformed even if map is null + map.sourcesContent = [originalCode] if ( inMap && inMap.mappings && @@ -353,18 +357,9 @@ async function ssrTransformScript( inMap.sources.length > 0 ) { map = combineSourcemaps(url, [ - { - ...map, - sources: inMap.sources, - sourcesContent: inMap.sourcesContent, - } as RawSourceMap, + map as RawSourceMap, inMap as RawSourceMap, ]) as SourceMap - } else { - map.sources = [path.basename(url)] - // needs to use originalCode instead of code - // because code might be already transformed even if map is null - map.sourcesContent = [originalCode] } return {