@vitejs/plugin-legacy 1.8.2 → 2.0.0-alpha.2
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 +11 -17
- package/dist/index.cjs +487 -0
- package/dist/index.d.ts +37 -0
- package/dist/index.mjs +475 -0
- package/package.json +28 -10
- package/index.d.ts +0 -35
- package/index.js +0 -712
package/index.js
DELETED
|
@@ -1,712 +0,0 @@
|
|
|
1
|
-
// @ts-check
|
|
2
|
-
const path = require('path')
|
|
3
|
-
const { createHash } = require('crypto')
|
|
4
|
-
const { build } = require('vite')
|
|
5
|
-
const MagicString = require('magic-string').default
|
|
6
|
-
|
|
7
|
-
// lazy load babel since it's not used during dev
|
|
8
|
-
let babel
|
|
9
|
-
/**
|
|
10
|
-
* @return {import('@babel/standalone')}
|
|
11
|
-
*/
|
|
12
|
-
const loadBabel = () => babel || (babel = require('@babel/standalone'))
|
|
13
|
-
|
|
14
|
-
// https://gist.github.com/samthor/64b114e4a4f539915a95b91ffd340acc
|
|
15
|
-
// DO NOT ALTER THIS CONTENT
|
|
16
|
-
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()}}();`
|
|
17
|
-
|
|
18
|
-
const legacyPolyfillId = 'vite-legacy-polyfill'
|
|
19
|
-
const legacyEntryId = 'vite-legacy-entry'
|
|
20
|
-
const systemJSInlineCode = `System.import(document.getElementById('${legacyEntryId}').getAttribute('data-src'))`
|
|
21
|
-
|
|
22
|
-
const detectDynamicImportVarName = '__vite_is_dynamic_import_support'
|
|
23
|
-
const detectDynamicImportCode = `try{import("_").catch(()=>1);}catch(e){}window.${detectDynamicImportVarName}=true;`
|
|
24
|
-
const dynamicFallbackInlineCode = `!function(){if(window.${detectDynamicImportVarName})return;console.warn("vite: loading legacy build because dynamic import 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)}();`
|
|
25
|
-
|
|
26
|
-
const forceDynamicImportUsage = `export function __vite_legacy_guard(){import('data:text/javascript,')};`
|
|
27
|
-
|
|
28
|
-
const legacyEnvVarMarker = `__VITE_IS_LEGACY__`
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* @param {import('.').Options} options
|
|
32
|
-
* @returns {import('vite').Plugin[]}
|
|
33
|
-
*/
|
|
34
|
-
function viteLegacyPlugin(options = {}) {
|
|
35
|
-
/**
|
|
36
|
-
* @type {import('vite').ResolvedConfig}
|
|
37
|
-
*/
|
|
38
|
-
let config
|
|
39
|
-
const targets = options.targets || 'defaults'
|
|
40
|
-
const genLegacy = options.renderLegacyChunks !== false
|
|
41
|
-
const genDynamicFallback = genLegacy
|
|
42
|
-
|
|
43
|
-
const debugFlags = (process.env.DEBUG || '').split(',')
|
|
44
|
-
const isDebug =
|
|
45
|
-
debugFlags.includes('vite:*') || debugFlags.includes('vite:legacy')
|
|
46
|
-
|
|
47
|
-
const facadeToLegacyChunkMap = new Map()
|
|
48
|
-
const facadeToLegacyPolyfillMap = new Map()
|
|
49
|
-
const facadeToModernPolyfillMap = new Map()
|
|
50
|
-
const modernPolyfills = new Set()
|
|
51
|
-
// System JS relies on the Promise interface. It needs to be polyfilled for IE 11. (array.iterator is mandatory for supporting Promise.all)
|
|
52
|
-
const DEFAULT_LEGACY_POLYFILL = [
|
|
53
|
-
'core-js/modules/es.promise',
|
|
54
|
-
'core-js/modules/es.array.iterator'
|
|
55
|
-
]
|
|
56
|
-
const legacyPolyfills = new Set(DEFAULT_LEGACY_POLYFILL)
|
|
57
|
-
|
|
58
|
-
if (Array.isArray(options.modernPolyfills)) {
|
|
59
|
-
options.modernPolyfills.forEach((i) => {
|
|
60
|
-
modernPolyfills.add(
|
|
61
|
-
i.includes('/') ? `core-js/${i}` : `core-js/modules/${i}.js`
|
|
62
|
-
)
|
|
63
|
-
})
|
|
64
|
-
}
|
|
65
|
-
if (Array.isArray(options.polyfills)) {
|
|
66
|
-
options.polyfills.forEach((i) => {
|
|
67
|
-
if (i.startsWith(`regenerator`)) {
|
|
68
|
-
legacyPolyfills.add(`regenerator-runtime/runtime.js`)
|
|
69
|
-
} else {
|
|
70
|
-
legacyPolyfills.add(
|
|
71
|
-
i.includes('/') ? `core-js/${i}` : `core-js/modules/${i}.js`
|
|
72
|
-
)
|
|
73
|
-
}
|
|
74
|
-
})
|
|
75
|
-
}
|
|
76
|
-
if (Array.isArray(options.additionalLegacyPolyfills)) {
|
|
77
|
-
options.additionalLegacyPolyfills.forEach((i) => {
|
|
78
|
-
legacyPolyfills.add(i)
|
|
79
|
-
})
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
/**
|
|
83
|
-
* @type {import('vite').Plugin}
|
|
84
|
-
*/
|
|
85
|
-
const legacyConfigPlugin = {
|
|
86
|
-
name: 'vite:legacy-config',
|
|
87
|
-
|
|
88
|
-
apply: 'build',
|
|
89
|
-
config(config) {
|
|
90
|
-
if (!config.build) {
|
|
91
|
-
config.build = {}
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
if (!config.build.cssTarget) {
|
|
95
|
-
// Hint for esbuild that we are targeting legacy browsers when minifying CSS.
|
|
96
|
-
// Full CSS compat table available at https://github.com/evanw/esbuild/blob/78e04680228cf989bdd7d471e02bbc2c8d345dc9/internal/compat/css_table.go
|
|
97
|
-
// But note that only the `HexRGBA` feature affects the minify outcome.
|
|
98
|
-
// HSL & rebeccapurple values will be minified away regardless the target.
|
|
99
|
-
// So targeting `chrome61` suffices to fix the compatiblity issue.
|
|
100
|
-
config.build.cssTarget = 'chrome61'
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
/**
|
|
106
|
-
* @type {import('vite').Plugin}
|
|
107
|
-
*/
|
|
108
|
-
const legacyGenerateBundlePlugin = {
|
|
109
|
-
name: 'vite:legacy-generate-polyfill-chunk',
|
|
110
|
-
apply: 'build',
|
|
111
|
-
|
|
112
|
-
async generateBundle(opts, bundle) {
|
|
113
|
-
if (config.build.ssr) {
|
|
114
|
-
return
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
if (!isLegacyBundle(bundle, opts)) {
|
|
118
|
-
if (!modernPolyfills.size) {
|
|
119
|
-
return
|
|
120
|
-
}
|
|
121
|
-
isDebug &&
|
|
122
|
-
console.log(
|
|
123
|
-
`[@vitejs/plugin-legacy] modern polyfills:`,
|
|
124
|
-
modernPolyfills
|
|
125
|
-
)
|
|
126
|
-
await buildPolyfillChunk(
|
|
127
|
-
'polyfills-modern',
|
|
128
|
-
modernPolyfills,
|
|
129
|
-
bundle,
|
|
130
|
-
facadeToModernPolyfillMap,
|
|
131
|
-
config.build,
|
|
132
|
-
options.externalSystemJS
|
|
133
|
-
)
|
|
134
|
-
return
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
if (!genLegacy) {
|
|
138
|
-
return
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
// legacy bundle
|
|
142
|
-
if (legacyPolyfills.size || genDynamicFallback) {
|
|
143
|
-
if (!legacyPolyfills.has('es.promise')) {
|
|
144
|
-
// check if the target needs Promise polyfill because SystemJS relies
|
|
145
|
-
// on it
|
|
146
|
-
detectPolyfills(`Promise.resolve()`, targets, legacyPolyfills)
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
isDebug &&
|
|
150
|
-
console.log(
|
|
151
|
-
`[@vitejs/plugin-legacy] legacy polyfills:`,
|
|
152
|
-
legacyPolyfills
|
|
153
|
-
)
|
|
154
|
-
|
|
155
|
-
await buildPolyfillChunk(
|
|
156
|
-
'polyfills-legacy',
|
|
157
|
-
legacyPolyfills,
|
|
158
|
-
bundle,
|
|
159
|
-
facadeToLegacyPolyfillMap,
|
|
160
|
-
// force using terser for legacy polyfill minification, since esbuild
|
|
161
|
-
// isn't legacy-safe
|
|
162
|
-
config.build,
|
|
163
|
-
options.externalSystemJS
|
|
164
|
-
)
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
/**
|
|
170
|
-
* @type {import('vite').Plugin}
|
|
171
|
-
*/
|
|
172
|
-
const legacyPostPlugin = {
|
|
173
|
-
name: 'vite:legacy-post-process',
|
|
174
|
-
enforce: 'post',
|
|
175
|
-
apply: 'build',
|
|
176
|
-
|
|
177
|
-
configResolved(_config) {
|
|
178
|
-
if (_config.build.lib) {
|
|
179
|
-
throw new Error('@vitejs/plugin-legacy does not support library mode.')
|
|
180
|
-
}
|
|
181
|
-
config = _config
|
|
182
|
-
|
|
183
|
-
if (!genLegacy || config.build.ssr) {
|
|
184
|
-
return
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
/**
|
|
188
|
-
* @param {string | ((chunkInfo: import('rollup').PreRenderedChunk) => string)} fileNames
|
|
189
|
-
* @param {string?} defaultFileName
|
|
190
|
-
* @returns {string | ((chunkInfo: import('rollup').PreRenderedChunk) => string)}
|
|
191
|
-
*/
|
|
192
|
-
const getLegacyOutputFileName = (
|
|
193
|
-
fileNames,
|
|
194
|
-
defaultFileName = '[name]-legacy.[hash].js'
|
|
195
|
-
) => {
|
|
196
|
-
if (!fileNames) {
|
|
197
|
-
return path.posix.join(config.build.assetsDir, defaultFileName)
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
return (chunkInfo) => {
|
|
201
|
-
let fileName =
|
|
202
|
-
typeof fileNames === 'function' ? fileNames(chunkInfo) : fileNames
|
|
203
|
-
|
|
204
|
-
if (fileName.includes('[name]')) {
|
|
205
|
-
// [name]-[hash].[format] -> [name]-legacy-[hash].[format]
|
|
206
|
-
fileName = fileName.replace('[name]', '[name]-legacy')
|
|
207
|
-
} else {
|
|
208
|
-
// entry.js -> entry-legacy.js
|
|
209
|
-
fileName = fileName.replace(/(.+)\.(.+)/, '$1-legacy.$2')
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
return fileName
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
/**
|
|
217
|
-
* @param {import('rollup').OutputOptions} options
|
|
218
|
-
* @returns {import('rollup').OutputOptions}
|
|
219
|
-
*/
|
|
220
|
-
const createLegacyOutput = (options = {}) => {
|
|
221
|
-
return {
|
|
222
|
-
...options,
|
|
223
|
-
format: 'system',
|
|
224
|
-
entryFileNames: getLegacyOutputFileName(options.entryFileNames),
|
|
225
|
-
chunkFileNames: getLegacyOutputFileName(options.chunkFileNames)
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
const { rollupOptions } = config.build
|
|
230
|
-
const { output } = rollupOptions
|
|
231
|
-
if (Array.isArray(output)) {
|
|
232
|
-
rollupOptions.output = [...output.map(createLegacyOutput), ...output]
|
|
233
|
-
} else {
|
|
234
|
-
rollupOptions.output = [createLegacyOutput(output), output || {}]
|
|
235
|
-
}
|
|
236
|
-
},
|
|
237
|
-
|
|
238
|
-
renderChunk(raw, chunk, opts) {
|
|
239
|
-
if (config.build.ssr) {
|
|
240
|
-
return
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
if (!isLegacyChunk(chunk, opts)) {
|
|
244
|
-
if (
|
|
245
|
-
options.modernPolyfills &&
|
|
246
|
-
!Array.isArray(options.modernPolyfills)
|
|
247
|
-
) {
|
|
248
|
-
// analyze and record modern polyfills
|
|
249
|
-
detectPolyfills(raw, { esmodules: true }, modernPolyfills)
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
const ms = new MagicString(raw)
|
|
253
|
-
|
|
254
|
-
if (genDynamicFallback && chunk.isEntry) {
|
|
255
|
-
ms.prepend(forceDynamicImportUsage)
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
if (raw.includes(legacyEnvVarMarker)) {
|
|
259
|
-
const re = new RegExp(legacyEnvVarMarker, 'g')
|
|
260
|
-
let match
|
|
261
|
-
while ((match = re.exec(raw))) {
|
|
262
|
-
ms.overwrite(
|
|
263
|
-
match.index,
|
|
264
|
-
match.index + legacyEnvVarMarker.length,
|
|
265
|
-
`false`
|
|
266
|
-
)
|
|
267
|
-
}
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
if (config.build.sourcemap) {
|
|
271
|
-
return {
|
|
272
|
-
code: ms.toString(),
|
|
273
|
-
map: ms.generateMap({ hires: true })
|
|
274
|
-
}
|
|
275
|
-
}
|
|
276
|
-
return ms.toString()
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
if (!genLegacy) {
|
|
280
|
-
return
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
// @ts-ignore avoid esbuild transform on legacy chunks since it produces
|
|
284
|
-
// legacy-unsafe code - e.g. rewriting object properties into shorthands
|
|
285
|
-
opts.__vite_skip_esbuild__ = true
|
|
286
|
-
|
|
287
|
-
// @ts-ignore force terser for legacy chunks. This only takes effect if
|
|
288
|
-
// minification isn't disabled, because that leaves out the terser plugin
|
|
289
|
-
// entirely.
|
|
290
|
-
opts.__vite_force_terser__ = true
|
|
291
|
-
|
|
292
|
-
// @ts-ignore
|
|
293
|
-
// In the `generateBundle` hook,
|
|
294
|
-
// we'll delete the assets from the legacy bundle to avoid emitting duplicate assets.
|
|
295
|
-
// But that's still a waste of computing resource.
|
|
296
|
-
// So we add this flag to avoid emitting the asset in the first place whenever possible.
|
|
297
|
-
opts.__vite_skip_asset_emit__ = true
|
|
298
|
-
|
|
299
|
-
// @ts-ignore avoid emitting assets for legacy bundle
|
|
300
|
-
const needPolyfills =
|
|
301
|
-
options.polyfills !== false && !Array.isArray(options.polyfills)
|
|
302
|
-
|
|
303
|
-
// transform the legacy chunk with @babel/preset-env
|
|
304
|
-
const sourceMaps = !!config.build.sourcemap
|
|
305
|
-
const { code, map } = loadBabel().transform(raw, {
|
|
306
|
-
babelrc: false,
|
|
307
|
-
configFile: false,
|
|
308
|
-
compact: true,
|
|
309
|
-
sourceMaps,
|
|
310
|
-
inputSourceMap: sourceMaps && chunk.map,
|
|
311
|
-
presets: [
|
|
312
|
-
// forcing our plugin to run before preset-env by wrapping it in a
|
|
313
|
-
// preset so we can catch the injected import statements...
|
|
314
|
-
[
|
|
315
|
-
() => ({
|
|
316
|
-
plugins: [
|
|
317
|
-
recordAndRemovePolyfillBabelPlugin(legacyPolyfills),
|
|
318
|
-
replaceLegacyEnvBabelPlugin(),
|
|
319
|
-
wrapIIFEBabelPlugin()
|
|
320
|
-
]
|
|
321
|
-
})
|
|
322
|
-
],
|
|
323
|
-
[
|
|
324
|
-
'env',
|
|
325
|
-
{
|
|
326
|
-
targets,
|
|
327
|
-
modules: false,
|
|
328
|
-
bugfixes: true,
|
|
329
|
-
loose: false,
|
|
330
|
-
useBuiltIns: needPolyfills ? 'usage' : false,
|
|
331
|
-
corejs: needPolyfills
|
|
332
|
-
? {
|
|
333
|
-
version: require('core-js/package.json').version,
|
|
334
|
-
proposals: false
|
|
335
|
-
}
|
|
336
|
-
: undefined,
|
|
337
|
-
shippedProposals: true,
|
|
338
|
-
ignoreBrowserslistConfig: options.ignoreBrowserslistConfig
|
|
339
|
-
}
|
|
340
|
-
]
|
|
341
|
-
]
|
|
342
|
-
})
|
|
343
|
-
|
|
344
|
-
return { code, map }
|
|
345
|
-
},
|
|
346
|
-
|
|
347
|
-
transformIndexHtml(html, { chunk }) {
|
|
348
|
-
if (config.build.ssr) return
|
|
349
|
-
if (!chunk) return
|
|
350
|
-
if (chunk.fileName.includes('-legacy')) {
|
|
351
|
-
// The legacy bundle is built first, and its index.html isn't actually
|
|
352
|
-
// emitted. Here we simply record its corresponding legacy chunk.
|
|
353
|
-
facadeToLegacyChunkMap.set(chunk.facadeModuleId, chunk.fileName)
|
|
354
|
-
return
|
|
355
|
-
}
|
|
356
|
-
|
|
357
|
-
/**
|
|
358
|
-
* @type {import('vite').HtmlTagDescriptor[]}
|
|
359
|
-
*/
|
|
360
|
-
const tags = []
|
|
361
|
-
const htmlFilename = chunk.facadeModuleId.replace(/\?.*$/, '')
|
|
362
|
-
|
|
363
|
-
// 1. inject modern polyfills
|
|
364
|
-
const modernPolyfillFilename = facadeToModernPolyfillMap.get(
|
|
365
|
-
chunk.facadeModuleId
|
|
366
|
-
)
|
|
367
|
-
if (modernPolyfillFilename) {
|
|
368
|
-
tags.push({
|
|
369
|
-
tag: 'script',
|
|
370
|
-
attrs: {
|
|
371
|
-
type: 'module',
|
|
372
|
-
src: `${config.base}${modernPolyfillFilename}`
|
|
373
|
-
}
|
|
374
|
-
})
|
|
375
|
-
} else if (modernPolyfills.size) {
|
|
376
|
-
throw new Error(
|
|
377
|
-
`No corresponding modern polyfill chunk found for ${htmlFilename}`
|
|
378
|
-
)
|
|
379
|
-
}
|
|
380
|
-
|
|
381
|
-
if (!genLegacy) {
|
|
382
|
-
return { html, tags }
|
|
383
|
-
}
|
|
384
|
-
|
|
385
|
-
// 2. inject Safari 10 nomodule fix
|
|
386
|
-
tags.push({
|
|
387
|
-
tag: 'script',
|
|
388
|
-
attrs: { nomodule: true },
|
|
389
|
-
children: safari10NoModuleFix,
|
|
390
|
-
injectTo: 'body'
|
|
391
|
-
})
|
|
392
|
-
|
|
393
|
-
// 3. inject legacy polyfills
|
|
394
|
-
const legacyPolyfillFilename = facadeToLegacyPolyfillMap.get(
|
|
395
|
-
chunk.facadeModuleId
|
|
396
|
-
)
|
|
397
|
-
if (legacyPolyfillFilename) {
|
|
398
|
-
tags.push({
|
|
399
|
-
tag: 'script',
|
|
400
|
-
attrs: {
|
|
401
|
-
nomodule: true,
|
|
402
|
-
id: legacyPolyfillId,
|
|
403
|
-
src: `${config.base}${legacyPolyfillFilename}`
|
|
404
|
-
},
|
|
405
|
-
injectTo: 'body'
|
|
406
|
-
})
|
|
407
|
-
} else if (legacyPolyfills.size) {
|
|
408
|
-
throw new Error(
|
|
409
|
-
`No corresponding legacy polyfill chunk found for ${htmlFilename}`
|
|
410
|
-
)
|
|
411
|
-
}
|
|
412
|
-
|
|
413
|
-
// 4. inject legacy entry
|
|
414
|
-
const legacyEntryFilename = facadeToLegacyChunkMap.get(
|
|
415
|
-
chunk.facadeModuleId
|
|
416
|
-
)
|
|
417
|
-
if (legacyEntryFilename) {
|
|
418
|
-
tags.push({
|
|
419
|
-
tag: 'script',
|
|
420
|
-
attrs: {
|
|
421
|
-
nomodule: true,
|
|
422
|
-
// we set the entry path on the element as an attribute so that the
|
|
423
|
-
// script content will stay consistent - which allows using a constant
|
|
424
|
-
// hash value for CSP.
|
|
425
|
-
id: legacyEntryId,
|
|
426
|
-
'data-src': config.base + legacyEntryFilename
|
|
427
|
-
},
|
|
428
|
-
children: systemJSInlineCode,
|
|
429
|
-
injectTo: 'body'
|
|
430
|
-
})
|
|
431
|
-
} else {
|
|
432
|
-
throw new Error(
|
|
433
|
-
`No corresponding legacy entry chunk found for ${htmlFilename}`
|
|
434
|
-
)
|
|
435
|
-
}
|
|
436
|
-
|
|
437
|
-
// 5. inject dynamic import fallback entry
|
|
438
|
-
if (genDynamicFallback && legacyPolyfillFilename && legacyEntryFilename) {
|
|
439
|
-
tags.push({
|
|
440
|
-
tag: 'script',
|
|
441
|
-
attrs: { type: 'module' },
|
|
442
|
-
children: detectDynamicImportCode,
|
|
443
|
-
injectTo: 'head'
|
|
444
|
-
})
|
|
445
|
-
tags.push({
|
|
446
|
-
tag: 'script',
|
|
447
|
-
attrs: { type: 'module' },
|
|
448
|
-
children: dynamicFallbackInlineCode,
|
|
449
|
-
injectTo: 'head'
|
|
450
|
-
})
|
|
451
|
-
}
|
|
452
|
-
|
|
453
|
-
return {
|
|
454
|
-
html,
|
|
455
|
-
tags
|
|
456
|
-
}
|
|
457
|
-
},
|
|
458
|
-
|
|
459
|
-
generateBundle(opts, bundle) {
|
|
460
|
-
if (config.build.ssr) {
|
|
461
|
-
return
|
|
462
|
-
}
|
|
463
|
-
|
|
464
|
-
if (isLegacyBundle(bundle, opts)) {
|
|
465
|
-
// avoid emitting duplicate assets
|
|
466
|
-
for (const name in bundle) {
|
|
467
|
-
if (bundle[name].type === 'asset') {
|
|
468
|
-
delete bundle[name]
|
|
469
|
-
}
|
|
470
|
-
}
|
|
471
|
-
}
|
|
472
|
-
}
|
|
473
|
-
}
|
|
474
|
-
|
|
475
|
-
let envInjectionFailed = false
|
|
476
|
-
/**
|
|
477
|
-
* @type {import('vite').Plugin}
|
|
478
|
-
*/
|
|
479
|
-
const legacyEnvPlugin = {
|
|
480
|
-
name: 'vite:legacy-env',
|
|
481
|
-
|
|
482
|
-
config(config, env) {
|
|
483
|
-
if (env) {
|
|
484
|
-
return {
|
|
485
|
-
define: {
|
|
486
|
-
'import.meta.env.LEGACY':
|
|
487
|
-
env.command === 'serve' || config.build.ssr
|
|
488
|
-
? false
|
|
489
|
-
: legacyEnvVarMarker
|
|
490
|
-
}
|
|
491
|
-
}
|
|
492
|
-
} else {
|
|
493
|
-
envInjectionFailed = true
|
|
494
|
-
}
|
|
495
|
-
},
|
|
496
|
-
|
|
497
|
-
configResolved(config) {
|
|
498
|
-
if (envInjectionFailed) {
|
|
499
|
-
config.logger.warn(
|
|
500
|
-
`[@vitejs/plugin-legacy] import.meta.env.LEGACY was not injected due ` +
|
|
501
|
-
`to incompatible vite version (requires vite@^2.0.0-beta.69).`
|
|
502
|
-
)
|
|
503
|
-
}
|
|
504
|
-
}
|
|
505
|
-
}
|
|
506
|
-
|
|
507
|
-
return [
|
|
508
|
-
legacyConfigPlugin,
|
|
509
|
-
legacyGenerateBundlePlugin,
|
|
510
|
-
legacyPostPlugin,
|
|
511
|
-
legacyEnvPlugin
|
|
512
|
-
]
|
|
513
|
-
}
|
|
514
|
-
|
|
515
|
-
/**
|
|
516
|
-
* @param {string} code
|
|
517
|
-
* @param {any} targets
|
|
518
|
-
* @param {Set<string>} list
|
|
519
|
-
*/
|
|
520
|
-
function detectPolyfills(code, targets, list) {
|
|
521
|
-
const { ast } = loadBabel().transform(code, {
|
|
522
|
-
ast: true,
|
|
523
|
-
babelrc: false,
|
|
524
|
-
configFile: false,
|
|
525
|
-
presets: [
|
|
526
|
-
[
|
|
527
|
-
'env',
|
|
528
|
-
{
|
|
529
|
-
targets,
|
|
530
|
-
modules: false,
|
|
531
|
-
useBuiltIns: 'usage',
|
|
532
|
-
corejs: { version: 3, proposals: false },
|
|
533
|
-
shippedProposals: true,
|
|
534
|
-
ignoreBrowserslistConfig: true
|
|
535
|
-
}
|
|
536
|
-
]
|
|
537
|
-
]
|
|
538
|
-
})
|
|
539
|
-
for (const node of ast.program.body) {
|
|
540
|
-
if (node.type === 'ImportDeclaration') {
|
|
541
|
-
const source = node.source.value
|
|
542
|
-
if (
|
|
543
|
-
source.startsWith('core-js/') ||
|
|
544
|
-
source.startsWith('regenerator-runtime/')
|
|
545
|
-
) {
|
|
546
|
-
list.add(source)
|
|
547
|
-
}
|
|
548
|
-
}
|
|
549
|
-
}
|
|
550
|
-
}
|
|
551
|
-
|
|
552
|
-
/**
|
|
553
|
-
* @param {string} name
|
|
554
|
-
* @param {Set<string>} imports
|
|
555
|
-
* @param {import('rollup').OutputBundle} bundle
|
|
556
|
-
* @param {Map<string, string>} facadeToChunkMap
|
|
557
|
-
* @param {import('vite').BuildOptions} buildOptions
|
|
558
|
-
*/
|
|
559
|
-
async function buildPolyfillChunk(
|
|
560
|
-
name,
|
|
561
|
-
imports,
|
|
562
|
-
bundle,
|
|
563
|
-
facadeToChunkMap,
|
|
564
|
-
buildOptions,
|
|
565
|
-
externalSystemJS
|
|
566
|
-
) {
|
|
567
|
-
let { minify, assetsDir } = buildOptions
|
|
568
|
-
minify = minify ? 'terser' : false
|
|
569
|
-
const res = await build({
|
|
570
|
-
// so that everything is resolved from here
|
|
571
|
-
root: __dirname,
|
|
572
|
-
configFile: false,
|
|
573
|
-
logLevel: 'error',
|
|
574
|
-
plugins: [polyfillsPlugin(imports, externalSystemJS)],
|
|
575
|
-
build: {
|
|
576
|
-
write: false,
|
|
577
|
-
target: false,
|
|
578
|
-
minify,
|
|
579
|
-
assetsDir,
|
|
580
|
-
rollupOptions: {
|
|
581
|
-
input: {
|
|
582
|
-
[name]: polyfillId
|
|
583
|
-
},
|
|
584
|
-
output: {
|
|
585
|
-
format: name.includes('legacy') ? 'iife' : 'es',
|
|
586
|
-
manualChunks: undefined
|
|
587
|
-
}
|
|
588
|
-
}
|
|
589
|
-
}
|
|
590
|
-
})
|
|
591
|
-
const _polyfillChunk = Array.isArray(res) ? res[0] : res
|
|
592
|
-
if (!('output' in _polyfillChunk)) return
|
|
593
|
-
const polyfillChunk = _polyfillChunk.output[0]
|
|
594
|
-
|
|
595
|
-
// associate the polyfill chunk to every entry chunk so that we can retrieve
|
|
596
|
-
// the polyfill filename in index html transform
|
|
597
|
-
for (const key in bundle) {
|
|
598
|
-
const chunk = bundle[key]
|
|
599
|
-
if (chunk.type === 'chunk' && chunk.facadeModuleId) {
|
|
600
|
-
facadeToChunkMap.set(chunk.facadeModuleId, polyfillChunk.fileName)
|
|
601
|
-
}
|
|
602
|
-
}
|
|
603
|
-
|
|
604
|
-
// add the chunk to the bundle
|
|
605
|
-
bundle[polyfillChunk.name] = polyfillChunk
|
|
606
|
-
}
|
|
607
|
-
|
|
608
|
-
const polyfillId = '\0vite/legacy-polyfills'
|
|
609
|
-
|
|
610
|
-
/**
|
|
611
|
-
* @param {Set<string>} imports
|
|
612
|
-
* @return {import('rollup').Plugin}
|
|
613
|
-
*/
|
|
614
|
-
function polyfillsPlugin(imports, externalSystemJS) {
|
|
615
|
-
return {
|
|
616
|
-
name: 'vite:legacy-polyfills',
|
|
617
|
-
resolveId(id) {
|
|
618
|
-
if (id === polyfillId) {
|
|
619
|
-
return id
|
|
620
|
-
}
|
|
621
|
-
},
|
|
622
|
-
load(id) {
|
|
623
|
-
if (id === polyfillId) {
|
|
624
|
-
return (
|
|
625
|
-
[...imports].map((i) => `import "${i}";`).join('') +
|
|
626
|
-
(externalSystemJS ? '' : `import "systemjs/dist/s.min.js";`)
|
|
627
|
-
)
|
|
628
|
-
}
|
|
629
|
-
}
|
|
630
|
-
}
|
|
631
|
-
}
|
|
632
|
-
|
|
633
|
-
/**
|
|
634
|
-
* @param {import('rollup').RenderedChunk} chunk
|
|
635
|
-
* @param {import('rollup').NormalizedOutputOptions} options
|
|
636
|
-
*/
|
|
637
|
-
function isLegacyChunk(chunk, options) {
|
|
638
|
-
return options.format === 'system' && chunk.fileName.includes('-legacy')
|
|
639
|
-
}
|
|
640
|
-
|
|
641
|
-
/**
|
|
642
|
-
* @param {import('rollup').OutputBundle} bundle
|
|
643
|
-
* @param {import('rollup').NormalizedOutputOptions} options
|
|
644
|
-
*/
|
|
645
|
-
function isLegacyBundle(bundle, options) {
|
|
646
|
-
if (options.format === 'system') {
|
|
647
|
-
const entryChunk = Object.values(bundle).find(
|
|
648
|
-
(output) => output.type === 'chunk' && output.isEntry
|
|
649
|
-
)
|
|
650
|
-
|
|
651
|
-
return !!entryChunk && entryChunk.fileName.includes('-legacy')
|
|
652
|
-
}
|
|
653
|
-
|
|
654
|
-
return false
|
|
655
|
-
}
|
|
656
|
-
|
|
657
|
-
/**
|
|
658
|
-
* @param {Set<string>} polyfills
|
|
659
|
-
*/
|
|
660
|
-
function recordAndRemovePolyfillBabelPlugin(polyfills) {
|
|
661
|
-
return ({ types: t }) => ({
|
|
662
|
-
name: 'vite-remove-polyfill-import',
|
|
663
|
-
post({ path }) {
|
|
664
|
-
path.get('body').forEach((p) => {
|
|
665
|
-
if (t.isImportDeclaration(p)) {
|
|
666
|
-
polyfills.add(p.node.source.value)
|
|
667
|
-
p.remove()
|
|
668
|
-
}
|
|
669
|
-
})
|
|
670
|
-
}
|
|
671
|
-
})
|
|
672
|
-
}
|
|
673
|
-
|
|
674
|
-
function replaceLegacyEnvBabelPlugin() {
|
|
675
|
-
return ({ types: t }) => ({
|
|
676
|
-
name: 'vite-replace-env-legacy',
|
|
677
|
-
visitor: {
|
|
678
|
-
Identifier(path) {
|
|
679
|
-
if (path.node.name === legacyEnvVarMarker) {
|
|
680
|
-
path.replaceWith(t.booleanLiteral(true))
|
|
681
|
-
}
|
|
682
|
-
}
|
|
683
|
-
}
|
|
684
|
-
})
|
|
685
|
-
}
|
|
686
|
-
|
|
687
|
-
function wrapIIFEBabelPlugin() {
|
|
688
|
-
return ({ types: t, template }) => {
|
|
689
|
-
const buildIIFE = template(';(function(){%%body%%})();')
|
|
690
|
-
|
|
691
|
-
return {
|
|
692
|
-
name: 'vite-wrap-iife',
|
|
693
|
-
post({ path }) {
|
|
694
|
-
if (!this.isWrapped) {
|
|
695
|
-
this.isWrapped = true
|
|
696
|
-
path.replaceWith(t.program(buildIIFE({ body: path.node.body })))
|
|
697
|
-
}
|
|
698
|
-
}
|
|
699
|
-
}
|
|
700
|
-
}
|
|
701
|
-
}
|
|
702
|
-
|
|
703
|
-
module.exports = viteLegacyPlugin
|
|
704
|
-
|
|
705
|
-
viteLegacyPlugin.default = viteLegacyPlugin
|
|
706
|
-
|
|
707
|
-
viteLegacyPlugin.cspHashes = [
|
|
708
|
-
createHash('sha256').update(safari10NoModuleFix).digest('base64'),
|
|
709
|
-
createHash('sha256').update(systemJSInlineCode).digest('base64'),
|
|
710
|
-
createHash('sha256').update(detectDynamicImportCode).digest('base64'),
|
|
711
|
-
createHash('sha256').update(dynamicFallbackInlineCode).digest('base64')
|
|
712
|
-
]
|