Skip to content

Commit 48edfcd

Browse files
shankerwangmiaobluwy
andauthoredMay 29, 2024··
fix(plugin-legacy): improve deterministic polyfills discovery (#16566)
Co-authored-by: bluwy <bjornlu.dev@gmail.com>
1 parent 7b0a65e commit 48edfcd

File tree

1 file changed

+37
-3
lines changed

1 file changed

+37
-3
lines changed
 

‎packages/plugin-legacy/src/index.ts

+37-3
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,11 @@ function viteLegacyPlugin(options: Options = {}): Plugin[] {
158158
const facadeToModernPolyfillMap = new Map()
159159
const modernPolyfills = new Set<string>()
160160
const legacyPolyfills = new Set<string>()
161+
// When discovering polyfills in `renderChunk`, the hook may be non-deterministic, so we group the
162+
// modern and legacy polyfills in a sorted map before merging them.
163+
let chunkFileNameToPolyfills:
164+
| Map<string, { modern: Set<string>; legacy: Set<string> }>
165+
| undefined
161166

162167
if (Array.isArray(options.modernPolyfills) && genModern) {
163168
options.modernPolyfills.forEach((i) => {
@@ -263,6 +268,12 @@ function viteLegacyPlugin(options: Options = {}): Plugin[] {
263268
}
264269

265270
if (!isLegacyBundle(bundle, opts)) {
271+
// Merge discovered modern polyfills to `modernPolyfills`
272+
if (chunkFileNameToPolyfills) {
273+
for (const { modern } of chunkFileNameToPolyfills.values()) {
274+
modern.forEach((p) => modernPolyfills.add(p))
275+
}
276+
}
266277
if (!modernPolyfills.size) {
267278
return
268279
}
@@ -291,6 +302,13 @@ function viteLegacyPlugin(options: Options = {}): Plugin[] {
291302
return
292303
}
293304

305+
// Merge discovered legacy polyfills to `legacyPolyfills`
306+
if (chunkFileNameToPolyfills) {
307+
for (const { legacy } of chunkFileNameToPolyfills.values()) {
308+
legacy.forEach((p) => legacyPolyfills.add(p))
309+
}
310+
}
311+
294312
// legacy bundle
295313
if (options.polyfills !== false) {
296314
// check if the target needs Promise polyfill because SystemJS relies on it
@@ -330,6 +348,10 @@ function viteLegacyPlugin(options: Options = {}): Plugin[] {
330348
enforce: 'post',
331349
apply: 'build',
332350

351+
renderStart() {
352+
chunkFileNameToPolyfills = undefined
353+
},
354+
333355
configResolved(_config) {
334356
if (_config.build.lib) {
335357
throw new Error('@vitejs/plugin-legacy does not support library mode.')
@@ -410,19 +432,31 @@ function viteLegacyPlugin(options: Options = {}): Plugin[] {
410432
}
411433
},
412434

413-
async renderChunk(raw, chunk, opts) {
435+
async renderChunk(raw, chunk, opts, { chunks }) {
414436
if (config.build.ssr) {
415437
return null
416438
}
417439

440+
// On first run, intialize the map with sorted chunk file names
441+
if (chunkFileNameToPolyfills == null) {
442+
chunkFileNameToPolyfills = new Map()
443+
for (const fileName in chunks) {
444+
chunkFileNameToPolyfills.set(fileName, {
445+
modern: new Set(),
446+
legacy: new Set(),
447+
})
448+
}
449+
}
450+
const polyfillsDiscovered = chunkFileNameToPolyfills.get(chunk.fileName)!
451+
418452
if (!isLegacyChunk(chunk, opts)) {
419453
if (
420454
options.modernPolyfills &&
421455
!Array.isArray(options.modernPolyfills) &&
422456
genModern
423457
) {
424458
// analyze and record modern polyfills
425-
await detectPolyfills(raw, modernTargets, modernPolyfills)
459+
await detectPolyfills(raw, modernTargets, polyfillsDiscovered.modern)
426460
}
427461

428462
const ms = new MagicString(raw)
@@ -493,7 +527,7 @@ function viteLegacyPlugin(options: Options = {}): Plugin[] {
493527
[
494528
() => ({
495529
plugins: [
496-
recordAndRemovePolyfillBabelPlugin(legacyPolyfills),
530+
recordAndRemovePolyfillBabelPlugin(polyfillsDiscovered.legacy),
497531
replaceLegacyEnvBabelPlugin(),
498532
wrapIIFEBabelPlugin(),
499533
],

0 commit comments

Comments
 (0)
Please sign in to comment.