Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(plugin-legacy): improve deterministic polyfills discovery #16566

Merged
merged 3 commits into from
May 29, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 37 additions & 3 deletions packages/plugin-legacy/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,11 @@ function viteLegacyPlugin(options: Options = {}): Plugin[] {
const facadeToModernPolyfillMap = new Map()
const modernPolyfills = new Set<string>()
const legacyPolyfills = new Set<string>()
// When discovering polyfills in `renderChunk`, the hook may be non-deterministic, so we group the
// modern and legacy polyfills in a sorted map before merging them.
let chunkFileNameToPolyfills:
| Map<string, { modern: Set<string>; legacy: Set<string> }>
| undefined

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

if (!isLegacyBundle(bundle, opts)) {
// Merge discovered modern polyfills to `modernPolyfills`
if (chunkFileNameToPolyfills) {
for (const { modern } of chunkFileNameToPolyfills.values()) {
modern.forEach((p) => modernPolyfills.add(p))
}
}
if (!modernPolyfills.size) {
return
}
Expand Down Expand Up @@ -291,6 +302,13 @@ function viteLegacyPlugin(options: Options = {}): Plugin[] {
return
}

// Merge discovered legacy polyfills to `legacyPolyfills`
if (chunkFileNameToPolyfills) {
for (const { legacy } of chunkFileNameToPolyfills.values()) {
legacy.forEach((p) => legacyPolyfills.add(p))
}
}

// legacy bundle
if (options.polyfills !== false) {
// check if the target needs Promise polyfill because SystemJS relies on it
Expand Down Expand Up @@ -330,6 +348,10 @@ function viteLegacyPlugin(options: Options = {}): Plugin[] {
enforce: 'post',
apply: 'build',

renderStart() {
chunkFileNameToPolyfills = undefined
},

configResolved(_config) {
if (_config.build.lib) {
throw new Error('@vitejs/plugin-legacy does not support library mode.')
Expand Down Expand Up @@ -410,19 +432,31 @@ function viteLegacyPlugin(options: Options = {}): Plugin[] {
}
},

async renderChunk(raw, chunk, opts) {
async renderChunk(raw, chunk, opts, { chunks }) {
if (config.build.ssr) {
return null
}

// On first run, intialize the map with sorted chunk file names
if (chunkFileNameToPolyfills == null) {
chunkFileNameToPolyfills = new Map()
for (const fileName in chunks) {
chunkFileNameToPolyfills.set(fileName, {
modern: new Set(),
legacy: new Set(),
})
}
}
const polyfillsDiscovered = chunkFileNameToPolyfills.get(chunk.fileName)!

if (!isLegacyChunk(chunk, opts)) {
if (
options.modernPolyfills &&
!Array.isArray(options.modernPolyfills) &&
genModern
) {
// analyze and record modern polyfills
await detectPolyfills(raw, modernTargets, modernPolyfills)
await detectPolyfills(raw, modernTargets, polyfillsDiscovered.modern)
}

const ms = new MagicString(raw)
Expand Down Expand Up @@ -493,7 +527,7 @@ function viteLegacyPlugin(options: Options = {}): Plugin[] {
[
() => ({
plugins: [
recordAndRemovePolyfillBabelPlugin(legacyPolyfills),
recordAndRemovePolyfillBabelPlugin(polyfillsDiscovered.legacy),
replaceLegacyEnvBabelPlugin(),
wrapIIFEBabelPlugin(),
],
Expand Down