From 4eee61fbb9737b9fa5d2a99dd84d38b14bbdc3e6 Mon Sep 17 00:00:00 2001 From: Miao Wang Date: Tue, 23 Apr 2024 11:39:03 +0800 Subject: [PATCH] fix(legacy): improve deterministic build of the polyfill bundle by sorting the polyfills discovered by babel --- packages/plugin-legacy/src/index.ts | 44 +++++++++++++++++++++++++++-- 1 file changed, 41 insertions(+), 3 deletions(-) diff --git a/packages/plugin-legacy/src/index.ts b/packages/plugin-legacy/src/index.ts index d1489fda5bb91d..4da71aa55237aa 100644 --- a/packages/plugin-legacy/src/index.ts +++ b/packages/plugin-legacy/src/index.ts @@ -158,6 +158,11 @@ function viteLegacyPlugin(options: Options = {}): Plugin[] { const facadeToModernPolyfillMap = new Map() const modernPolyfills = new Set() const legacyPolyfills = new Set() + const polyfillsDiscovered = { + modern: new Map(), + legacy: new Map(), + } + const orderedChunks: string[] = [] if (Array.isArray(options.modernPolyfills) && genModern) { options.modernPolyfills.forEach((i) => { @@ -253,6 +258,25 @@ function viteLegacyPlugin(options: Options = {}): Plugin[] { }, } + function sortPolyfills(polyfillInfo: Map): Set { + const resultSet = new Set() + orderedChunks.forEach((chunkName) => { + const polyfills = polyfillInfo.get(chunkName) + if (polyfills) { + polyfills.forEach((p) => { + resultSet.add(p) + }) + } + polyfillInfo.delete(chunkName) + }) + if (polyfillInfo.size) { + throw new Error( + 'Unexpected chunk: ' + Array.from(polyfillInfo.keys()).join(', '), + ) + } + return resultSet + } + const legacyGenerateBundlePlugin: Plugin = { name: 'vite:legacy-generate-polyfill-chunk', apply: 'build', @@ -263,6 +287,9 @@ function viteLegacyPlugin(options: Options = {}): Plugin[] { } if (!isLegacyBundle(bundle, opts)) { + sortPolyfills(polyfillsDiscovered.modern).forEach((polyfill) => { + modernPolyfills.add(polyfill) + }) if (!modernPolyfills.size) { return } @@ -291,6 +318,10 @@ function viteLegacyPlugin(options: Options = {}): Plugin[] { return } + sortPolyfills(polyfillsDiscovered.legacy).forEach((polyfill) => { + legacyPolyfills.add(polyfill) + }) + // legacy bundle if (options.polyfills !== false) { // check if the target needs Promise polyfill because SystemJS relies on it @@ -410,10 +441,13 @@ function viteLegacyPlugin(options: Options = {}): Plugin[] { } }, - async renderChunk(raw, chunk, opts) { + async renderChunk(raw, chunk, opts, { chunks }) { if (config.build.ssr) { return null } + if (!orderedChunks.length) { + orderedChunks.push(...Object.keys(chunks)) + } if (!isLegacyChunk(chunk, opts)) { if ( @@ -422,7 +456,9 @@ function viteLegacyPlugin(options: Options = {}): Plugin[] { genModern ) { // analyze and record modern polyfills - await detectPolyfills(raw, modernTargets, modernPolyfills) + const polyfills = new Set() + await detectPolyfills(raw, modernTargets, polyfills) + polyfillsDiscovered.modern.set(chunk.fileName, [...polyfills]) } const ms = new MagicString(raw) @@ -481,6 +517,7 @@ function viteLegacyPlugin(options: Options = {}): Plugin[] { // transform the legacy chunk with @babel/preset-env const sourceMaps = !!config.build.sourcemap const babel = await loadBabel() + const polyfills = new Set() const result = babel.transform(raw, { babelrc: false, configFile: false, @@ -493,7 +530,7 @@ function viteLegacyPlugin(options: Options = {}): Plugin[] { [ () => ({ plugins: [ - recordAndRemovePolyfillBabelPlugin(legacyPolyfills), + recordAndRemovePolyfillBabelPlugin(polyfills), replaceLegacyEnvBabelPlugin(), wrapIIFEBabelPlugin(), ], @@ -505,6 +542,7 @@ function viteLegacyPlugin(options: Options = {}): Plugin[] { ], ], }) + polyfillsDiscovered.legacy.set(chunk.fileName, [...polyfills]) if (result) return { code: result.code!, map: result.map } return null