Skip to content

Commit 931b24f

Browse files
lsdsjyamirkian007sapphi-red
authoredJul 4, 2023
feat(plugin-legacy): add option to output only legacy builds (#10139)
Co-authored-by: “amirkian007” <amircc1200@gmail.com> Co-authored-by: sapphi-red <green@sapphi.red>
1 parent 02c6bc3 commit 931b24f

File tree

3 files changed

+70
-37
lines changed

3 files changed

+70
-37
lines changed
 

‎packages/plugin-legacy/README.md

+7
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,13 @@ npm add -D terser
117117

118118
Defaults to `false`. Enabling this option will exclude `systemjs/dist/s.min.js` inside polyfills-legacy chunk.
119119

120+
### `renderModernChunks`
121+
122+
- **Type:** `boolean`
123+
- **Default:** `true`
124+
125+
Set to `false` to only output the legacy bundles that support all target browsers.
126+
120127
## Browsers that supports ESM but does not support widely-available features
121128

122129
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:

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

+59-37
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,12 @@ function viteLegacyPlugin(options: Options = {}): Plugin[] {
125125
let targets: Options['targets']
126126

127127
const genLegacy = options.renderLegacyChunks !== false
128+
const genModern = options.renderModernChunks !== false
129+
if (!genLegacy && !genModern) {
130+
throw new Error(
131+
'`renderLegacyChunks` and `renderModernChunks` cannot be both false',
132+
)
133+
}
128134

129135
const debugFlags = (process.env.DEBUG || '').split(',')
130136
const isDebug =
@@ -136,7 +142,7 @@ function viteLegacyPlugin(options: Options = {}): Plugin[] {
136142
const modernPolyfills = new Set<string>()
137143
const legacyPolyfills = new Set<string>()
138144

139-
if (Array.isArray(options.modernPolyfills)) {
145+
if (Array.isArray(options.modernPolyfills) && genModern) {
140146
options.modernPolyfills.forEach((i) => {
141147
modernPolyfills.add(
142148
i.includes('/') ? `core-js/${i}` : `core-js/modules/${i}.js`,
@@ -343,9 +349,15 @@ function viteLegacyPlugin(options: Options = {}): Plugin[] {
343349
const { rollupOptions } = config.build
344350
const { output } = rollupOptions
345351
if (Array.isArray(output)) {
346-
rollupOptions.output = [...output.map(createLegacyOutput), ...output]
352+
rollupOptions.output = [
353+
...output.map(createLegacyOutput),
354+
...(genModern ? output : []),
355+
]
347356
} else {
348-
rollupOptions.output = [createLegacyOutput(output), output || {}]
357+
rollupOptions.output = [
358+
createLegacyOutput(output),
359+
...(genModern ? [output || {}] : []),
360+
]
349361
}
350362
},
351363

@@ -357,7 +369,8 @@ function viteLegacyPlugin(options: Options = {}): Plugin[] {
357369
if (!isLegacyChunk(chunk, opts)) {
358370
if (
359371
options.modernPolyfills &&
360-
!Array.isArray(options.modernPolyfills)
372+
!Array.isArray(options.modernPolyfills) &&
373+
genModern
361374
) {
362375
// analyze and record modern polyfills
363376
await detectPolyfills(raw, { esmodules: true }, modernPolyfills)
@@ -455,50 +468,59 @@ function viteLegacyPlugin(options: Options = {}): Plugin[] {
455468
if (config.build.ssr) return
456469
if (!chunk) return
457470
if (chunk.fileName.includes('-legacy')) {
458-
// The legacy bundle is built first, and its index.html isn't actually
459-
// emitted. Here we simply record its corresponding legacy chunk.
471+
// The legacy bundle is built first, and its index.html isn't actually emitted if
472+
// modern bundle will be generated. Here we simply record its corresponding legacy chunk.
460473
facadeToLegacyChunkMap.set(chunk.facadeModuleId, chunk.fileName)
461-
return
474+
if (genModern) {
475+
return
476+
}
477+
}
478+
if (!genModern) {
479+
html = html.replace(/<script type="module".*?<\/script>/g, '')
462480
}
463481

464482
const tags: HtmlTagDescriptor[] = []
465483
const htmlFilename = chunk.facadeModuleId?.replace(/\?.*$/, '')
466484

467485
// 1. inject modern polyfills
468-
const modernPolyfillFilename = facadeToModernPolyfillMap.get(
469-
chunk.facadeModuleId,
470-
)
471-
472-
if (modernPolyfillFilename) {
473-
tags.push({
474-
tag: 'script',
475-
attrs: {
476-
type: 'module',
477-
crossorigin: true,
478-
src: toAssetPathFromHtml(
479-
modernPolyfillFilename,
480-
chunk.facadeModuleId!,
481-
config,
482-
),
483-
},
484-
})
485-
} else if (modernPolyfills.size) {
486-
throw new Error(
487-
`No corresponding modern polyfill chunk found for ${htmlFilename}`,
486+
if (genModern) {
487+
const modernPolyfillFilename = facadeToModernPolyfillMap.get(
488+
chunk.facadeModuleId,
488489
)
490+
491+
if (modernPolyfillFilename) {
492+
tags.push({
493+
tag: 'script',
494+
attrs: {
495+
type: 'module',
496+
crossorigin: true,
497+
src: toAssetPathFromHtml(
498+
modernPolyfillFilename,
499+
chunk.facadeModuleId!,
500+
config,
501+
),
502+
},
503+
})
504+
} else if (modernPolyfills.size) {
505+
throw new Error(
506+
`No corresponding modern polyfill chunk found for ${htmlFilename}`,
507+
)
508+
}
489509
}
490510

491511
if (!genLegacy) {
492512
return { html, tags }
493513
}
494514

495515
// 2. inject Safari 10 nomodule fix
496-
tags.push({
497-
tag: 'script',
498-
attrs: { nomodule: true },
499-
children: safari10NoModuleFix,
500-
injectTo: 'body',
501-
})
516+
if (genModern) {
517+
tags.push({
518+
tag: 'script',
519+
attrs: { nomodule: genModern },
520+
children: safari10NoModuleFix,
521+
injectTo: 'body',
522+
})
523+
}
502524

503525
// 3. inject legacy polyfills
504526
const legacyPolyfillFilename = facadeToLegacyPolyfillMap.get(
@@ -508,7 +530,7 @@ function viteLegacyPlugin(options: Options = {}): Plugin[] {
508530
tags.push({
509531
tag: 'script',
510532
attrs: {
511-
nomodule: true,
533+
nomodule: genModern,
512534
crossorigin: true,
513535
id: legacyPolyfillId,
514536
src: toAssetPathFromHtml(
@@ -534,7 +556,7 @@ function viteLegacyPlugin(options: Options = {}): Plugin[] {
534556
tags.push({
535557
tag: 'script',
536558
attrs: {
537-
nomodule: true,
559+
nomodule: genModern,
538560
crossorigin: true,
539561
// we set the entry path on the element as an attribute so that the
540562
// script content will stay consistent - which allows using a constant
@@ -556,7 +578,7 @@ function viteLegacyPlugin(options: Options = {}): Plugin[] {
556578
}
557579

558580
// 5. inject dynamic import fallback entry
559-
if (genLegacy && legacyPolyfillFilename && legacyEntryFilename) {
581+
if (legacyPolyfillFilename && legacyEntryFilename && genModern) {
560582
tags.push({
561583
tag: 'script',
562584
attrs: { type: 'module' },
@@ -582,7 +604,7 @@ function viteLegacyPlugin(options: Options = {}): Plugin[] {
582604
return
583605
}
584606

585-
if (isLegacyBundle(bundle, opts)) {
607+
if (isLegacyBundle(bundle, opts) && genModern) {
586608
// avoid emitting duplicate assets
587609
for (const name in bundle) {
588610
if (bundle[name].type === 'asset' && !/.+\.map$/.test(name)) {

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

+4
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,8 @@ export interface Options {
2424
* default: false
2525
*/
2626
externalSystemJS?: boolean
27+
/**
28+
* default: true
29+
*/
30+
renderModernChunks?: boolean
2731
}

0 commit comments

Comments
 (0)
Please sign in to comment.