@Dale-Lin
2022-09-19T13:23:41.000000Z
字数 3032
阅读 727
Babel
babel.config.js 文件导出一个配置对象或者一个返回配置对象的函数:
module.exports = {presets: ['@babel/preset-typescript',['@babel/preset-env', { modules: false }]],plugins: ["@babel/plugin-transform-runtime"]}
导出函数接受 api 对象:
module.exports = (api) => {api.cache(true)return {presets: ["@babel/preset-env"],plugins: [['@babel/plugin-proposal-optional-chaining', { loose: false }],'@babel/plugin-transform-runtime'],env: {test: {presets: ["@babel/preset-env"],plugins: [['@babel/plugin-proposal-optional-chaining', { loose: false }],'@babel/plugin-transform-runtime','dynamic-import-node']}}}}
babel-loader 和 @babel/cli 都会读这个配置
当前使用的 babel 版本字符串
babel.config.js 的好处是每次执行都动态返回一个配置,缺点是 babel 每次执行编译都需要重新执行插件/预设的函数;
api.cache 设计用来解决这个问题
api.cache.forever()
永久缓存计算出的配置,等于 api.cache(true);
api.cache.never()
永不缓存计算出的配置,每次都会重新执行函数,等于 api.cache(false);
api.cache.using(() => process.env.NODE_ENV)
基于 NODE_ENV 缓存,每次失效会生成对应 NODE_ENV 的新缓存;
api.cache.invalidate(() => process.env.NODE_ENV)
基于 NODE_ENV 缓存,每次失效会用新配置替换旧缓存;
using 回调必须没有副作用,返回值应该是最小范围的依赖
检测 babel 环境配置的 envName,默认是 process.env.BABEL_ENV || process.env.NODE_ENV || 'development'
api.env("production")
返回 envName === "production"
api.env(["development", "test"])
返回 ["development", "test"].includes(envName)
api.env()
返回 envName
api.env(envName => envName.startsWith("test-"))
返回 envName.startsWith("test-")
api.env内部会使用api.cache来保证 babel 基于指定的 envName 来构建,所以不能和api.cache.forever()和api.cache.never()同时使用。
api.assertVersion(range)
module.exports = (api) => {api.assertVersion("^7.2")return {// ...}}
presets 是一组 babel 预设的插件,例如 @babel/preset-env / @babel/preset-typescript / @babel/preset-react
presets 的执行顺序是从后往前,所以通常 @babel/preset-env 会放在第一位。
targets 描述项目支持的运行环境:
{"targets": {"chrome": "58","ie": "11"}}
支持的环境标签有:android, chrome, edge, electron, firefox, ie, ios, node, opera, safari;
没有指定 targets 的时候,Babel 会假设需要支持最老的浏览器。
esmodules 选项表示脚本需要在支持 esmodule 规范的浏览器里运行,Babel 会和 targets 的其他环境互取交集,可以用这个来生产支持 <script type="module"></script> 的轻量级脚本。
{"esmodule": true}
继承另一个配置文件。
babel 合并配置的规则:不是 undefined 的配置项会被替换,以下除外:
assumptions, parserOpts, generatorOpts 是属性的 merge例如:
{sourceType: "script",assumptions: {setClassFields: true,iterableIsArray: false},env: {test: {sourceType: "module",assumptions: {iterableIsArray: true,},}}};
当 NODE_ENV 是 test 时的结果:
{sourceType: "module",assumptions: {setClassFields: true,interableIsArray: t rue}}
plugins, presets 会用 id + name 来识别,相同项会被覆盖例如:
plugins: ['./other',['./plug', { thing: true, field1: true }]],overrides: [{plugins: [['./plug', { thing: false }]}]
由于插件 ./plug 的 id 一致且没有指定 name,所以会被替换:
plugins: ['./other',['./plug', { thing: false }]]
id 和 name 只要有一个不同就可以同时存在:
plugins: [['./plug', { one: true }, "first-instance-name"],['./plug', { two: true }, "second-instance-name"]
一个由 envName-config 键值对组成的对象,当 envName 匹配上时会 merge 对应的配置
一个配置数组,会在某些时刻合并进当前的配置中,可以用 "test" / "include" / "exclude" 来指定合并时机:
overrides: [{test: './vendor/large.min.js',compact: true}]
当前配置生效的匹配方式,通常在 overrides 里使用
相当于 test
在匹配成功时当前配置会失效,通常在 overrides 里使用
匹配成功时会停止当前的构建过程,例如:
ignore: ["./lib"]
只有在匹配成功时才会继续构建过程,例如:
only: ['./src']
是否生成 module ID
(name: string) => string 根据 babel 生成的模块名称返回自定义的名称