@vitejs/plugin-legacy 3.0.2 → 4.0.0
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 +50 -27
- package/dist/index.mjs +50 -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,12 +74,22 @@ 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
|
}
|
|
@@ -125,21 +140,12 @@ function toAssetPathFromHtml(filename, htmlPath, config) {
|
|
|
125
140
|
toRelative
|
|
126
141
|
);
|
|
127
142
|
}
|
|
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
143
|
const legacyEnvVarMarker = `__VITE_IS_LEGACY__`;
|
|
137
144
|
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
145
|
function viteLegacyPlugin(options = {}) {
|
|
139
146
|
let config;
|
|
140
|
-
|
|
147
|
+
let targets;
|
|
141
148
|
const genLegacy = options.renderLegacyChunks !== false;
|
|
142
|
-
const genDynamicFallback = genLegacy;
|
|
143
149
|
const debugFlags = (process.env.DEBUG || "").split(",");
|
|
144
150
|
const isDebug = debugFlags.includes("vite:*") || debugFlags.includes("vite:legacy");
|
|
145
151
|
const facadeToLegacyChunkMap = /* @__PURE__ */ new Map();
|
|
@@ -188,7 +194,7 @@ function viteLegacyPlugin(options = {}) {
|
|
|
188
194
|
"edge79",
|
|
189
195
|
"firefox67",
|
|
190
196
|
"chrome64",
|
|
191
|
-
"
|
|
197
|
+
"safari12"
|
|
192
198
|
];
|
|
193
199
|
}
|
|
194
200
|
}
|
|
@@ -201,7 +207,7 @@ function viteLegacyPlugin(options = {}) {
|
|
|
201
207
|
configResolved(config2) {
|
|
202
208
|
if (overriddenBuildTarget) {
|
|
203
209
|
config2.logger.warn(
|
|
204
|
-
|
|
210
|
+
picocolorsExports.yellow(
|
|
205
211
|
`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
212
|
)
|
|
207
213
|
);
|
|
@@ -238,7 +244,7 @@ function viteLegacyPlugin(options = {}) {
|
|
|
238
244
|
if (!genLegacy) {
|
|
239
245
|
return;
|
|
240
246
|
}
|
|
241
|
-
if (legacyPolyfills.size
|
|
247
|
+
if (legacyPolyfills.size) {
|
|
242
248
|
await detectPolyfills(
|
|
243
249
|
`Promise.resolve(); Promise.all();`,
|
|
244
250
|
targets,
|
|
@@ -253,6 +259,8 @@ function viteLegacyPlugin(options = {}) {
|
|
|
253
259
|
legacyPolyfills,
|
|
254
260
|
bundle,
|
|
255
261
|
facadeToLegacyPolyfillMap,
|
|
262
|
+
// force using terser for legacy polyfill minification, since esbuild
|
|
263
|
+
// isn't legacy-safe
|
|
256
264
|
config.build,
|
|
257
265
|
"iife",
|
|
258
266
|
opts,
|
|
@@ -273,6 +281,8 @@ function viteLegacyPlugin(options = {}) {
|
|
|
273
281
|
if (!genLegacy || config.build.ssr) {
|
|
274
282
|
return;
|
|
275
283
|
}
|
|
284
|
+
targets = options.targets || browserslist.loadConfig({ path: config.root }) || "last 2 versions and not dead, > 0.3%, Firefox ESR";
|
|
285
|
+
isDebug && console.log(`[@vitejs/plugin-legacy] targets:`, targets);
|
|
276
286
|
const getLegacyOutputFileName = (fileNames, defaultFileName = "[name]-legacy-[hash].js") => {
|
|
277
287
|
if (!fileNames) {
|
|
278
288
|
return path.posix.join(config.build.assetsDir, defaultFileName);
|
|
@@ -312,8 +322,8 @@ function viteLegacyPlugin(options = {}) {
|
|
|
312
322
|
await detectPolyfills(raw, { esmodules: true }, modernPolyfills);
|
|
313
323
|
}
|
|
314
324
|
const ms = new MagicString(raw);
|
|
315
|
-
if (
|
|
316
|
-
ms.prepend(
|
|
325
|
+
if (genLegacy && chunk.isEntry) {
|
|
326
|
+
ms.prepend(modernChunkLegacyGuard);
|
|
317
327
|
}
|
|
318
328
|
if (raw.includes(legacyEnvVarMarker)) {
|
|
319
329
|
const re = new RegExp(legacyEnvVarMarker, "g");
|
|
@@ -345,13 +355,16 @@ function viteLegacyPlugin(options = {}) {
|
|
|
345
355
|
const needPolyfills = options.polyfills !== false && !Array.isArray(options.polyfills);
|
|
346
356
|
const sourceMaps = !!config.build.sourcemap;
|
|
347
357
|
const babel2 = await loadBabel();
|
|
348
|
-
const
|
|
358
|
+
const result = babel2.transform(raw, {
|
|
349
359
|
babelrc: false,
|
|
350
360
|
configFile: false,
|
|
351
361
|
compact: !!config.build.minify,
|
|
352
362
|
sourceMaps,
|
|
353
363
|
inputSourceMap: void 0,
|
|
364
|
+
// sourceMaps ? chunk.map : undefined, `.map` TODO: moved to OutputChunk?
|
|
354
365
|
presets: [
|
|
366
|
+
// forcing our plugin to run before preset-env by wrapping it in a
|
|
367
|
+
// preset so we can catch the injected import statements...
|
|
355
368
|
[
|
|
356
369
|
() => ({
|
|
357
370
|
plugins: [
|
|
@@ -362,7 +375,7 @@ function viteLegacyPlugin(options = {}) {
|
|
|
362
375
|
})
|
|
363
376
|
],
|
|
364
377
|
[
|
|
365
|
-
"env",
|
|
378
|
+
"@babel/preset-env",
|
|
366
379
|
createBabelPresetEnvOptions(targets, {
|
|
367
380
|
needPolyfills,
|
|
368
381
|
ignoreBrowserslistConfig: options.ignoreBrowserslistConfig
|
|
@@ -370,8 +383,8 @@ function viteLegacyPlugin(options = {}) {
|
|
|
370
383
|
]
|
|
371
384
|
]
|
|
372
385
|
});
|
|
373
|
-
if (
|
|
374
|
-
return { code, map };
|
|
386
|
+
if (result)
|
|
387
|
+
return { code: result.code, map: result.map };
|
|
375
388
|
return null;
|
|
376
389
|
},
|
|
377
390
|
transformIndexHtml(html, { chunk }) {
|
|
@@ -447,6 +460,9 @@ function viteLegacyPlugin(options = {}) {
|
|
|
447
460
|
attrs: {
|
|
448
461
|
nomodule: true,
|
|
449
462
|
crossorigin: true,
|
|
463
|
+
// we set the entry path on the element as an attribute so that the
|
|
464
|
+
// script content will stay consistent - which allows using a constant
|
|
465
|
+
// hash value for CSP.
|
|
450
466
|
id: legacyEntryId,
|
|
451
467
|
"data-src": toAssetPathFromHtml(
|
|
452
468
|
legacyEntryFilename,
|
|
@@ -462,7 +478,7 @@ function viteLegacyPlugin(options = {}) {
|
|
|
462
478
|
`No corresponding legacy entry chunk found for ${htmlFilename}`
|
|
463
479
|
);
|
|
464
480
|
}
|
|
465
|
-
if (
|
|
481
|
+
if (genLegacy && legacyPolyfillFilename && legacyEntryFilename) {
|
|
466
482
|
tags.push({
|
|
467
483
|
tag: "script",
|
|
468
484
|
attrs: { type: "module" },
|
|
@@ -487,7 +503,7 @@ function viteLegacyPlugin(options = {}) {
|
|
|
487
503
|
}
|
|
488
504
|
if (isLegacyBundle(bundle, opts)) {
|
|
489
505
|
for (const name in bundle) {
|
|
490
|
-
if (bundle[name].type === "asset") {
|
|
506
|
+
if (bundle[name].type === "asset" && !/.+\.map$/.test(name)) {
|
|
491
507
|
delete bundle[name];
|
|
492
508
|
}
|
|
493
509
|
}
|
|
@@ -498,20 +514,20 @@ function viteLegacyPlugin(options = {}) {
|
|
|
498
514
|
}
|
|
499
515
|
async function detectPolyfills(code, targets, list) {
|
|
500
516
|
const babel2 = await loadBabel();
|
|
501
|
-
const
|
|
517
|
+
const result = babel2.transform(code, {
|
|
502
518
|
ast: true,
|
|
503
519
|
babelrc: false,
|
|
504
520
|
configFile: false,
|
|
505
521
|
presets: [
|
|
506
522
|
[
|
|
507
|
-
"env",
|
|
523
|
+
"@babel/preset-env",
|
|
508
524
|
createBabelPresetEnvOptions(targets, {
|
|
509
525
|
ignoreBrowserslistConfig: true
|
|
510
526
|
})
|
|
511
527
|
]
|
|
512
528
|
]
|
|
513
529
|
});
|
|
514
|
-
for (const node of ast.program.body) {
|
|
530
|
+
for (const node of result.ast.program.body) {
|
|
515
531
|
if (node.type === "ImportDeclaration") {
|
|
516
532
|
const source = node.source.value;
|
|
517
533
|
if (source.startsWith("core-js/") || source.startsWith("regenerator-runtime/")) {
|
|
@@ -543,6 +559,7 @@ async function buildPolyfillChunk(mode, imports, bundle, facadeToChunkMap, build
|
|
|
543
559
|
minify = minify ? "terser" : false;
|
|
544
560
|
const res = await vite.build({
|
|
545
561
|
mode,
|
|
562
|
+
// so that everything is resolved from here
|
|
546
563
|
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
564
|
configFile: false,
|
|
548
565
|
logLevel: "error",
|
|
@@ -561,9 +578,15 @@ async function buildPolyfillChunk(mode, imports, bundle, facadeToChunkMap, build
|
|
|
561
578
|
}
|
|
562
579
|
}
|
|
563
580
|
},
|
|
581
|
+
// Don't run esbuild for transpilation or minification
|
|
582
|
+
// because we don't want to transpile code.
|
|
564
583
|
esbuild: false,
|
|
565
584
|
optimizeDeps: {
|
|
566
585
|
esbuildOptions: {
|
|
586
|
+
// If a value above 'es5' is set, esbuild injects helper functions which uses es2015 features.
|
|
587
|
+
// This limits the input code not to include es2015+ codes.
|
|
588
|
+
// But core-js is the only dependency which includes commonjs code
|
|
589
|
+
// and core-js doesn't include es2015+ codes.
|
|
567
590
|
target: "es5"
|
|
568
591
|
}
|
|
569
592
|
}
|
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 { loadConfig } 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,12 +70,22 @@ 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
|
}
|
|
@@ -121,21 +136,12 @@ function toAssetPathFromHtml(filename, htmlPath, config) {
|
|
|
121
136
|
toRelative
|
|
122
137
|
);
|
|
123
138
|
}
|
|
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
139
|
const legacyEnvVarMarker = `__VITE_IS_LEGACY__`;
|
|
133
140
|
const _require = createRequire(import.meta.url);
|
|
134
141
|
function viteLegacyPlugin(options = {}) {
|
|
135
142
|
let config;
|
|
136
|
-
|
|
143
|
+
let targets;
|
|
137
144
|
const genLegacy = options.renderLegacyChunks !== false;
|
|
138
|
-
const genDynamicFallback = genLegacy;
|
|
139
145
|
const debugFlags = (process.env.DEBUG || "").split(",");
|
|
140
146
|
const isDebug = debugFlags.includes("vite:*") || debugFlags.includes("vite:legacy");
|
|
141
147
|
const facadeToLegacyChunkMap = /* @__PURE__ */ new Map();
|
|
@@ -184,7 +190,7 @@ function viteLegacyPlugin(options = {}) {
|
|
|
184
190
|
"edge79",
|
|
185
191
|
"firefox67",
|
|
186
192
|
"chrome64",
|
|
187
|
-
"
|
|
193
|
+
"safari12"
|
|
188
194
|
];
|
|
189
195
|
}
|
|
190
196
|
}
|
|
@@ -197,7 +203,7 @@ function viteLegacyPlugin(options = {}) {
|
|
|
197
203
|
configResolved(config2) {
|
|
198
204
|
if (overriddenBuildTarget) {
|
|
199
205
|
config2.logger.warn(
|
|
200
|
-
|
|
206
|
+
picocolorsExports.yellow(
|
|
201
207
|
`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
208
|
)
|
|
203
209
|
);
|
|
@@ -234,7 +240,7 @@ function viteLegacyPlugin(options = {}) {
|
|
|
234
240
|
if (!genLegacy) {
|
|
235
241
|
return;
|
|
236
242
|
}
|
|
237
|
-
if (legacyPolyfills.size
|
|
243
|
+
if (legacyPolyfills.size) {
|
|
238
244
|
await detectPolyfills(
|
|
239
245
|
`Promise.resolve(); Promise.all();`,
|
|
240
246
|
targets,
|
|
@@ -249,6 +255,8 @@ function viteLegacyPlugin(options = {}) {
|
|
|
249
255
|
legacyPolyfills,
|
|
250
256
|
bundle,
|
|
251
257
|
facadeToLegacyPolyfillMap,
|
|
258
|
+
// force using terser for legacy polyfill minification, since esbuild
|
|
259
|
+
// isn't legacy-safe
|
|
252
260
|
config.build,
|
|
253
261
|
"iife",
|
|
254
262
|
opts,
|
|
@@ -269,6 +277,8 @@ function viteLegacyPlugin(options = {}) {
|
|
|
269
277
|
if (!genLegacy || config.build.ssr) {
|
|
270
278
|
return;
|
|
271
279
|
}
|
|
280
|
+
targets = options.targets || loadConfig({ path: config.root }) || "last 2 versions and not dead, > 0.3%, Firefox ESR";
|
|
281
|
+
isDebug && console.log(`[@vitejs/plugin-legacy] targets:`, targets);
|
|
272
282
|
const getLegacyOutputFileName = (fileNames, defaultFileName = "[name]-legacy-[hash].js") => {
|
|
273
283
|
if (!fileNames) {
|
|
274
284
|
return path.posix.join(config.build.assetsDir, defaultFileName);
|
|
@@ -308,8 +318,8 @@ function viteLegacyPlugin(options = {}) {
|
|
|
308
318
|
await detectPolyfills(raw, { esmodules: true }, modernPolyfills);
|
|
309
319
|
}
|
|
310
320
|
const ms = new MagicString(raw);
|
|
311
|
-
if (
|
|
312
|
-
ms.prepend(
|
|
321
|
+
if (genLegacy && chunk.isEntry) {
|
|
322
|
+
ms.prepend(modernChunkLegacyGuard);
|
|
313
323
|
}
|
|
314
324
|
if (raw.includes(legacyEnvVarMarker)) {
|
|
315
325
|
const re = new RegExp(legacyEnvVarMarker, "g");
|
|
@@ -341,13 +351,16 @@ function viteLegacyPlugin(options = {}) {
|
|
|
341
351
|
const needPolyfills = options.polyfills !== false && !Array.isArray(options.polyfills);
|
|
342
352
|
const sourceMaps = !!config.build.sourcemap;
|
|
343
353
|
const babel2 = await loadBabel();
|
|
344
|
-
const
|
|
354
|
+
const result = babel2.transform(raw, {
|
|
345
355
|
babelrc: false,
|
|
346
356
|
configFile: false,
|
|
347
357
|
compact: !!config.build.minify,
|
|
348
358
|
sourceMaps,
|
|
349
359
|
inputSourceMap: void 0,
|
|
360
|
+
// sourceMaps ? chunk.map : undefined, `.map` TODO: moved to OutputChunk?
|
|
350
361
|
presets: [
|
|
362
|
+
// forcing our plugin to run before preset-env by wrapping it in a
|
|
363
|
+
// preset so we can catch the injected import statements...
|
|
351
364
|
[
|
|
352
365
|
() => ({
|
|
353
366
|
plugins: [
|
|
@@ -358,7 +371,7 @@ function viteLegacyPlugin(options = {}) {
|
|
|
358
371
|
})
|
|
359
372
|
],
|
|
360
373
|
[
|
|
361
|
-
"env",
|
|
374
|
+
"@babel/preset-env",
|
|
362
375
|
createBabelPresetEnvOptions(targets, {
|
|
363
376
|
needPolyfills,
|
|
364
377
|
ignoreBrowserslistConfig: options.ignoreBrowserslistConfig
|
|
@@ -366,8 +379,8 @@ function viteLegacyPlugin(options = {}) {
|
|
|
366
379
|
]
|
|
367
380
|
]
|
|
368
381
|
});
|
|
369
|
-
if (
|
|
370
|
-
return { code, map };
|
|
382
|
+
if (result)
|
|
383
|
+
return { code: result.code, map: result.map };
|
|
371
384
|
return null;
|
|
372
385
|
},
|
|
373
386
|
transformIndexHtml(html, { chunk }) {
|
|
@@ -443,6 +456,9 @@ function viteLegacyPlugin(options = {}) {
|
|
|
443
456
|
attrs: {
|
|
444
457
|
nomodule: true,
|
|
445
458
|
crossorigin: true,
|
|
459
|
+
// we set the entry path on the element as an attribute so that the
|
|
460
|
+
// script content will stay consistent - which allows using a constant
|
|
461
|
+
// hash value for CSP.
|
|
446
462
|
id: legacyEntryId,
|
|
447
463
|
"data-src": toAssetPathFromHtml(
|
|
448
464
|
legacyEntryFilename,
|
|
@@ -458,7 +474,7 @@ function viteLegacyPlugin(options = {}) {
|
|
|
458
474
|
`No corresponding legacy entry chunk found for ${htmlFilename}`
|
|
459
475
|
);
|
|
460
476
|
}
|
|
461
|
-
if (
|
|
477
|
+
if (genLegacy && legacyPolyfillFilename && legacyEntryFilename) {
|
|
462
478
|
tags.push({
|
|
463
479
|
tag: "script",
|
|
464
480
|
attrs: { type: "module" },
|
|
@@ -483,7 +499,7 @@ function viteLegacyPlugin(options = {}) {
|
|
|
483
499
|
}
|
|
484
500
|
if (isLegacyBundle(bundle, opts)) {
|
|
485
501
|
for (const name in bundle) {
|
|
486
|
-
if (bundle[name].type === "asset") {
|
|
502
|
+
if (bundle[name].type === "asset" && !/.+\.map$/.test(name)) {
|
|
487
503
|
delete bundle[name];
|
|
488
504
|
}
|
|
489
505
|
}
|
|
@@ -494,20 +510,20 @@ function viteLegacyPlugin(options = {}) {
|
|
|
494
510
|
}
|
|
495
511
|
async function detectPolyfills(code, targets, list) {
|
|
496
512
|
const babel2 = await loadBabel();
|
|
497
|
-
const
|
|
513
|
+
const result = babel2.transform(code, {
|
|
498
514
|
ast: true,
|
|
499
515
|
babelrc: false,
|
|
500
516
|
configFile: false,
|
|
501
517
|
presets: [
|
|
502
518
|
[
|
|
503
|
-
"env",
|
|
519
|
+
"@babel/preset-env",
|
|
504
520
|
createBabelPresetEnvOptions(targets, {
|
|
505
521
|
ignoreBrowserslistConfig: true
|
|
506
522
|
})
|
|
507
523
|
]
|
|
508
524
|
]
|
|
509
525
|
});
|
|
510
|
-
for (const node of ast.program.body) {
|
|
526
|
+
for (const node of result.ast.program.body) {
|
|
511
527
|
if (node.type === "ImportDeclaration") {
|
|
512
528
|
const source = node.source.value;
|
|
513
529
|
if (source.startsWith("core-js/") || source.startsWith("regenerator-runtime/")) {
|
|
@@ -539,6 +555,7 @@ async function buildPolyfillChunk(mode, imports, bundle, facadeToChunkMap, build
|
|
|
539
555
|
minify = minify ? "terser" : false;
|
|
540
556
|
const res = await build({
|
|
541
557
|
mode,
|
|
558
|
+
// so that everything is resolved from here
|
|
542
559
|
root: path.dirname(fileURLToPath(import.meta.url)),
|
|
543
560
|
configFile: false,
|
|
544
561
|
logLevel: "error",
|
|
@@ -557,9 +574,15 @@ async function buildPolyfillChunk(mode, imports, bundle, facadeToChunkMap, build
|
|
|
557
574
|
}
|
|
558
575
|
}
|
|
559
576
|
},
|
|
577
|
+
// Don't run esbuild for transpilation or minification
|
|
578
|
+
// because we don't want to transpile code.
|
|
560
579
|
esbuild: false,
|
|
561
580
|
optimizeDeps: {
|
|
562
581
|
esbuildOptions: {
|
|
582
|
+
// If a value above 'es5' is set, esbuild injects helper functions which uses es2015 features.
|
|
583
|
+
// This limits the input code not to include es2015+ codes.
|
|
584
|
+
// But core-js is the only dependency which includes commonjs code
|
|
585
|
+
// and core-js doesn't include es2015+ codes.
|
|
563
586
|
target: "es5"
|
|
564
587
|
}
|
|
565
588
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vitejs/plugin-legacy",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "4.0.0",
|
|
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
|
}
|