@@ -124,6 +124,9 @@ const _require = createRequire(import.meta.url)
124
124
const nonLeadingHashInFileNameRE = / [ ^ / ] + \[ h a s h (?: : \d + ) ? \] /
125
125
const prefixedHashInFileNameRE = / \W ? \[ h a s h (?: : \d + ) ? \] /
126
126
127
+ const outputOptionsForLegacyChunks =
128
+ new WeakSet < Rollup . NormalizedOutputOptions > ( )
129
+
127
130
function viteLegacyPlugin ( options : Options = { } ) : Plugin [ ] {
128
131
let config : ResolvedConfig
129
132
let targets : Options [ 'targets' ]
@@ -287,7 +290,7 @@ function viteLegacyPlugin(options: Options = {}): Plugin[] {
287
290
)
288
291
}
289
292
290
- if ( ! isLegacyBundle ( bundle , opts ) ) {
293
+ if ( ! isLegacyBundle ( bundle ) ) {
291
294
// Merge discovered modern polyfills to `modernPolyfills`
292
295
for ( const { modern } of chunkFileNameToPolyfills . values ( ) ) {
293
296
modern . forEach ( ( p ) => modernPolyfills . add ( p ) )
@@ -302,6 +305,7 @@ function viteLegacyPlugin(options: Options = {}): Plugin[] {
302
305
)
303
306
}
304
307
await buildPolyfillChunk (
308
+ this ,
305
309
config . mode ,
306
310
modernPolyfills ,
307
311
bundle ,
@@ -345,6 +349,7 @@ function viteLegacyPlugin(options: Options = {}): Plugin[] {
345
349
}
346
350
347
351
await buildPolyfillChunk (
352
+ this ,
348
353
config . mode ,
349
354
legacyPolyfills ,
350
355
bundle ,
@@ -432,7 +437,7 @@ function viteLegacyPlugin(options: Options = {}): Plugin[] {
432
437
) : Rollup . OutputOptions => {
433
438
return {
434
439
...options ,
435
- format : 'system ' ,
440
+ format : 'esm ' ,
436
441
entryFileNames : getLegacyOutputFileName ( options . entryFileNames ) ,
437
442
chunkFileNames : getLegacyOutputFileName ( options . chunkFileNames ) ,
438
443
}
@@ -451,6 +456,11 @@ function viteLegacyPlugin(options: Options = {}): Plugin[] {
451
456
...( genModern ? [ output || { } ] : [ ] ) ,
452
457
]
453
458
}
459
+
460
+ // @ts -expect-error is readonly but should be injected here
461
+ _config . isOutputOptionsForLegacyChunks = (
462
+ opts : Rollup . NormalizedOutputOptions ,
463
+ ) : boolean => outputOptionsForLegacyChunks . has ( opts )
454
464
} ,
455
465
456
466
async renderChunk ( raw , chunk , opts , { chunks } ) {
@@ -477,7 +487,7 @@ function viteLegacyPlugin(options: Options = {}): Plugin[] {
477
487
)
478
488
}
479
489
480
- if ( ! isLegacyChunk ( chunk , opts ) ) {
490
+ if ( ! isLegacyChunk ( chunk ) ) {
481
491
if (
482
492
options . modernPolyfills &&
483
493
! Array . isArray ( options . modernPolyfills ) &&
@@ -526,20 +536,7 @@ function viteLegacyPlugin(options: Options = {}): Plugin[] {
526
536
return null
527
537
}
528
538
529
- // @ts -expect-error avoid esbuild transform on legacy chunks since it produces
530
- // legacy-unsafe code - e.g. rewriting object properties into shorthands
531
- opts . __vite_skip_esbuild__ = true
532
-
533
- // @ts -expect-error force terser for legacy chunks. This only takes effect if
534
- // minification isn't disabled, because that leaves out the terser plugin
535
- // entirely.
536
- opts . __vite_force_terser__ = true
537
-
538
- // @ts -expect-error In the `generateBundle` hook,
539
- // we'll delete the assets from the legacy bundle to avoid emitting duplicate assets.
540
- // But that's still a waste of computing resource.
541
- // So we add this flag to avoid emitting the asset in the first place whenever possible.
542
- opts . __vite_skip_asset_emit__ = true
539
+ outputOptionsForLegacyChunks . add ( opts )
543
540
544
541
// avoid emitting assets for legacy bundle
545
542
const needPolyfills =
@@ -548,7 +545,23 @@ function viteLegacyPlugin(options: Options = {}): Plugin[] {
548
545
// transform the legacy chunk with @babel /preset-env
549
546
const sourceMaps = ! ! config . build . sourcemap
550
547
const babel = await loadBabel ( )
551
- const result = babel . transform ( raw , {
548
+
549
+ // need to transform into systemjs separately from other plugins
550
+ // for preset-env polyfill detection and removal
551
+ const resultSystem = babel . transform ( raw , {
552
+ babelrc : false ,
553
+ configFile : false ,
554
+ ast : true ,
555
+ sourceMaps,
556
+ plugins : [
557
+ // @ts -expect-error -- not typed
558
+ ( await import ( '@babel/plugin-transform-dynamic-import' ) ) . default ,
559
+ // @ts -expect-error -- not typed
560
+ ( await import ( '@babel/plugin-transform-modules-systemjs' ) ) . default ,
561
+ ] ,
562
+ } )
563
+
564
+ const babelTransformOptions : babel . TransformOptions = {
552
565
babelrc : false ,
553
566
configFile : false ,
554
567
compact : ! ! config . build . minify ,
@@ -572,8 +585,17 @@ function viteLegacyPlugin(options: Options = {}): Plugin[] {
572
585
createBabelPresetEnvOptions ( targets , { needPolyfills } ) ,
573
586
] ,
574
587
] ,
575
- } )
576
-
588
+ }
589
+ let result : babel . BabelFileResult | null
590
+ if ( resultSystem ) {
591
+ result = babel . transformFromAstSync (
592
+ resultSystem . ast ! ,
593
+ resultSystem . code ?? undefined ,
594
+ babelTransformOptions ,
595
+ )
596
+ } else {
597
+ result = babel . transform ( raw , babelTransformOptions )
598
+ }
577
599
if ( result ) return { code : result . code ! , map : result . map }
578
600
return null
579
601
} ,
@@ -713,15 +735,19 @@ function viteLegacyPlugin(options: Options = {}): Plugin[] {
713
735
}
714
736
} ,
715
737
716
- generateBundle ( opts , bundle ) {
738
+ generateBundle ( _opts , bundle ) {
717
739
if ( config . build . ssr ) {
718
740
return
719
741
}
720
742
721
- if ( isLegacyBundle ( bundle , opts ) && genModern ) {
743
+ if ( isLegacyBundle ( bundle ) && genModern ) {
722
744
// avoid emitting duplicate assets
723
745
for ( const name in bundle ) {
724
- if ( bundle [ name ] . type === 'asset' && ! / .+ \. m a p $ / . test ( name ) ) {
746
+ if (
747
+ bundle [ name ] . type === 'asset' &&
748
+ ! / .+ \. m a p $ / . test ( name ) &&
749
+ ! name . includes ( '-legacy' ) // legacy chunks
750
+ ) {
725
751
delete bundle [ name ]
726
752
}
727
753
}
@@ -787,6 +813,7 @@ function createBabelPresetEnvOptions(
787
813
}
788
814
789
815
async function buildPolyfillChunk (
816
+ ctx : Rollup . PluginContext ,
790
817
mode : string ,
791
818
imports : Set < string > ,
792
819
bundle : Rollup . OutputBundle ,
@@ -822,7 +849,7 @@ async function buildPolyfillChunk(
822
849
format,
823
850
hashCharacters : rollupOutputOptions . hashCharacters ,
824
851
entryFileNames : rollupOutputOptions . entryFileNames ,
825
- sourcemapBaseUrl : rollupOutputOptions . sourcemapBaseUrl ,
852
+ // sourcemapBaseUrl: rollupOutputOptions.sourcemapBaseUrl,
826
853
} ,
827
854
} ,
828
855
} ,
@@ -855,15 +882,23 @@ async function buildPolyfillChunk(
855
882
}
856
883
857
884
// add the chunk to the bundle
858
- bundle [ polyfillChunk . fileName ] = polyfillChunk
885
+ ctx . emitFile ( {
886
+ type : 'asset' ,
887
+ fileName : polyfillChunk . fileName ,
888
+ source : polyfillChunk . code ,
889
+ } )
859
890
if ( polyfillChunk . sourcemapFileName ) {
860
891
const polyfillChunkMapAsset = _polyfillChunk . output . find (
861
892
( chunk ) =>
862
893
chunk . type === 'asset' &&
863
894
chunk . fileName === polyfillChunk . sourcemapFileName ,
864
895
) as Rollup . OutputAsset | undefined
865
896
if ( polyfillChunkMapAsset ) {
866
- bundle [ polyfillChunk . sourcemapFileName ] = polyfillChunkMapAsset
897
+ ctx . emitFile ( {
898
+ type : 'asset' ,
899
+ fileName : polyfillChunkMapAsset . fileName ,
900
+ source : polyfillChunkMapAsset . source ,
901
+ } )
867
902
}
868
903
}
869
904
}
@@ -914,26 +949,16 @@ function prependModenChunkLegacyGuardPlugin(): Plugin {
914
949
}
915
950
}
916
951
917
- function isLegacyChunk (
918
- chunk : Rollup . RenderedChunk ,
919
- options : Rollup . NormalizedOutputOptions ,
920
- ) {
921
- return options . format === 'system' && chunk . fileName . includes ( '-legacy' )
952
+ function isLegacyChunk ( chunk : Rollup . RenderedChunk ) {
953
+ return chunk . fileName . includes ( '-legacy' )
922
954
}
923
955
924
- function isLegacyBundle (
925
- bundle : Rollup . OutputBundle ,
926
- options : Rollup . NormalizedOutputOptions ,
927
- ) {
928
- if ( options . format === 'system' ) {
929
- const entryChunk = Object . values ( bundle ) . find (
930
- ( output ) => output . type === 'chunk' && output . isEntry ,
931
- )
932
-
933
- return ! ! entryChunk && entryChunk . fileName . includes ( '-legacy' )
934
- }
956
+ function isLegacyBundle ( bundle : Rollup . OutputBundle ) {
957
+ const entryChunk = Object . values ( bundle ) . find (
958
+ ( output ) => output . type === 'chunk' && output . isEntry ,
959
+ )
935
960
936
- return false
961
+ return ! ! entryChunk && entryChunk . fileName . includes ( '-legacy' )
937
962
}
938
963
939
964
function recordAndRemovePolyfillBabelPlugin (
0 commit comments