index.js 3.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. const path = require('path')
  2. const babel = require('@babel/core')
  3. const { isWindows } = require('@vue/cli-shared-utils')
  4. function genTranspileDepRegex (transpileDependencies) {
  5. const deps = transpileDependencies.map(dep => {
  6. if (typeof dep === 'string') {
  7. const depPath = path.join('node_modules', dep, '/')
  8. return isWindows
  9. ? depPath.replace(/\\/g, '\\\\') // double escape for windows style path
  10. : depPath
  11. } else if (dep instanceof RegExp) {
  12. return dep.source
  13. }
  14. })
  15. return deps.length ? new RegExp(deps.join('|')) : null
  16. }
  17. module.exports = (api, options) => {
  18. const useThreads = process.env.NODE_ENV === 'production' && !!options.parallel
  19. const cliServicePath = path.dirname(require.resolve('@vue/cli-service'))
  20. const transpileDepRegex = genTranspileDepRegex(options.transpileDependencies)
  21. // try to load the project babel config;
  22. // if the default preset is used,
  23. // there will be a VUE_CLI_TRANSPILE_BABEL_RUNTIME env var set.
  24. // the `filename` field is required
  25. // in case there're filename-related options like `ignore` in the user config
  26. babel.loadPartialConfigSync({ filename: api.resolve('src/main.js') })
  27. api.chainWebpack(webpackConfig => {
  28. webpackConfig.resolveLoader.modules.prepend(path.join(__dirname, 'node_modules'))
  29. const jsRule = webpackConfig.module
  30. .rule('js')
  31. .test(/\.m?jsx?$/)
  32. .exclude
  33. .add(filepath => {
  34. // always transpile js in vue files
  35. if (/\.vue\.jsx?$/.test(filepath)) {
  36. return false
  37. }
  38. // exclude dynamic entries from cli-service
  39. if (filepath.startsWith(cliServicePath)) {
  40. return true
  41. }
  42. // only include @babel/runtime when the @vue/babel-preset-app preset is used
  43. if (
  44. process.env.VUE_CLI_TRANSPILE_BABEL_RUNTIME &&
  45. filepath.includes(path.join('@babel', 'runtime'))
  46. ) {
  47. return false
  48. }
  49. // check if this is something the user explicitly wants to transpile
  50. if (transpileDepRegex && transpileDepRegex.test(filepath)) {
  51. return false
  52. }
  53. // Don't transpile node_modules
  54. return /node_modules/.test(filepath)
  55. })
  56. .end()
  57. .use('cache-loader')
  58. .loader(require.resolve('cache-loader'))
  59. .options(api.genCacheConfig('babel-loader', {
  60. '@babel/core': require('@babel/core/package.json').version,
  61. '@vue/babel-preset-app': require('@vue/babel-preset-app/package.json').version,
  62. 'babel-loader': require('babel-loader/package.json').version,
  63. modern: !!process.env.VUE_CLI_MODERN_BUILD,
  64. browserslist: api.service.pkg.browserslist
  65. }, [
  66. 'babel.config.js',
  67. '.browserslistrc'
  68. ]))
  69. .end()
  70. if (useThreads) {
  71. const threadLoaderConfig = jsRule
  72. .use('thread-loader')
  73. .loader(require.resolve('thread-loader'))
  74. if (typeof options.parallel === 'number') {
  75. threadLoaderConfig.options({ workers: options.parallel })
  76. }
  77. }
  78. jsRule
  79. .use('babel-loader')
  80. .loader(require.resolve('babel-loader'))
  81. })
  82. }