You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							285 lines
						
					
					
						
							9.2 KiB
						
					
					
				
			
		
		
	
	
							285 lines
						
					
					
						
							9.2 KiB
						
					
					
				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') | 
						|
 | 
						|
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 getModernTargets (targets) { | 
						|
  const allModernTargets = getTargets( | 
						|
    { esmodules: true }, | 
						|
    { ignoreBrowserslistConfig: true } | 
						|
  ) | 
						|
 | 
						|
  // use the intersection of modern mode browsers and user defined targets config | 
						|
  const result = getIntersectionTargets(targets, allModernTargets) | 
						|
 | 
						|
  // webpack 4 uses acorn 6, which does not support newer syntaxes such as optional chaining | 
						|
  // so we have to add samsung 12 as a target to force transpiling these syntaxes | 
						|
  // https://github.com/vuejs/vue-cli/issues/6449#issuecomment-828559068 | 
						|
  result.samsung = '12.0.0' | 
						|
 | 
						|
  return result | 
						|
} | 
						|
 | 
						|
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/runtime@7.0.0-beta.0 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 = getModernTargets(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
 | 
						|
 |