-
-
Notifications
You must be signed in to change notification settings - Fork 6.3k
/
Copy pathindex.js
282 lines (248 loc) · 9.15 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
const path = require('path')
const semver = require('semver')
const defaultPolyfills = [
// promise polyfill alone doesn't work in IE,
// needs this as well. see: #1642
'es.array.iterator',
// this is required for webpack code splitting, vuex etc.
'es.promise',
// this is needed for object rest spread support in templates
// as vue-template-es2015-compiler 1.8+ compiles it to Object.assign() calls.
'es.object.assign',
// #2012 es.promise replaces native Promise in FF and causes missing finally
'es.promise.finally'
]
const {
default: getTargets,
isRequired
} = require('@babel/helper-compilation-targets')
// We'll no longer need this logic in Babel 8 as it's the default behavior
// See discussions at:
// https://github.com/babel/rfcs/pull/2#issuecomment-714785228
// https://github.com/babel/babel/pull/12189
function getIntersectionTargets (targets, constraintTargets) {
const intersection = Object.keys(constraintTargets).reduce(
(results, browser) => {
// exclude the browsers that the user does not need
if (!targets[browser]) {
return results
}
// if the user-specified version is higher the minimum version that supports esmodule, than use it
results[browser] = semver.gt(
semver.coerce(constraintTargets[browser]),
semver.coerce(targets[browser])
)
? constraintTargets[browser]
: targets[browser]
return results
},
{}
)
return intersection
}
function getModuleTargets (targets) {
const allModuleTargets = getTargets(
{ esmodules: true },
{ ignoreBrowserslistConfig: true }
)
// use the intersection of modern mode browsers and user defined targets config
return getIntersectionTargets(targets, allModuleTargets)
}
function getWCTargets (targets) {
// targeting browsers that at least support ES2015 classes
// https://github.com/babel/babel/blob/v7.9.6/packages/babel-compat-data/data/plugins.json#L194-L204
const allWCTargets = getTargets(
{
browsers: [
'Chrome >= 46',
'Firefox >= 45',
'Safari >= 10',
'Edge >= 13',
'iOS >= 10',
'Electron >= 0.36'
]
},
{ ignoreBrowserslistConfig: true }
)
// use the intersection of browsers supporting Web Components and user defined targets config
return getIntersectionTargets(targets, allWCTargets)
}
function getPolyfills (targets, includes) {
// if no targets specified, include all default polyfills
if (!targets || !Object.keys(targets).length) {
return includes
}
const compatData = require('core-js-compat').data
return includes.filter(item => {
if (!compatData[item]) {
throw new Error(`Cannot find polyfill ${item}, please refer to 'core-js-compat' for a complete list of available modules`)
}
return isRequired(item, targets, { compatData })
})
}
module.exports = (context, options = {}) => {
const presets = []
const plugins = []
const defaultEntryFiles = JSON.parse(process.env.VUE_CLI_ENTRY_FILES || '[]')
// Though in the vue-cli repo, we only use the two environment variables
// for tests, users may have relied on them for some features,
// dropping them may break some projects.
// So in the following blocks we don't directly test the `NODE_ENV`.
// Rather, we turn it into the two commonly used feature flags.
if (!process.env.VUE_CLI_TEST && process.env.NODE_ENV === 'test') {
// Both Jest & Mocha set NODE_ENV to 'test'.
// And both requires the `node` target.
process.env.VUE_CLI_BABEL_TARGET_NODE = 'true'
// Jest runs without bundling so it needs this.
// With the node target, tree shaking is not a necessity,
// so we set it for maximum compatibility.
process.env.VUE_CLI_BABEL_TRANSPILE_MODULES = 'true'
}
// JSX
if (options.jsx !== false) {
let jsxOptions = {}
if (typeof options.jsx === 'object') {
jsxOptions = options.jsx
}
let vueVersion = 2
try {
const Vue = require('vue')
vueVersion = semver.major(Vue.version)
} catch (e) {}
if (vueVersion === 2) {
presets.push([require('@vue/babel-preset-jsx'), jsxOptions])
} else if (vueVersion === 3) {
plugins.push([require('@vue/babel-plugin-jsx'), jsxOptions])
}
}
const runtimePath = path.dirname(require.resolve('@babel/runtime/package.json'))
const runtimeVersion = require('@babel/runtime/package.json').version
const {
polyfills: userPolyfills,
loose = false,
debug = false,
useBuiltIns = 'usage',
modules = false,
bugfixes = true,
targets: rawTargets,
spec,
ignoreBrowserslistConfig,
configPath,
include,
exclude,
shippedProposals,
forceAllTransforms,
decoratorsBeforeExport,
decoratorsLegacy,
// entry file list
entryFiles = defaultEntryFiles,
// Undocumented option of @babel/plugin-transform-runtime.
// When enabled, an absolute path is used when importing a runtime helper after transforming.
// This ensures the transpiled file always use the runtime version required in this package.
// However, this may cause hash inconsistency if the project is moved to another directory.
// So here we allow user to explicit disable this option if hash consistency is a requirement
// and the runtime version is sure to be correct.
absoluteRuntime = runtimePath,
// https://babeljs.io/docs/en/babel-plugin-transform-runtime#version
// By default transform-runtime assumes that @babel/[email protected] is installed, which means helpers introduced later than 7.0.0-beta.0 will be inlined instead of imported.
// See https://github.com/babel/babel/issues/10261
// And https://github.com/facebook/docusaurus/pull/2111
version = runtimeVersion
} = options
// resolve targets for preset-env
let targets = getTargets(rawTargets, { ignoreBrowserslistConfig, configPath })
if (process.env.VUE_CLI_BABEL_TARGET_NODE) {
// running tests in Node.js
targets = { node: 'current' }
} else if (process.env.VUE_CLI_BUILD_TARGET === 'wc' || process.env.VUE_CLI_BUILD_TARGET === 'wc-async') {
// targeting browsers that at least support ES2015 classes
targets = getWCTargets(targets)
} else if (process.env.VUE_CLI_MODERN_BUILD) {
// targeting browsers that at least support <script type="module">
targets = getModuleTargets(targets)
}
// included-by-default polyfills. These are common polyfills that 3rd party
// dependencies may rely on (e.g. Vuex relies on Promise), but since with
// useBuiltIns: 'usage' we won't be running Babel on these deps, they need to
// be force-included.
let polyfills
const buildTarget = process.env.VUE_CLI_BUILD_TARGET || 'app'
if (
buildTarget === 'app' &&
useBuiltIns === 'usage' &&
!process.env.VUE_CLI_BABEL_TARGET_NODE
) {
polyfills = getPolyfills(targets, userPolyfills || defaultPolyfills)
plugins.push([
require('./polyfillsPlugin'),
{ polyfills, entryFiles, useAbsolutePath: !!absoluteRuntime }
])
} else {
polyfills = []
}
const envOptions = {
bugfixes,
corejs: useBuiltIns ? require('core-js/package.json').version : false,
spec,
loose,
debug,
modules,
targets,
useBuiltIns,
ignoreBrowserslistConfig,
configPath,
include,
exclude: polyfills.concat(exclude || []),
shippedProposals,
forceAllTransforms
}
// cli-plugin-jest sets this to true because Jest runs without bundling
if (process.env.VUE_CLI_BABEL_TRANSPILE_MODULES) {
envOptions.modules = 'commonjs'
if (process.env.VUE_CLI_BABEL_TARGET_NODE) {
// necessary for dynamic import to work in tests
plugins.push(require('babel-plugin-dynamic-import-node'))
}
}
// pass options along to babel-preset-env
presets.unshift([require('@babel/preset-env'), envOptions])
// additional <= stage-3 plugins
// Babel 7 is removing stage presets altogether because people are using
// too many unstable proposals. Let's be conservative in the defaults here.
plugins.push(
require('@babel/plugin-syntax-dynamic-import'),
[require('@babel/plugin-proposal-decorators'), {
decoratorsBeforeExport,
legacy: decoratorsLegacy !== false
}],
[require('@babel/plugin-proposal-class-properties'), { loose }]
)
// transform runtime, but only for helpers
plugins.push([require('@babel/plugin-transform-runtime'), {
regenerator: useBuiltIns !== 'usage',
// polyfills are injected by preset-env & polyfillsPlugin, so no need to add them again
corejs: false,
helpers: useBuiltIns === 'usage',
useESModules: !process.env.VUE_CLI_BABEL_TRANSPILE_MODULES,
absoluteRuntime,
version
}])
return {
sourceType: 'unambiguous',
overrides: [{
exclude: [/@babel[/|\\\\]runtime/, /core-js/],
presets,
plugins
}, {
// there are some untranspiled code in @babel/runtime
// https://github.com/babel/babel/issues/9903
include: [/@babel[/|\\\\]runtime/],
presets: [
[require('@babel/preset-env'), envOptions]
]
}]
}
}
// a special flag to tell @vue/cli-plugin-babel to include @babel/runtime for transpilation
// otherwise the above `include` option won't take effect
process.env.VUE_CLI_TRANSPILE_BABEL_RUNTIME = true