diff --git a/packages/vite/src/node/plugins/importAnalysisBuild.ts b/packages/vite/src/node/plugins/importAnalysisBuild.ts index da43afbe668a09..2311f0859ef4d3 100644 --- a/packages/vite/src/node/plugins/importAnalysisBuild.ts +++ b/packages/vite/src/node/plugins/importAnalysisBuild.ts @@ -507,13 +507,11 @@ function __vite__mapDeps(indexes) { return indexes.map((i) => __vite__mapDeps.viteFileDeps[i]) }\n` - // inject extra code before sourcemap comment - const mapFileCommentMatch = - convertSourceMap.mapFileCommentRegex.exec(code) - if (mapFileCommentMatch) { - s.appendRight(mapFileCommentMatch.index, mapDepsCode) + // inject extra code at the top or next line of hashbang + if (code.startsWith('#!')) { + s.prependLeft(code.indexOf('\n') + 1, mapDepsCode) } else { - s.append(mapDepsCode) + s.prepend(mapDepsCode) } // there may still be markers due to inlined dynamic imports, remove diff --git a/playground/js-sourcemap/__tests__/js-sourcemap.spec.ts b/playground/js-sourcemap/__tests__/js-sourcemap.spec.ts index 7c22274b2a3a66..be37165a35c10e 100644 --- a/playground/js-sourcemap/__tests__/js-sourcemap.spec.ts +++ b/playground/js-sourcemap/__tests__/js-sourcemap.spec.ts @@ -137,7 +137,7 @@ describe.runIf(isBuild)('build tests', () => { const map = findAssetFile(/after-preload-dynamic.*\.js\.map/) expect(formatSourcemapForSnapshot(JSON.parse(map))).toMatchInlineSnapshot(` { - "mappings": "i3BAAA,OAAO,2BAAuB,EAAC,wBAE/B,QAAQ,IAAI,uBAAuB", + "mappings": ";;;;;;i3BAAA,OAAO,2BAAuB,EAAC,wBAE/B,QAAQ,IAAI,uBAAuB", "sources": [ "../../after-preload-dynamic.js", ], @@ -150,10 +150,10 @@ describe.runIf(isBuild)('build tests', () => { "version": 3, } `) - // + // verify sourcemap comment is preserved at the last line const js = findAssetFile(/after-preload-dynamic.*\.js$/) - expect(js.trim().split('\n').at(-1)).toMatch( - /^\/\/# sourceMappingURL=after-preload-dynamic.*\.js\.map$/, + expect(js).toMatch( + /\n\/\/# sourceMappingURL=after-preload-dynamic.*\.js\.map\n$/, ) }) }) diff --git a/playground/js-sourcemap/after-preload-dynamic-hashbang.js b/playground/js-sourcemap/after-preload-dynamic-hashbang.js new file mode 100644 index 00000000000000..918cdeff7932a4 --- /dev/null +++ b/playground/js-sourcemap/after-preload-dynamic-hashbang.js @@ -0,0 +1,5 @@ +// hashbang is injected via rollupOptions.output.banner + +import('./dynamic/dynamic-foo') + +console.log('after preload dynamic hashbang') diff --git a/playground/js-sourcemap/index.html b/playground/js-sourcemap/index.html index 80ee729d99ce90..37ebf9397507c7 100644 --- a/playground/js-sourcemap/index.html +++ b/playground/js-sourcemap/index.html @@ -6,5 +6,6 @@

JS Sourcemap

+ diff --git a/playground/js-sourcemap/vite.config.js b/playground/js-sourcemap/vite.config.js index 41484f2c99d0f3..ba1c3510fc23b5 100644 --- a/playground/js-sourcemap/vite.config.js +++ b/playground/js-sourcemap/vite.config.js @@ -12,9 +12,17 @@ export default defineConfig({ rollupOptions: { output: { manualChunks(name) { - if (name.includes('after-preload-dynamic')) { + if (name.endsWith('after-preload-dynamic.js')) { return 'after-preload-dynamic' } + if (name.endsWith('after-preload-dynamic-hashbang.js')) { + return 'after-preload-dynamic-hashbang' + } + }, + banner(chunk) { + if (chunk.name.endsWith('after-preload-dynamic-hashbang')) { + return '#!/usr/bin/env node' + } }, }, },