From f311ff3c2b19636457c3023095ef32ab9a96b84a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=BF=A0=20/=20green?= Date: Fri, 4 Oct 2024 21:54:23 +0900 Subject: [PATCH] fix(legacy): generate sourcemap for polyfill chunks (#18250) --- packages/plugin-legacy/src/index.ts | 55 ++++++++++++++++++---- playground/legacy/__tests__/legacy.spec.ts | 14 ++++-- 2 files changed, 57 insertions(+), 12 deletions(-) diff --git a/packages/plugin-legacy/src/index.ts b/packages/plugin-legacy/src/index.ts index 4bd497f1af8de8..355a5e0f214d2b 100644 --- a/packages/plugin-legacy/src/index.ts +++ b/packages/plugin-legacy/src/index.ts @@ -13,7 +13,9 @@ import type { } from 'vite' import type { NormalizedOutputOptions, + OutputAsset, OutputBundle, + OutputChunk, OutputOptions, PreRenderedChunk, RenderedChunk, @@ -302,7 +304,7 @@ function viteLegacyPlugin(options: Options = {}): Plugin[] { modernPolyfills, ) } - const polyfillChunk = await buildPolyfillChunk( + await buildPolyfillChunk( config.mode, modernPolyfills, bundle, @@ -311,10 +313,8 @@ function viteLegacyPlugin(options: Options = {}): Plugin[] { 'es', opts, true, + genLegacy, ) - if (genLegacy && polyfillChunk) { - polyfillChunk.code = modernChunkLegacyGuard + polyfillChunk.code - } return } @@ -789,8 +789,9 @@ async function buildPolyfillChunk( format: 'iife' | 'es', rollupOutputOptions: NormalizedOutputOptions, excludeSystemJS?: boolean, + prependModenChunkLegacyGuard?: boolean, ) { - let { minify, assetsDir } = buildOptions + let { minify, assetsDir, sourcemap } = buildOptions minify = minify ? 'terser' : false const res = await build({ mode, @@ -798,11 +799,15 @@ async function buildPolyfillChunk( root: path.dirname(fileURLToPath(import.meta.url)), configFile: false, logLevel: 'error', - plugins: [polyfillsPlugin(imports, excludeSystemJS)], + plugins: [ + polyfillsPlugin(imports, excludeSystemJS), + prependModenChunkLegacyGuard && prependModenChunkLegacyGuardPlugin(), + ], build: { write: false, minify, assetsDir, + sourcemap, rollupOptions: { input: { polyfills: polyfillId, @@ -828,7 +833,9 @@ async function buildPolyfillChunk( }) const _polyfillChunk = Array.isArray(res) ? res[0] : res if (!('output' in _polyfillChunk)) return - const polyfillChunk = _polyfillChunk.output[0] + const polyfillChunk = _polyfillChunk.output.find( + (chunk) => chunk.type === 'chunk' && chunk.isEntry, + ) as OutputChunk // associate the polyfill chunk to every entry chunk so that we can retrieve // the polyfill filename in index html transform @@ -841,8 +848,16 @@ async function buildPolyfillChunk( // add the chunk to the bundle bundle[polyfillChunk.fileName] = polyfillChunk - - return polyfillChunk + if (polyfillChunk.sourcemapFileName) { + const polyfillChunkMapAsset = _polyfillChunk.output.find( + (chunk) => + chunk.type === 'asset' && + chunk.fileName === polyfillChunk.sourcemapFileName, + ) as OutputAsset | undefined + if (polyfillChunkMapAsset) { + bundle[polyfillChunk.sourcemapFileName] = polyfillChunkMapAsset + } + } } const polyfillId = '\0vite/legacy-polyfills' @@ -869,6 +884,28 @@ function polyfillsPlugin( } } +function prependModenChunkLegacyGuardPlugin(): Plugin { + let sourceMapEnabled!: boolean + return { + name: 'vite:legacy-prepend-moden-chunk-legacy-guard', + configResolved(config) { + sourceMapEnabled = !!config.build.sourcemap + }, + renderChunk(code) { + if (!sourceMapEnabled) { + return modernChunkLegacyGuard + code + } + + const ms = new MagicString(code) + ms.prepend(modernChunkLegacyGuard) + return { + code: ms.toString(), + map: ms.generateMap({ hires: 'boundary' }), + } + }, + } +} + function isLegacyChunk(chunk: RenderedChunk, options: NormalizedOutputOptions) { return options.format === 'system' && chunk.fileName.includes('-legacy') } diff --git a/playground/legacy/__tests__/legacy.spec.ts b/playground/legacy/__tests__/legacy.spec.ts index cc747761588ca5..8318df00a9a964 100644 --- a/playground/legacy/__tests__/legacy.spec.ts +++ b/playground/legacy/__tests__/legacy.spec.ts @@ -143,13 +143,21 @@ describe.runIf(isBuild)('build', () => { test('should generate legacy sourcemap file', async () => { expect( - listAssets().some((filename) => /index-legacy.+\.map$/.test(filename)), + listAssets().some((filename) => + /index-legacy-[-\w]{8}\.js\.map$/.test(filename), + ), ).toBeTruthy() expect( listAssets().some((filename) => - /polyfills-legacy.+\.map$/.test(filename), + /polyfills-legacy-[-\w]{8}\.js\.map$/.test(filename), ), - ).toBeFalsy() + ).toBeTruthy() + // also for modern polyfills + expect( + listAssets().some((filename) => + /polyfills-[-\w]{8}\.js\.map$/.test(filename), + ), + ).toBeTruthy() }) test('should have only modern entry files guarded', async () => {