diff --git a/packages/plugin-legacy/README.md b/packages/plugin-legacy/README.md index 04abcec6a3a4e5..da3c0adf3ff6d7 100644 --- a/packages/plugin-legacy/README.md +++ b/packages/plugin-legacy/README.md @@ -117,6 +117,13 @@ npm add -D terser Defaults to `false`. Enabling this option will exclude `systemjs/dist/s.min.js` inside polyfills-legacy chunk. +### `renderModernChunks` + +- **Type:** `boolean` +- **Default:** `true` + + Set to `false` to only output the legacy bundles that support all target browsers. + ## Browsers that supports ESM but does not support widely-available features The legacy plugin offers a way to use widely-available features natively in the modern build, while falling back to the legacy build in browsers with native ESM but without those features supported (e.g. Legacy Edge). This feature works by injecting a runtime check and loading the legacy bundle with SystemJs runtime if needed. There are the following drawbacks: diff --git a/packages/plugin-legacy/src/index.ts b/packages/plugin-legacy/src/index.ts index b9e3be2a852802..69524956f00db0 100644 --- a/packages/plugin-legacy/src/index.ts +++ b/packages/plugin-legacy/src/index.ts @@ -125,6 +125,12 @@ function viteLegacyPlugin(options: Options = {}): Plugin[] { let targets: Options['targets'] const genLegacy = options.renderLegacyChunks !== false + const genModern = options.renderModernChunks !== false + if (!genLegacy && !genModern) { + throw new Error( + '`renderLegacyChunks` and `renderModernChunks` cannot be both false', + ) + } const debugFlags = (process.env.DEBUG || '').split(',') const isDebug = @@ -136,7 +142,7 @@ function viteLegacyPlugin(options: Options = {}): Plugin[] { const modernPolyfills = new Set() const legacyPolyfills = new Set() - if (Array.isArray(options.modernPolyfills)) { + if (Array.isArray(options.modernPolyfills) && genModern) { options.modernPolyfills.forEach((i) => { modernPolyfills.add( i.includes('/') ? `core-js/${i}` : `core-js/modules/${i}.js`, @@ -343,9 +349,15 @@ function viteLegacyPlugin(options: Options = {}): Plugin[] { const { rollupOptions } = config.build const { output } = rollupOptions if (Array.isArray(output)) { - rollupOptions.output = [...output.map(createLegacyOutput), ...output] + rollupOptions.output = [ + ...output.map(createLegacyOutput), + ...(genModern ? output : []), + ] } else { - rollupOptions.output = [createLegacyOutput(output), output || {}] + rollupOptions.output = [ + createLegacyOutput(output), + ...(genModern ? [output || {}] : []), + ] } }, @@ -357,7 +369,8 @@ function viteLegacyPlugin(options: Options = {}): Plugin[] { if (!isLegacyChunk(chunk, opts)) { if ( options.modernPolyfills && - !Array.isArray(options.modernPolyfills) + !Array.isArray(options.modernPolyfills) && + genModern ) { // analyze and record modern polyfills await detectPolyfills(raw, { esmodules: true }, modernPolyfills) @@ -455,37 +468,44 @@ function viteLegacyPlugin(options: Options = {}): Plugin[] { if (config.build.ssr) return if (!chunk) return if (chunk.fileName.includes('-legacy')) { - // The legacy bundle is built first, and its index.html isn't actually - // emitted. Here we simply record its corresponding legacy chunk. + // The legacy bundle is built first, and its index.html isn't actually emitted if + // modern bundle will be generated. Here we simply record its corresponding legacy chunk. facadeToLegacyChunkMap.set(chunk.facadeModuleId, chunk.fileName) - return + if (genModern) { + return + } + } + if (!genModern) { + html = html.replace(/