mirror of
https://github.com/nuxt/nuxt.git
synced 2024-11-15 10:24:50 +00:00
203 lines
4.9 KiB
JavaScript
203 lines
4.9 KiB
JavaScript
const coreJsMeta = {
|
|
2: {
|
|
prefixes: {
|
|
es6: 'es6',
|
|
es7: 'es7'
|
|
},
|
|
builtIns: '@babel/compat-data/corejs2-built-ins'
|
|
},
|
|
3: {
|
|
prefixes: {
|
|
es6: 'es',
|
|
es7: 'es'
|
|
},
|
|
builtIns: 'core-js-compat/data'
|
|
}
|
|
}
|
|
|
|
function getDefaultPolyfills (corejs) {
|
|
const { prefixes: { es6, es7 } } = coreJsMeta[corejs.version]
|
|
return [
|
|
// Promise polyfill alone doesn't work in IE,
|
|
// Needs this as well. see: #1642
|
|
`${es6}.array.iterator`,
|
|
// This is required for webpack code splitting, vuex etc.
|
|
`${es6}.promise`,
|
|
// this is needed for object rest spread support in templates
|
|
// as vue-template-es2015-compiler 1.8+ compiles it to Object.assign() calls.
|
|
`${es6}.object.assign`,
|
|
// #2012 es7.promise replaces native Promise in FF and causes missing finally
|
|
`${es7}.promise.finally`
|
|
]
|
|
}
|
|
|
|
function getPolyfills (targets, includes, { ignoreBrowserslistConfig, configPath, corejs }) {
|
|
const { default: getTargets, isRequired } = require('@babel/helper-compilation-targets')
|
|
const builtInsList = require(coreJsMeta[corejs.version].builtIns)
|
|
const builtInTargets = getTargets(targets, {
|
|
ignoreBrowserslistConfig,
|
|
configPath
|
|
})
|
|
|
|
return includes.filter(item => isRequired(
|
|
'nuxt-polyfills',
|
|
builtInTargets,
|
|
{
|
|
compatData: { 'nuxt-polyfills': builtInsList[item] }
|
|
}
|
|
))
|
|
}
|
|
|
|
function isPackageHoisted (packageName) {
|
|
const path = require('path')
|
|
const installedPath = require.resolve(packageName)
|
|
const relativePath = path.resolve(__dirname, '..', 'node_modules', packageName)
|
|
return installedPath !== relativePath
|
|
}
|
|
|
|
module.exports = (api, options = {}) => {
|
|
const presets = []
|
|
const plugins = []
|
|
|
|
const envName = api.env()
|
|
|
|
const {
|
|
bugfixes,
|
|
polyfills: userPolyfills,
|
|
loose = false,
|
|
debug = false,
|
|
useBuiltIns = 'usage',
|
|
modules = false,
|
|
spec,
|
|
ignoreBrowserslistConfig = envName === 'modern',
|
|
configPath,
|
|
include,
|
|
exclude,
|
|
shippedProposals,
|
|
forceAllTransforms,
|
|
decoratorsBeforeExport,
|
|
decoratorsLegacy,
|
|
absoluteRuntime
|
|
} = options
|
|
|
|
let { corejs = { version: 3 } } = options
|
|
|
|
if (typeof corejs !== 'object') {
|
|
corejs = { version: Number(corejs) }
|
|
}
|
|
|
|
const isCorejs3Hoisted = isPackageHoisted('core-js')
|
|
if (
|
|
(corejs.version === 3 && !isCorejs3Hoisted) ||
|
|
(corejs.version === 2 && isCorejs3Hoisted)
|
|
) {
|
|
// eslint-disable-next-line no-console
|
|
(console.fatal || console.error)(`babel corejs option is ${corejs.version}, please directlly install core-js@${corejs.version}.`)
|
|
}
|
|
|
|
const defaultTargets = {
|
|
server: { node: 'current' },
|
|
client: { ie: 9 },
|
|
modern: { esmodules: true }
|
|
}
|
|
|
|
let { targets = defaultTargets[envName] } = options
|
|
|
|
// modern mode can only be { esmodules: true }
|
|
if (envName === 'modern') {
|
|
targets = defaultTargets.modern
|
|
}
|
|
|
|
const polyfills = []
|
|
|
|
if (envName === 'client' && useBuiltIns === 'usage') {
|
|
polyfills.push(
|
|
...getPolyfills(
|
|
targets,
|
|
userPolyfills || getDefaultPolyfills(corejs),
|
|
{
|
|
ignoreBrowserslistConfig,
|
|
configPath,
|
|
corejs
|
|
}
|
|
)
|
|
)
|
|
plugins.push([polyfillsPlugin, { polyfills }])
|
|
}
|
|
|
|
// Pass options along to babel-preset-env
|
|
presets.push([
|
|
require('@babel/preset-env'), {
|
|
bugfixes,
|
|
spec,
|
|
loose,
|
|
debug,
|
|
modules,
|
|
targets,
|
|
useBuiltIns,
|
|
corejs,
|
|
ignoreBrowserslistConfig,
|
|
configPath,
|
|
include,
|
|
exclude: polyfills.concat(exclude || []),
|
|
shippedProposals,
|
|
forceAllTransforms
|
|
}
|
|
], [
|
|
require('@babel/preset-typescript')
|
|
])
|
|
|
|
// JSX
|
|
if (options.jsx !== false) {
|
|
// presets.push([require('@vue/babel-preset-jsx'), Object.assign({}, options.jsx)])
|
|
}
|
|
|
|
plugins.push(
|
|
[require('@babel/plugin-proposal-decorators'), {
|
|
decoratorsBeforeExport,
|
|
legacy: decoratorsLegacy !== false
|
|
}],
|
|
[require('@babel/plugin-proposal-class-properties'), { loose: true }]
|
|
)
|
|
|
|
// Transform runtime, but only for helpers
|
|
plugins.push([require('@babel/plugin-transform-runtime'), {
|
|
regenerator: useBuiltIns !== 'usage',
|
|
corejs: false,
|
|
helpers: useBuiltIns === 'usage',
|
|
useESModules: envName !== 'server',
|
|
absoluteRuntime
|
|
}])
|
|
|
|
return {
|
|
sourceType: 'unambiguous',
|
|
presets,
|
|
plugins
|
|
}
|
|
}
|
|
|
|
// Add polyfill imports to the first file encountered.
|
|
function polyfillsPlugin ({ _types }) {
|
|
let entryFile
|
|
return {
|
|
name: 'inject-polyfills',
|
|
visitor: {
|
|
Program (path, state) {
|
|
if (!entryFile) {
|
|
entryFile = state.filename
|
|
} else if (state.filename !== entryFile) {
|
|
return
|
|
}
|
|
|
|
const { polyfills } = state.opts
|
|
const { createImport } = require('@babel/preset-env/lib/utils')
|
|
|
|
// Imports are injected in reverse order
|
|
polyfills.slice().reverse().forEach((p) => {
|
|
createImport(path, p)
|
|
})
|
|
}
|
|
}
|
|
}
|
|
}
|