create-react-app中的babel配置探索


版本

babel-loader version:"8.1.0"

create-react-app:"3.4.1"

三個配置

第一部分:

{
  test: /\.(js|mjs|jsx|ts|tsx)$/,
  include: paths.appSrc,
  loader: require.resolve('babel-loader'),
  options: {
    customize: require.resolve(
      'babel-preset-react-app/webpack-overrides'
    ),
    plugins: [
      [
        require.resolve('babel-plugin-named-asset-import'),
        {
          loaderMap: {
            svg: {
              ReactComponent:
                '@svgr/webpack?-svgo,+titleProp,+ref![path]',
            },
          },
        },
      ]
    ],
    cacheDirectory: true,
    cacheCompression: false,
    compact: isEnvProduction,
  },
},

第二部分

{
  test: /\.(js|mjs)$/,
  exclude: /@babel(?:\/|\\{1,2})runtime/,
  loader: require.resolve('babel-loader'),
  options: {
    babelrc: false,
    configFile: false,
    compact: false,
    presets: [
      [
        require.resolve('babel-preset-react-app/dependencies'),
        { helpers: true },
      ],
    ],
    cacheDirectory: true,
    cacheCompression: false,
    sourceMaps: shouldUseSourceMap,
    inputSourceMap: shouldUseSourceMap,
  },
},

第三部分

"babel": {
  "presets": [
    "react-app"
  ]
}

疑惑

以上三部分是babel處理代碼的配置來源,那么babel是怎么處理這些配置的?

解析

首先,看一下babel-loader中一些選項的含義:

babelrc:如果指定了選項filename,默認值為true,babel將會在項目中搜索配置文件;該配置只能在程序中配置,類似babel-loader。

[".babelrc", ".babelrc.js", ".babelrc.cjs", ".babelrc.mjs", ".babelrc.json"],以及package.json中的“babel”字段  
這幾個都是RelativeConfig

configFile:搜索指定的文件,如果沒有就是false。默認會去搜索path.resolve(opts.root, "babel.config.json"),也可以指定文件。該配置只能在程序中配置,類似babel-loader。

 ["babel.config.js", "babel.config.cjs", "babel.config.mjs", "babel.config.json"];

如果babelrc與configFile同時指定為false,babel將不會搜索配置文件,babel-loader中的選項將成為babel的配置。

在其他特定條件下,babel-loader中的options會和項目中babel配置文件中的配置相合並,類似於webpack-merge。

configFileChain // babel.config.[json,js,mjs,cjs] 里面的配置 
fileChain       // .babelrc.[js,cjs,mjs,json]里面的配置
programmaticChain // babel-loader中的配置
const chain = mergeChain(mergeChain(mergeChain(emptyChain(), configFileChain), fileChain), programmaticChain);
// 經過合並生成最后的配置
// babelrc,configFile 設置為false的時候 configFileChain  fileChain 里面的內容為空,最后的配置由babel-loader決定。

相關邏輯在node_modules/@babel/core/lib/config/config-chain.js中。

結論

所以文章開始的三個配置最后到達babel.transform的配置有兩種:

第一種,被第一個test匹配(此處使用了oneOf),同時在 include: paths.appSrc的范圍內,結果就是

  1. plugins中包含babel-plugin-named-asset-import;
  2. presets中是package.json中的babel字段的配置。

(image-20200721000026369)

第二種,主要是上一種include的漏網之魚,被exclude: /@babel(?:\/|\\{1,2})runtime/撿了起來,大多數是node_module中的文件。

presets中包含babel-preset-react-app/dependencies,主要原因是設置了babelrc和configFile為false,不再查找其他配置。

image-20200721000630848


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM