@vitejs/plugin-legacy 3.0.2 → 4.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +12 -6
- package/dist/index.cjs +51 -27
- package/dist/index.mjs +51 -27
- package/package.json +5 -3
package/README.md
CHANGED
|
@@ -8,7 +8,7 @@ By default, this plugin will:
|
|
|
8
8
|
|
|
9
9
|
- Generate a polyfill chunk including SystemJS runtime, and any necessary polyfills determined by specified browser targets and **actual usage** in the bundle.
|
|
10
10
|
|
|
11
|
-
- Inject `<script nomodule>` tags into generated HTML to conditionally load the polyfills and legacy bundle only in browsers without
|
|
11
|
+
- Inject `<script nomodule>` tags into generated HTML to conditionally load the polyfills and legacy bundle only in browsers without widely-available features support.
|
|
12
12
|
|
|
13
13
|
- Inject the `import.meta.env.LEGACY` env variable, which will only be `true` in the legacy production build, and `false` in all other cases.
|
|
14
14
|
|
|
@@ -38,11 +38,11 @@ npm add -D terser
|
|
|
38
38
|
### `targets`
|
|
39
39
|
|
|
40
40
|
- **Type:** `string | string[] | { [key: string]: string }`
|
|
41
|
-
- **Default:** `'
|
|
41
|
+
- **Default:** [`'last 2 versions and not dead, > 0.3%, Firefox ESR'`](https://browsersl.ist/#q=last+2+versions+and+not+dead%2C+%3E+0.3%25%2C+Firefox+ESR)
|
|
42
42
|
|
|
43
43
|
If explicitly set, it's passed on to [`@babel/preset-env`](https://babeljs.io/docs/en/babel-preset-env#targets).
|
|
44
44
|
|
|
45
|
-
The query is also [Browserslist compatible](https://github.com/browserslist/browserslist).
|
|
45
|
+
The query is also [Browserslist compatible](https://github.com/browserslist/browserslist). See [Browserslist Best Practices](https://github.com/browserslist/browserslist#best-practices) for more details.
|
|
46
46
|
|
|
47
47
|
### `polyfills`
|
|
48
48
|
|
|
@@ -117,12 +117,18 @@ npm add -D terser
|
|
|
117
117
|
|
|
118
118
|
Defaults to `false`. Enabling this option will exclude `systemjs/dist/s.min.js` inside polyfills-legacy chunk.
|
|
119
119
|
|
|
120
|
-
##
|
|
120
|
+
## Browsers that supports ESM but does not support widely-available features
|
|
121
121
|
|
|
122
|
-
The legacy plugin offers a way to use
|
|
122
|
+
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:
|
|
123
123
|
|
|
124
124
|
- Modern bundle is downloaded in all ESM browsers
|
|
125
|
-
- Modern bundle throws `SyntaxError` in browsers without
|
|
125
|
+
- Modern bundle throws `SyntaxError` in browsers without those features support
|
|
126
|
+
|
|
127
|
+
The following syntax are considered as widely-available:
|
|
128
|
+
|
|
129
|
+
- dynamic import
|
|
130
|
+
- `import.meta`
|
|
131
|
+
- async generator
|
|
126
132
|
|
|
127
133
|
## Polyfill Specifiers
|
|
128
134
|
|
package/dist/index.cjs
CHANGED
|
@@ -9,8 +9,13 @@ const node_url = require('node:url');
|
|
|
9
9
|
const vite = require('vite');
|
|
10
10
|
const MagicString = require('magic-string');
|
|
11
11
|
const require$$0 = require('tty');
|
|
12
|
+
const browserslist = require('browserslist');
|
|
12
13
|
|
|
13
|
-
var
|
|
14
|
+
var picocolorsExports = {};
|
|
15
|
+
var picocolors = {
|
|
16
|
+
get exports(){ return picocolorsExports; },
|
|
17
|
+
set exports(v){ picocolorsExports = v; },
|
|
18
|
+
};
|
|
14
19
|
|
|
15
20
|
let tty = require$$0;
|
|
16
21
|
|
|
@@ -69,15 +74,26 @@ let createColors = (enabled = isColorSupported) => ({
|
|
|
69
74
|
});
|
|
70
75
|
|
|
71
76
|
picocolors.exports = createColors();
|
|
72
|
-
|
|
77
|
+
picocolorsExports.createColors = createColors;
|
|
78
|
+
|
|
79
|
+
const safari10NoModuleFix = `!function(){var e=document,t=e.createElement("script");if(!("noModule"in t)&&"onbeforeload"in t){var n=!1;e.addEventListener("beforeload",(function(e){if(e.target===t)n=!0;else if(!e.target.hasAttribute("nomodule")||!n)return;e.preventDefault()}),!0),t.type="module",t.src=".",e.head.appendChild(t),t.remove()}}();`;
|
|
80
|
+
const legacyPolyfillId = "vite-legacy-polyfill";
|
|
81
|
+
const legacyEntryId = "vite-legacy-entry";
|
|
82
|
+
const systemJSInlineCode = `System.import(document.getElementById('${legacyEntryId}').getAttribute('data-src'))`;
|
|
83
|
+
const detectModernBrowserVarName = "__vite_is_modern_browser";
|
|
84
|
+
const detectModernBrowserDetector = 'import.meta.url;import("_").catch(()=>1);async function* g(){};';
|
|
85
|
+
const detectModernBrowserCode = `${detectModernBrowserDetector}window.${detectModernBrowserVarName}=true;`;
|
|
86
|
+
const dynamicFallbackInlineCode = `!function(){if(window.${detectModernBrowserVarName})return;console.warn("vite: loading legacy chunks, syntax error above and the same error below should be ignored");var e=document.getElementById("${legacyPolyfillId}"),n=document.createElement("script");n.src=e.src,n.onload=function(){${systemJSInlineCode}},document.body.appendChild(n)}();`;
|
|
87
|
+
const modernChunkLegacyGuard = `export function __vite_legacy_guard(){${detectModernBrowserDetector}};`;
|
|
73
88
|
|
|
74
89
|
let babel;
|
|
75
90
|
async function loadBabel() {
|
|
76
91
|
if (!babel) {
|
|
77
|
-
babel = await import('@babel/
|
|
92
|
+
babel = await import('@babel/core');
|
|
78
93
|
}
|
|
79
94
|
return babel;
|
|
80
95
|
}
|
|
96
|
+
const { loadConfig: browserslistLoadConfig } = browserslist;
|
|
81
97
|
function toOutputFilePathInHtml(filename, type, hostId, hostType, config, toRelative) {
|
|
82
98
|
const { renderBuiltUrl } = config.experimental;
|
|
83
99
|
let relative = config.base === "" || config.base === "./";
|
|
@@ -125,21 +141,12 @@ function toAssetPathFromHtml(filename, htmlPath, config) {
|
|
|
125
141
|
toRelative
|
|
126
142
|
);
|
|
127
143
|
}
|
|
128
|
-
const safari10NoModuleFix = `!function(){var e=document,t=e.createElement("script");if(!("noModule"in t)&&"onbeforeload"in t){var n=!1;e.addEventListener("beforeload",(function(e){if(e.target===t)n=!0;else if(!e.target.hasAttribute("nomodule")||!n)return;e.preventDefault()}),!0),t.type="module",t.src=".",e.head.appendChild(t),t.remove()}}();`;
|
|
129
|
-
const legacyPolyfillId = "vite-legacy-polyfill";
|
|
130
|
-
const legacyEntryId = "vite-legacy-entry";
|
|
131
|
-
const systemJSInlineCode = `System.import(document.getElementById('${legacyEntryId}').getAttribute('data-src'))`;
|
|
132
|
-
const detectModernBrowserVarName = "__vite_is_modern_browser";
|
|
133
|
-
const detectModernBrowserCode = `try{import.meta.url;import("_").catch(()=>1);}catch(e){}window.${detectModernBrowserVarName}=true;`;
|
|
134
|
-
const dynamicFallbackInlineCode = `!function(){if(window.${detectModernBrowserVarName})return;console.warn("vite: loading legacy build because dynamic import or import.meta.url is unsupported, syntax error above should be ignored");var e=document.getElementById("${legacyPolyfillId}"),n=document.createElement("script");n.src=e.src,n.onload=function(){${systemJSInlineCode}},document.body.appendChild(n)}();`;
|
|
135
|
-
const forceDynamicImportUsage = `export function __vite_legacy_guard(){import('data:text/javascript,')};`;
|
|
136
144
|
const legacyEnvVarMarker = `__VITE_IS_LEGACY__`;
|
|
137
145
|
const _require = node_module.createRequire((typeof document === 'undefined' ? new (require('u' + 'rl').URL)('file:' + __filename).href : (document.currentScript && document.currentScript.src || new URL('index.cjs', document.baseURI).href)));
|
|
138
146
|
function viteLegacyPlugin(options = {}) {
|
|
139
147
|
let config;
|
|
140
|
-
|
|
148
|
+
let targets;
|
|
141
149
|
const genLegacy = options.renderLegacyChunks !== false;
|
|
142
|
-
const genDynamicFallback = genLegacy;
|
|
143
150
|
const debugFlags = (process.env.DEBUG || "").split(",");
|
|
144
151
|
const isDebug = debugFlags.includes("vite:*") || debugFlags.includes("vite:legacy");
|
|
145
152
|
const facadeToLegacyChunkMap = /* @__PURE__ */ new Map();
|
|
@@ -188,7 +195,7 @@ function viteLegacyPlugin(options = {}) {
|
|
|
188
195
|
"edge79",
|
|
189
196
|
"firefox67",
|
|
190
197
|
"chrome64",
|
|
191
|
-
"
|
|
198
|
+
"safari12"
|
|
192
199
|
];
|
|
193
200
|
}
|
|
194
201
|
}
|
|
@@ -201,7 +208,7 @@ function viteLegacyPlugin(options = {}) {
|
|
|
201
208
|
configResolved(config2) {
|
|
202
209
|
if (overriddenBuildTarget) {
|
|
203
210
|
config2.logger.warn(
|
|
204
|
-
|
|
211
|
+
picocolorsExports.yellow(
|
|
205
212
|
`plugin-legacy overrode 'build.target'. You should pass 'targets' as an option to this plugin with the list of legacy browsers to support instead.`
|
|
206
213
|
)
|
|
207
214
|
);
|
|
@@ -238,7 +245,7 @@ function viteLegacyPlugin(options = {}) {
|
|
|
238
245
|
if (!genLegacy) {
|
|
239
246
|
return;
|
|
240
247
|
}
|
|
241
|
-
if (legacyPolyfills.size
|
|
248
|
+
if (legacyPolyfills.size) {
|
|
242
249
|
await detectPolyfills(
|
|
243
250
|
`Promise.resolve(); Promise.all();`,
|
|
244
251
|
targets,
|
|
@@ -253,6 +260,8 @@ function viteLegacyPlugin(options = {}) {
|
|
|
253
260
|
legacyPolyfills,
|
|
254
261
|
bundle,
|
|
255
262
|
facadeToLegacyPolyfillMap,
|
|
263
|
+
// force using terser for legacy polyfill minification, since esbuild
|
|
264
|
+
// isn't legacy-safe
|
|
256
265
|
config.build,
|
|
257
266
|
"iife",
|
|
258
267
|
opts,
|
|
@@ -273,6 +282,8 @@ function viteLegacyPlugin(options = {}) {
|
|
|
273
282
|
if (!genLegacy || config.build.ssr) {
|
|
274
283
|
return;
|
|
275
284
|
}
|
|
285
|
+
targets = options.targets || browserslistLoadConfig({ path: config.root }) || "last 2 versions and not dead, > 0.3%, Firefox ESR";
|
|
286
|
+
isDebug && console.log(`[@vitejs/plugin-legacy] targets:`, targets);
|
|
276
287
|
const getLegacyOutputFileName = (fileNames, defaultFileName = "[name]-legacy-[hash].js") => {
|
|
277
288
|
if (!fileNames) {
|
|
278
289
|
return path.posix.join(config.build.assetsDir, defaultFileName);
|
|
@@ -312,8 +323,8 @@ function viteLegacyPlugin(options = {}) {
|
|
|
312
323
|
await detectPolyfills(raw, { esmodules: true }, modernPolyfills);
|
|
313
324
|
}
|
|
314
325
|
const ms = new MagicString(raw);
|
|
315
|
-
if (
|
|
316
|
-
ms.prepend(
|
|
326
|
+
if (genLegacy && chunk.isEntry) {
|
|
327
|
+
ms.prepend(modernChunkLegacyGuard);
|
|
317
328
|
}
|
|
318
329
|
if (raw.includes(legacyEnvVarMarker)) {
|
|
319
330
|
const re = new RegExp(legacyEnvVarMarker, "g");
|
|
@@ -345,13 +356,16 @@ function viteLegacyPlugin(options = {}) {
|
|
|
345
356
|
const needPolyfills = options.polyfills !== false && !Array.isArray(options.polyfills);
|
|
346
357
|
const sourceMaps = !!config.build.sourcemap;
|
|
347
358
|
const babel2 = await loadBabel();
|
|
348
|
-
const
|
|
359
|
+
const result = babel2.transform(raw, {
|
|
349
360
|
babelrc: false,
|
|
350
361
|
configFile: false,
|
|
351
362
|
compact: !!config.build.minify,
|
|
352
363
|
sourceMaps,
|
|
353
364
|
inputSourceMap: void 0,
|
|
365
|
+
// sourceMaps ? chunk.map : undefined, `.map` TODO: moved to OutputChunk?
|
|
354
366
|
presets: [
|
|
367
|
+
// forcing our plugin to run before preset-env by wrapping it in a
|
|
368
|
+
// preset so we can catch the injected import statements...
|
|
355
369
|
[
|
|
356
370
|
() => ({
|
|
357
371
|
plugins: [
|
|
@@ -362,7 +376,7 @@ function viteLegacyPlugin(options = {}) {
|
|
|
362
376
|
})
|
|
363
377
|
],
|
|
364
378
|
[
|
|
365
|
-
"env",
|
|
379
|
+
"@babel/preset-env",
|
|
366
380
|
createBabelPresetEnvOptions(targets, {
|
|
367
381
|
needPolyfills,
|
|
368
382
|
ignoreBrowserslistConfig: options.ignoreBrowserslistConfig
|
|
@@ -370,8 +384,8 @@ function viteLegacyPlugin(options = {}) {
|
|
|
370
384
|
]
|
|
371
385
|
]
|
|
372
386
|
});
|
|
373
|
-
if (
|
|
374
|
-
return { code, map };
|
|
387
|
+
if (result)
|
|
388
|
+
return { code: result.code, map: result.map };
|
|
375
389
|
return null;
|
|
376
390
|
},
|
|
377
391
|
transformIndexHtml(html, { chunk }) {
|
|
@@ -447,6 +461,9 @@ function viteLegacyPlugin(options = {}) {
|
|
|
447
461
|
attrs: {
|
|
448
462
|
nomodule: true,
|
|
449
463
|
crossorigin: true,
|
|
464
|
+
// we set the entry path on the element as an attribute so that the
|
|
465
|
+
// script content will stay consistent - which allows using a constant
|
|
466
|
+
// hash value for CSP.
|
|
450
467
|
id: legacyEntryId,
|
|
451
468
|
"data-src": toAssetPathFromHtml(
|
|
452
469
|
legacyEntryFilename,
|
|
@@ -462,7 +479,7 @@ function viteLegacyPlugin(options = {}) {
|
|
|
462
479
|
`No corresponding legacy entry chunk found for ${htmlFilename}`
|
|
463
480
|
);
|
|
464
481
|
}
|
|
465
|
-
if (
|
|
482
|
+
if (genLegacy && legacyPolyfillFilename && legacyEntryFilename) {
|
|
466
483
|
tags.push({
|
|
467
484
|
tag: "script",
|
|
468
485
|
attrs: { type: "module" },
|
|
@@ -487,7 +504,7 @@ function viteLegacyPlugin(options = {}) {
|
|
|
487
504
|
}
|
|
488
505
|
if (isLegacyBundle(bundle, opts)) {
|
|
489
506
|
for (const name in bundle) {
|
|
490
|
-
if (bundle[name].type === "asset") {
|
|
507
|
+
if (bundle[name].type === "asset" && !/.+\.map$/.test(name)) {
|
|
491
508
|
delete bundle[name];
|
|
492
509
|
}
|
|
493
510
|
}
|
|
@@ -498,20 +515,20 @@ function viteLegacyPlugin(options = {}) {
|
|
|
498
515
|
}
|
|
499
516
|
async function detectPolyfills(code, targets, list) {
|
|
500
517
|
const babel2 = await loadBabel();
|
|
501
|
-
const
|
|
518
|
+
const result = babel2.transform(code, {
|
|
502
519
|
ast: true,
|
|
503
520
|
babelrc: false,
|
|
504
521
|
configFile: false,
|
|
505
522
|
presets: [
|
|
506
523
|
[
|
|
507
|
-
"env",
|
|
524
|
+
"@babel/preset-env",
|
|
508
525
|
createBabelPresetEnvOptions(targets, {
|
|
509
526
|
ignoreBrowserslistConfig: true
|
|
510
527
|
})
|
|
511
528
|
]
|
|
512
529
|
]
|
|
513
530
|
});
|
|
514
|
-
for (const node of ast.program.body) {
|
|
531
|
+
for (const node of result.ast.program.body) {
|
|
515
532
|
if (node.type === "ImportDeclaration") {
|
|
516
533
|
const source = node.source.value;
|
|
517
534
|
if (source.startsWith("core-js/") || source.startsWith("regenerator-runtime/")) {
|
|
@@ -543,6 +560,7 @@ async function buildPolyfillChunk(mode, imports, bundle, facadeToChunkMap, build
|
|
|
543
560
|
minify = minify ? "terser" : false;
|
|
544
561
|
const res = await vite.build({
|
|
545
562
|
mode,
|
|
563
|
+
// so that everything is resolved from here
|
|
546
564
|
root: path.dirname(node_url.fileURLToPath((typeof document === 'undefined' ? new (require('u' + 'rl').URL)('file:' + __filename).href : (document.currentScript && document.currentScript.src || new URL('index.cjs', document.baseURI).href)))),
|
|
547
565
|
configFile: false,
|
|
548
566
|
logLevel: "error",
|
|
@@ -561,9 +579,15 @@ async function buildPolyfillChunk(mode, imports, bundle, facadeToChunkMap, build
|
|
|
561
579
|
}
|
|
562
580
|
}
|
|
563
581
|
},
|
|
582
|
+
// Don't run esbuild for transpilation or minification
|
|
583
|
+
// because we don't want to transpile code.
|
|
564
584
|
esbuild: false,
|
|
565
585
|
optimizeDeps: {
|
|
566
586
|
esbuildOptions: {
|
|
587
|
+
// If a value above 'es5' is set, esbuild injects helper functions which uses es2015 features.
|
|
588
|
+
// This limits the input code not to include es2015+ codes.
|
|
589
|
+
// But core-js is the only dependency which includes commonjs code
|
|
590
|
+
// and core-js doesn't include es2015+ codes.
|
|
567
591
|
target: "es5"
|
|
568
592
|
}
|
|
569
593
|
}
|
package/dist/index.mjs
CHANGED
|
@@ -5,8 +5,13 @@ import { fileURLToPath } from 'node:url';
|
|
|
5
5
|
import { build, normalizePath } from 'vite';
|
|
6
6
|
import MagicString from 'magic-string';
|
|
7
7
|
import require$$0 from 'tty';
|
|
8
|
+
import browserslist from 'browserslist';
|
|
8
9
|
|
|
9
|
-
var
|
|
10
|
+
var picocolorsExports = {};
|
|
11
|
+
var picocolors = {
|
|
12
|
+
get exports(){ return picocolorsExports; },
|
|
13
|
+
set exports(v){ picocolorsExports = v; },
|
|
14
|
+
};
|
|
10
15
|
|
|
11
16
|
let tty = require$$0;
|
|
12
17
|
|
|
@@ -65,15 +70,26 @@ let createColors = (enabled = isColorSupported) => ({
|
|
|
65
70
|
});
|
|
66
71
|
|
|
67
72
|
picocolors.exports = createColors();
|
|
68
|
-
|
|
73
|
+
picocolorsExports.createColors = createColors;
|
|
74
|
+
|
|
75
|
+
const safari10NoModuleFix = `!function(){var e=document,t=e.createElement("script");if(!("noModule"in t)&&"onbeforeload"in t){var n=!1;e.addEventListener("beforeload",(function(e){if(e.target===t)n=!0;else if(!e.target.hasAttribute("nomodule")||!n)return;e.preventDefault()}),!0),t.type="module",t.src=".",e.head.appendChild(t),t.remove()}}();`;
|
|
76
|
+
const legacyPolyfillId = "vite-legacy-polyfill";
|
|
77
|
+
const legacyEntryId = "vite-legacy-entry";
|
|
78
|
+
const systemJSInlineCode = `System.import(document.getElementById('${legacyEntryId}').getAttribute('data-src'))`;
|
|
79
|
+
const detectModernBrowserVarName = "__vite_is_modern_browser";
|
|
80
|
+
const detectModernBrowserDetector = 'import.meta.url;import("_").catch(()=>1);async function* g(){};';
|
|
81
|
+
const detectModernBrowserCode = `${detectModernBrowserDetector}window.${detectModernBrowserVarName}=true;`;
|
|
82
|
+
const dynamicFallbackInlineCode = `!function(){if(window.${detectModernBrowserVarName})return;console.warn("vite: loading legacy chunks, syntax error above and the same error below should be ignored");var e=document.getElementById("${legacyPolyfillId}"),n=document.createElement("script");n.src=e.src,n.onload=function(){${systemJSInlineCode}},document.body.appendChild(n)}();`;
|
|
83
|
+
const modernChunkLegacyGuard = `export function __vite_legacy_guard(){${detectModernBrowserDetector}};`;
|
|
69
84
|
|
|
70
85
|
let babel;
|
|
71
86
|
async function loadBabel() {
|
|
72
87
|
if (!babel) {
|
|
73
|
-
babel = await import('@babel/
|
|
88
|
+
babel = await import('@babel/core');
|
|
74
89
|
}
|
|
75
90
|
return babel;
|
|
76
91
|
}
|
|
92
|
+
const { loadConfig: browserslistLoadConfig } = browserslist;
|
|
77
93
|
function toOutputFilePathInHtml(filename, type, hostId, hostType, config, toRelative) {
|
|
78
94
|
const { renderBuiltUrl } = config.experimental;
|
|
79
95
|
let relative = config.base === "" || config.base === "./";
|
|
@@ -121,21 +137,12 @@ function toAssetPathFromHtml(filename, htmlPath, config) {
|
|
|
121
137
|
toRelative
|
|
122
138
|
);
|
|
123
139
|
}
|
|
124
|
-
const safari10NoModuleFix = `!function(){var e=document,t=e.createElement("script");if(!("noModule"in t)&&"onbeforeload"in t){var n=!1;e.addEventListener("beforeload",(function(e){if(e.target===t)n=!0;else if(!e.target.hasAttribute("nomodule")||!n)return;e.preventDefault()}),!0),t.type="module",t.src=".",e.head.appendChild(t),t.remove()}}();`;
|
|
125
|
-
const legacyPolyfillId = "vite-legacy-polyfill";
|
|
126
|
-
const legacyEntryId = "vite-legacy-entry";
|
|
127
|
-
const systemJSInlineCode = `System.import(document.getElementById('${legacyEntryId}').getAttribute('data-src'))`;
|
|
128
|
-
const detectModernBrowserVarName = "__vite_is_modern_browser";
|
|
129
|
-
const detectModernBrowserCode = `try{import.meta.url;import("_").catch(()=>1);}catch(e){}window.${detectModernBrowserVarName}=true;`;
|
|
130
|
-
const dynamicFallbackInlineCode = `!function(){if(window.${detectModernBrowserVarName})return;console.warn("vite: loading legacy build because dynamic import or import.meta.url is unsupported, syntax error above should be ignored");var e=document.getElementById("${legacyPolyfillId}"),n=document.createElement("script");n.src=e.src,n.onload=function(){${systemJSInlineCode}},document.body.appendChild(n)}();`;
|
|
131
|
-
const forceDynamicImportUsage = `export function __vite_legacy_guard(){import('data:text/javascript,')};`;
|
|
132
140
|
const legacyEnvVarMarker = `__VITE_IS_LEGACY__`;
|
|
133
141
|
const _require = createRequire(import.meta.url);
|
|
134
142
|
function viteLegacyPlugin(options = {}) {
|
|
135
143
|
let config;
|
|
136
|
-
|
|
144
|
+
let targets;
|
|
137
145
|
const genLegacy = options.renderLegacyChunks !== false;
|
|
138
|
-
const genDynamicFallback = genLegacy;
|
|
139
146
|
const debugFlags = (process.env.DEBUG || "").split(",");
|
|
140
147
|
const isDebug = debugFlags.includes("vite:*") || debugFlags.includes("vite:legacy");
|
|
141
148
|
const facadeToLegacyChunkMap = /* @__PURE__ */ new Map();
|
|
@@ -184,7 +191,7 @@ function viteLegacyPlugin(options = {}) {
|
|
|
184
191
|
"edge79",
|
|
185
192
|
"firefox67",
|
|
186
193
|
"chrome64",
|
|
187
|
-
"
|
|
194
|
+
"safari12"
|
|
188
195
|
];
|
|
189
196
|
}
|
|
190
197
|
}
|
|
@@ -197,7 +204,7 @@ function viteLegacyPlugin(options = {}) {
|
|
|
197
204
|
configResolved(config2) {
|
|
198
205
|
if (overriddenBuildTarget) {
|
|
199
206
|
config2.logger.warn(
|
|
200
|
-
|
|
207
|
+
picocolorsExports.yellow(
|
|
201
208
|
`plugin-legacy overrode 'build.target'. You should pass 'targets' as an option to this plugin with the list of legacy browsers to support instead.`
|
|
202
209
|
)
|
|
203
210
|
);
|
|
@@ -234,7 +241,7 @@ function viteLegacyPlugin(options = {}) {
|
|
|
234
241
|
if (!genLegacy) {
|
|
235
242
|
return;
|
|
236
243
|
}
|
|
237
|
-
if (legacyPolyfills.size
|
|
244
|
+
if (legacyPolyfills.size) {
|
|
238
245
|
await detectPolyfills(
|
|
239
246
|
`Promise.resolve(); Promise.all();`,
|
|
240
247
|
targets,
|
|
@@ -249,6 +256,8 @@ function viteLegacyPlugin(options = {}) {
|
|
|
249
256
|
legacyPolyfills,
|
|
250
257
|
bundle,
|
|
251
258
|
facadeToLegacyPolyfillMap,
|
|
259
|
+
// force using terser for legacy polyfill minification, since esbuild
|
|
260
|
+
// isn't legacy-safe
|
|
252
261
|
config.build,
|
|
253
262
|
"iife",
|
|
254
263
|
opts,
|
|
@@ -269,6 +278,8 @@ function viteLegacyPlugin(options = {}) {
|
|
|
269
278
|
if (!genLegacy || config.build.ssr) {
|
|
270
279
|
return;
|
|
271
280
|
}
|
|
281
|
+
targets = options.targets || browserslistLoadConfig({ path: config.root }) || "last 2 versions and not dead, > 0.3%, Firefox ESR";
|
|
282
|
+
isDebug && console.log(`[@vitejs/plugin-legacy] targets:`, targets);
|
|
272
283
|
const getLegacyOutputFileName = (fileNames, defaultFileName = "[name]-legacy-[hash].js") => {
|
|
273
284
|
if (!fileNames) {
|
|
274
285
|
return path.posix.join(config.build.assetsDir, defaultFileName);
|
|
@@ -308,8 +319,8 @@ function viteLegacyPlugin(options = {}) {
|
|
|
308
319
|
await detectPolyfills(raw, { esmodules: true }, modernPolyfills);
|
|
309
320
|
}
|
|
310
321
|
const ms = new MagicString(raw);
|
|
311
|
-
if (
|
|
312
|
-
ms.prepend(
|
|
322
|
+
if (genLegacy && chunk.isEntry) {
|
|
323
|
+
ms.prepend(modernChunkLegacyGuard);
|
|
313
324
|
}
|
|
314
325
|
if (raw.includes(legacyEnvVarMarker)) {
|
|
315
326
|
const re = new RegExp(legacyEnvVarMarker, "g");
|
|
@@ -341,13 +352,16 @@ function viteLegacyPlugin(options = {}) {
|
|
|
341
352
|
const needPolyfills = options.polyfills !== false && !Array.isArray(options.polyfills);
|
|
342
353
|
const sourceMaps = !!config.build.sourcemap;
|
|
343
354
|
const babel2 = await loadBabel();
|
|
344
|
-
const
|
|
355
|
+
const result = babel2.transform(raw, {
|
|
345
356
|
babelrc: false,
|
|
346
357
|
configFile: false,
|
|
347
358
|
compact: !!config.build.minify,
|
|
348
359
|
sourceMaps,
|
|
349
360
|
inputSourceMap: void 0,
|
|
361
|
+
// sourceMaps ? chunk.map : undefined, `.map` TODO: moved to OutputChunk?
|
|
350
362
|
presets: [
|
|
363
|
+
// forcing our plugin to run before preset-env by wrapping it in a
|
|
364
|
+
// preset so we can catch the injected import statements...
|
|
351
365
|
[
|
|
352
366
|
() => ({
|
|
353
367
|
plugins: [
|
|
@@ -358,7 +372,7 @@ function viteLegacyPlugin(options = {}) {
|
|
|
358
372
|
})
|
|
359
373
|
],
|
|
360
374
|
[
|
|
361
|
-
"env",
|
|
375
|
+
"@babel/preset-env",
|
|
362
376
|
createBabelPresetEnvOptions(targets, {
|
|
363
377
|
needPolyfills,
|
|
364
378
|
ignoreBrowserslistConfig: options.ignoreBrowserslistConfig
|
|
@@ -366,8 +380,8 @@ function viteLegacyPlugin(options = {}) {
|
|
|
366
380
|
]
|
|
367
381
|
]
|
|
368
382
|
});
|
|
369
|
-
if (
|
|
370
|
-
return { code, map };
|
|
383
|
+
if (result)
|
|
384
|
+
return { code: result.code, map: result.map };
|
|
371
385
|
return null;
|
|
372
386
|
},
|
|
373
387
|
transformIndexHtml(html, { chunk }) {
|
|
@@ -443,6 +457,9 @@ function viteLegacyPlugin(options = {}) {
|
|
|
443
457
|
attrs: {
|
|
444
458
|
nomodule: true,
|
|
445
459
|
crossorigin: true,
|
|
460
|
+
// we set the entry path on the element as an attribute so that the
|
|
461
|
+
// script content will stay consistent - which allows using a constant
|
|
462
|
+
// hash value for CSP.
|
|
446
463
|
id: legacyEntryId,
|
|
447
464
|
"data-src": toAssetPathFromHtml(
|
|
448
465
|
legacyEntryFilename,
|
|
@@ -458,7 +475,7 @@ function viteLegacyPlugin(options = {}) {
|
|
|
458
475
|
`No corresponding legacy entry chunk found for ${htmlFilename}`
|
|
459
476
|
);
|
|
460
477
|
}
|
|
461
|
-
if (
|
|
478
|
+
if (genLegacy && legacyPolyfillFilename && legacyEntryFilename) {
|
|
462
479
|
tags.push({
|
|
463
480
|
tag: "script",
|
|
464
481
|
attrs: { type: "module" },
|
|
@@ -483,7 +500,7 @@ function viteLegacyPlugin(options = {}) {
|
|
|
483
500
|
}
|
|
484
501
|
if (isLegacyBundle(bundle, opts)) {
|
|
485
502
|
for (const name in bundle) {
|
|
486
|
-
if (bundle[name].type === "asset") {
|
|
503
|
+
if (bundle[name].type === "asset" && !/.+\.map$/.test(name)) {
|
|
487
504
|
delete bundle[name];
|
|
488
505
|
}
|
|
489
506
|
}
|
|
@@ -494,20 +511,20 @@ function viteLegacyPlugin(options = {}) {
|
|
|
494
511
|
}
|
|
495
512
|
async function detectPolyfills(code, targets, list) {
|
|
496
513
|
const babel2 = await loadBabel();
|
|
497
|
-
const
|
|
514
|
+
const result = babel2.transform(code, {
|
|
498
515
|
ast: true,
|
|
499
516
|
babelrc: false,
|
|
500
517
|
configFile: false,
|
|
501
518
|
presets: [
|
|
502
519
|
[
|
|
503
|
-
"env",
|
|
520
|
+
"@babel/preset-env",
|
|
504
521
|
createBabelPresetEnvOptions(targets, {
|
|
505
522
|
ignoreBrowserslistConfig: true
|
|
506
523
|
})
|
|
507
524
|
]
|
|
508
525
|
]
|
|
509
526
|
});
|
|
510
|
-
for (const node of ast.program.body) {
|
|
527
|
+
for (const node of result.ast.program.body) {
|
|
511
528
|
if (node.type === "ImportDeclaration") {
|
|
512
529
|
const source = node.source.value;
|
|
513
530
|
if (source.startsWith("core-js/") || source.startsWith("regenerator-runtime/")) {
|
|
@@ -539,6 +556,7 @@ async function buildPolyfillChunk(mode, imports, bundle, facadeToChunkMap, build
|
|
|
539
556
|
minify = minify ? "terser" : false;
|
|
540
557
|
const res = await build({
|
|
541
558
|
mode,
|
|
559
|
+
// so that everything is resolved from here
|
|
542
560
|
root: path.dirname(fileURLToPath(import.meta.url)),
|
|
543
561
|
configFile: false,
|
|
544
562
|
logLevel: "error",
|
|
@@ -557,9 +575,15 @@ async function buildPolyfillChunk(mode, imports, bundle, facadeToChunkMap, build
|
|
|
557
575
|
}
|
|
558
576
|
}
|
|
559
577
|
},
|
|
578
|
+
// Don't run esbuild for transpilation or minification
|
|
579
|
+
// because we don't want to transpile code.
|
|
560
580
|
esbuild: false,
|
|
561
581
|
optimizeDeps: {
|
|
562
582
|
esbuildOptions: {
|
|
583
|
+
// If a value above 'es5' is set, esbuild injects helper functions which uses es2015 features.
|
|
584
|
+
// This limits the input code not to include es2015+ codes.
|
|
585
|
+
// But core-js is the only dependency which includes commonjs code
|
|
586
|
+
// and core-js doesn't include es2015+ codes.
|
|
563
587
|
target: "es5"
|
|
564
588
|
}
|
|
565
589
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vitejs/plugin-legacy",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "4.0.1",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"author": "Evan You",
|
|
6
6
|
"files": [
|
|
@@ -41,7 +41,9 @@
|
|
|
41
41
|
},
|
|
42
42
|
"homepage": "https://github.com/vitejs/vite/tree/main/packages/plugin-legacy#readme",
|
|
43
43
|
"dependencies": {
|
|
44
|
-
"@babel/
|
|
44
|
+
"@babel/core": "^7.20.12",
|
|
45
|
+
"@babel/preset-env": "^7.20.2",
|
|
46
|
+
"browserslist": "^4.21.4",
|
|
45
47
|
"core-js": "^3.27.2",
|
|
46
48
|
"magic-string": "^0.27.0",
|
|
47
49
|
"regenerator-runtime": "^0.13.11",
|
|
@@ -52,7 +54,7 @@
|
|
|
52
54
|
"vite": "^4.0.0"
|
|
53
55
|
},
|
|
54
56
|
"devDependencies": {
|
|
55
|
-
"
|
|
57
|
+
"acorn": "^8.8.2",
|
|
56
58
|
"picocolors": "^1.0.0",
|
|
57
59
|
"vite": "workspace:*"
|
|
58
60
|
}
|