Skip to content

Commit 9650262

Browse files
committed
wip: support plugin-legacy
1 parent 5a3ed8b commit 9650262

File tree

4 files changed

+57
-19
lines changed

4 files changed

+57
-19
lines changed

packages/plugin-legacy/package.json

+2
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@
4242
"funding": "https://github.com/vitejs/vite?sponsor=1",
4343
"dependencies": {
4444
"@babel/core": "^7.26.0",
45+
"@babel/plugin-transform-dynamic-import": "^7.25.9",
46+
"@babel/plugin-transform-modules-systemjs": "^7.25.9",
4547
"@babel/preset-env": "^7.26.0",
4648
"browserslist": "^4.24.3",
4749
"browserslist-to-esbuild": "^2.1.1",

packages/plugin-legacy/src/index.ts

+48-19
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import type {
1717
OutputBundle,
1818
OutputChunk,
1919
OutputOptions,
20+
PluginContext,
2021
PreRenderedChunk,
2122
RenderedChunk,
2223
} from 'rollup'
@@ -174,6 +175,7 @@ function viteLegacyPlugin(options: Options = {}): Plugin[] {
174175
const legacyPolyfills = new Set<string>()
175176
// When discovering polyfills in `renderChunk`, the hook may be non-deterministic, so we group the
176177
// modern and legacy polyfills in a sorted chunks map for each rendered outputs before merging them.
178+
// TODO: options object is not identical, so Map won't work
177179
const outputToChunkFileNameToPolyfills = new WeakMap<
178180
NormalizedOutputOptions,
179181
Map<string, { modern: Set<string>; legacy: Set<string> }> | null
@@ -282,13 +284,14 @@ function viteLegacyPlugin(options: Options = {}): Plugin[] {
282284
return
283285
}
284286

285-
const chunkFileNameToPolyfills =
286-
outputToChunkFileNameToPolyfills.get(opts)
287-
if (chunkFileNameToPolyfills == null) {
288-
throw new Error(
289-
'Internal @vitejs/plugin-legacy error: discovered polyfills should exist',
290-
)
291-
}
287+
// const chunkFileNameToPolyfills =
288+
// outputToChunkFileNameToPolyfills.get(opts)
289+
// if (chunkFileNameToPolyfills == null) {
290+
// throw new Error(
291+
// 'Internal @vitejs/plugin-legacy error: discovered polyfills should exist',
292+
// )
293+
// }
294+
const chunkFileNameToPolyfills = new Map()
292295

293296
if (!isLegacyBundle(bundle, opts)) {
294297
// Merge discovered modern polyfills to `modernPolyfills`
@@ -305,6 +308,7 @@ function viteLegacyPlugin(options: Options = {}): Plugin[] {
305308
)
306309
}
307310
await buildPolyfillChunk(
311+
this,
308312
config.mode,
309313
modernPolyfills,
310314
bundle,
@@ -347,6 +351,7 @@ function viteLegacyPlugin(options: Options = {}): Plugin[] {
347351
}
348352

349353
await buildPolyfillChunk(
354+
this,
350355
config.mode,
351356
legacyPolyfills,
352357
bundle,
@@ -434,7 +439,9 @@ function viteLegacyPlugin(options: Options = {}): Plugin[] {
434439
): OutputOptions => {
435440
return {
436441
...options,
437-
format: 'system',
442+
// TODO
443+
format: 'esm',
444+
// format: 'system',
438445
entryFileNames: getLegacyOutputFileName(options.entryFileNames),
439446
chunkFileNames: getLegacyOutputFileName(options.chunkFileNames),
440447
}
@@ -455,7 +462,8 @@ function viteLegacyPlugin(options: Options = {}): Plugin[] {
455462
}
456463
},
457464

458-
async renderChunk(raw, chunk, opts, { chunks }) {
465+
// TODO: meta.chunks not supported
466+
async renderChunk(raw, chunk, opts, { chunks } = { chunks: {} }) {
459467
if (config.build.ssr) {
460468
return null
461469
}
@@ -472,11 +480,15 @@ function viteLegacyPlugin(options: Options = {}): Plugin[] {
472480
}
473481
outputToChunkFileNameToPolyfills.set(opts, chunkFileNameToPolyfills)
474482
}
475-
const polyfillsDiscovered = chunkFileNameToPolyfills.get(chunk.fileName)
476-
if (polyfillsDiscovered == null) {
477-
throw new Error(
478-
`Internal @vitejs/plugin-legacy error: discovered polyfills for ${chunk.fileName} should exist`,
479-
)
483+
// const polyfillsDiscovered = chunkFileNameToPolyfills.get(chunk.fileName)
484+
// if (polyfillsDiscovered == null) {
485+
// throw new Error(
486+
// `Internal @vitejs/plugin-legacy error: discovered polyfills for ${chunk.fileName} should exist`,
487+
// )
488+
// }
489+
const polyfillsDiscovered = {
490+
modern: new Set(),
491+
legacy: new Set(),
480492
}
481493

482494
if (!isLegacyChunk(chunk, opts)) {
@@ -545,6 +557,12 @@ function viteLegacyPlugin(options: Options = {}): Plugin[] {
545557
// transform the legacy chunk with @babel/preset-env
546558
const sourceMaps = !!config.build.sourcemap
547559
const babel = await loadBabel()
560+
const systemJsPlugins = [
561+
// @ts-ignore
562+
(await import('@babel/plugin-transform-dynamic-import')).default,
563+
// @ts-ignore
564+
(await import('@babel/plugin-transform-modules-systemjs')).default,
565+
]
548566
const result = babel.transform(raw, {
549567
babelrc: false,
550568
configFile: false,
@@ -557,6 +575,7 @@ function viteLegacyPlugin(options: Options = {}): Plugin[] {
557575
[
558576
() => ({
559577
plugins: [
578+
...systemJsPlugins,
560579
recordAndRemovePolyfillBabelPlugin(polyfillsDiscovered.legacy),
561580
replaceLegacyEnvBabelPlugin(),
562581
wrapIIFEBabelPlugin(),
@@ -718,7 +737,8 @@ function viteLegacyPlugin(options: Options = {}): Plugin[] {
718737
// avoid emitting duplicate assets
719738
for (const name in bundle) {
720739
if (bundle[name].type === 'asset' && !/.+\.map$/.test(name)) {
721-
delete bundle[name]
740+
// TODO: don't delete polyfil chunk emitted as asset
741+
// delete bundle[name]
722742
}
723743
}
724744
}
@@ -781,6 +801,7 @@ function createBabelPresetEnvOptions(
781801
}
782802

783803
async function buildPolyfillChunk(
804+
ctx: PluginContext,
784805
mode: string,
785806
imports: Set<string>,
786807
bundle: OutputBundle,
@@ -846,16 +867,23 @@ async function buildPolyfillChunk(
846867
}
847868
}
848869

870+
// TODO: adding a whole new chunk to `bundle` is not supported by rolldown.
871+
// can we use `emitFile(asset)` instead?
872+
ctx.emitFile({
873+
type: 'asset',
874+
fileName: polyfillChunk.fileName,
875+
source: polyfillChunk.code,
876+
})
849877
// add the chunk to the bundle
850-
bundle[polyfillChunk.fileName] = polyfillChunk
878+
// bundle[polyfillChunk.fileName] = polyfillChunk
851879
if (polyfillChunk.sourcemapFileName) {
852880
const polyfillChunkMapAsset = _polyfillChunk.output.find(
853881
(chunk) =>
854882
chunk.type === 'asset' &&
855883
chunk.fileName === polyfillChunk.sourcemapFileName,
856884
) as OutputAsset | undefined
857885
if (polyfillChunkMapAsset) {
858-
bundle[polyfillChunk.sourcemapFileName] = polyfillChunkMapAsset
886+
// bundle[polyfillChunk.sourcemapFileName] = polyfillChunkMapAsset
859887
}
860888
}
861889
}
@@ -907,14 +935,15 @@ function prependModenChunkLegacyGuardPlugin(): Plugin {
907935
}
908936

909937
function isLegacyChunk(chunk: RenderedChunk, options: NormalizedOutputOptions) {
910-
return options.format === 'system' && chunk.fileName.includes('-legacy')
938+
return chunk.fileName.includes('-legacy')
939+
// return options.format === 'system' && chunk.fileName.includes('-legacy')
911940
}
912941

913942
function isLegacyBundle(
914943
bundle: OutputBundle,
915944
options: NormalizedOutputOptions,
916945
) {
917-
if (options.format === 'system') {
946+
if (true || options.format === 'system') {
918947
const entryChunk = Object.values(bundle).find(
919948
(output) => output.type === 'chunk' && output.isEntry,
920949
)

playground/legacy/vite.config.js

+1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ export default defineConfig({
1313
],
1414

1515
build: {
16+
minify: false,
1617
cssCodeSplit: false,
1718
manifest: true,
1819
sourcemap: true,

pnpm-lock.yaml

+6
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)