@Dale-Lin
2022-09-19T21:23:41.000000Z
字数 3032
阅读 344
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 生成的模块名称返回自定义的名称