Babel 是什么?
Babel 是一個(gè) JavaScript 編譯器
Babel 是一個(gè)工具鏈,主要用于將采用 ECMAScript 2015+ 語法編寫的代碼轉(zhuǎn)換為向后兼容的 JavaScript 語法,以便能夠運(yùn)行在當(dāng)前和舊版本的瀏覽器或其他環(huán)境中。下面列出的是 Babel 能為你做的事情:
- 語法轉(zhuǎn)換
- 通過 Polyfill 方式在目標(biāo)環(huán)境中添加缺失的特性(通過第三方 polyfill 模塊仙逻,例如 core-js,實(shí)現(xiàn))
- 源碼轉(zhuǎn)換 (codemods)
配置 Babel
.babelrc和babel.config.js 都是Babel的配置文件
babel 7.x 以上開始支持兩種類型的配置文件, 分別是.babelrc 和 babel.config.js
babel.config.js
是在babel第7版引入的肋坚,主要是為了解決babel6中的一些問題
- .babelrc會(huì)在一些情況下项棠,莫名地應(yīng)用在node_modules中
- .babelrc的配置不能應(yīng)用在使用符號(hào)鏈接引用進(jìn)來的文件
- 在node_modules中的.babelrc會(huì)被檢測到,即使它們中的插件和預(yù)設(shè)通常沒有安裝蚀浆,也可能在Babel編譯文件的版本中無效
并且支持的文件擴(kuò)展名:
Babel 可以使用 Node.js 原生支持的任何文件擴(kuò)展名進(jìn)行配置:您可以使用.json缀程、 .js、.cjs和.mjs市俊, forbabel.config.json和.babelrc.jsonfiles
杨凑。
推薦使用場景:
- babel.config.json
- 你正在使用一個(gè)monorepo(可以理解為在一個(gè)項(xiàng)目中會(huì)有多個(gè)子工程)
- 你希望編譯node_modules以及symobllinked-project中的代碼
*.babelrc - 你的配置僅適用于項(xiàng)目的單個(gè)部分
- 需要在子目錄/文件中運(yùn)行一些特定的轉(zhuǎn)換,比如你可能不希望一些第三方庫被轉(zhuǎn)碼
- 綜合推薦使用babel.config.json摆昧,Babel itself is using it
配置文件 .babelrc
使用 Babel 第一步就是配置此文件撩满,放在項(xiàng)目根目錄,此文件用于配置轉(zhuǎn)碼規(guī)則和插件绅你,基本格式:
{
"presets":[],
"plugins":[]
}
預(yù)設(shè)(Presets)
Babel 的預(yù)設(shè)(preset)可以被看作是一組 Babel 插件和/或 options
配置的可共享模塊伺帘。
創(chuàng)建預(yù)設(shè)
如需創(chuàng)建一個(gè)自己的預(yù)設(shè)(無論是為了本地使用還是發(fā)布到 npm),需要導(dǎo)出(export)一個(gè)配置對(duì)象
可以是返回一個(gè)插件數(shù)組...
module.exports = function() {
return {
plugins: ["pluginA", "pluginB", "pluginC"],
};
};
preset 可以包含其他的 preset忌锯,以及帶有參數(shù)的插件伪嫁。
module.exports = () => ({
presets: [require("@babel/preset-env")],
plugins: [
[require("@babel/plugin-proposal-class-properties"), { loose: true }],
require("@babel/plugin-proposal-object-rest-spread"),
],
});
預(yù)設(shè)的排列順序
Preset 是逆序排列的(從后往前)。
{
"presets": ["a", "b", "c"]
}
將按如下順序執(zhí)行: c偶垮、b 然后是 a张咳。
這主要是為了確保向后兼容,由于大多數(shù)用戶將 "es2015" 放在 "stage-0" 之前似舵。
預(yù)設(shè)的參數(shù)
插件和 preset 都可以接受參數(shù)脚猾,參數(shù)由插件名和參數(shù)對(duì)象組成一個(gè)數(shù)組,可以在配置文件中設(shè)置砚哗。
如果不指定參數(shù)龙助,下面這幾種形式都是一樣的:
{
"presets": [
"presetA", // bare string
["presetA"], // wrapped in array
["presetA", {}] // 2nd argument is an empty options object
]
}
要指定參數(shù),請(qǐng)傳遞一個(gè)以參數(shù)名作為鍵(key)的對(duì)象频祝。
{
"presets": [
[
"@babel/preset-env",
{
"loose": true,
"modules": false
}
]
]
}
插件(plugins)
Babel 的代碼轉(zhuǎn)換是通過將插件(或預(yù)設(shè))應(yīng)用到您的配置文件來啟用的泌参。
使用插件
如果插件在npm 上,你可以傳入插件的名稱常空,Babel 會(huì)檢查它是否安裝在node_modules
. 這被添加到plugins配置選項(xiàng)沽一,它采用一個(gè)數(shù)組。
{
"plugins": ["babel-plugin-myPlugin", "@babel/plugin-transform-runtime"]
}
您還可以指定插件的相對(duì)/絕對(duì)路徑漓糙。
{
"plugins": ["./node_modules/asdf/plugin"]
}
插件順序
這意味著如果兩個(gè)轉(zhuǎn)換插件都將處理“程序(Program)”的某個(gè)代碼片段铣缠,則將根據(jù)轉(zhuǎn)換插件或 預(yù)設(shè)(preset) 的排列順序依次執(zhí)行。
- 插件在 預(yù)設(shè)(preset) 前運(yùn)行。
- 插件順序從前往后排列蝗蛙。
{
"plugins": ["transform-decorators-legacy", "transform-class-properties"]
}
先執(zhí)行 transform-decorators-legacy 蝇庭,在執(zhí)行 transform-class-properties
** 插件參數(shù)**
參數(shù)由插件名和參數(shù)對(duì)象組成一個(gè)數(shù)組,可以在配置文件中設(shè)置捡硅。
如果不指定參數(shù)哮内,下面這幾種形式都是一樣的:
{
"plugins": ["pluginA", ["pluginA"], ["pluginA", {}]]
}
要指定參數(shù),請(qǐng)傳遞一個(gè)以參數(shù)名作為鍵(key)的對(duì)象壮韭。
{
"plugins": [
[
"transform-async-to-module-method",
{
"module": "bluebird",
"method": "coroutine"
}
]
]
}
補(bǔ)充
1.語法轉(zhuǎn)譯器
@babel/preset-env
轉(zhuǎn)譯包
主要對(duì) JavaScript 最新的語法糖進(jìn)行編譯北发,并不負(fù)責(zé)轉(zhuǎn)譯新增的 API 和全局對(duì)象。
而 Promise,Iterator,Generator,Set,Maps,Proxy,Symbol 等全局對(duì)象喷屋,以及一些定義在全局對(duì)象的方法(比如 includes/Object.assign 等)并不能被編譯琳拨。
官方推薦使用,包含了所有現(xiàn)代js(es2015 es2016等)的所有新特性屯曹,你也可以傳遞一些配置給env狱庇,精準(zhǔn)實(shí)現(xiàn)你想要的編譯效果。
{
"presets": [
[
"@babel/preset-env",
{
"useBuiltIns": "entry"
}
]
]
}
參數(shù):
-
targets https://www.babeljs.cn/docs/babel-preset-env#targets
string | Array<string> | { [string]: string },targets如果在@babel/preset-env的文檔中沒有指定與瀏覽器列表相關(guān)的選項(xiàng)恶耽,則默認(rèn)為頂級(jí)選項(xiàng)密任,否則為{}
描述您的項(xiàng)目支持/目標(biāo)的環(huán)境。
{
"targets": "> 0.25%, not dead"
}
-
modules
"amd" | "umd" | "systemjs" | "commonjs" | "cjs" | "auto" | false偷俭,默認(rèn)為"auto"批什。
啟用 ES 模塊語法到另一種模塊類型的轉(zhuǎn)換。請(qǐng)注意社搅,這cjs
只是commonjs
.
將此設(shè)置為false
將保留 ES 模塊。僅當(dāng)您打算將本機(jī) ES 模塊發(fā)送到瀏覽器時(shí)才使用此選項(xiàng)乳规。如果您在 Babel 中使用捆綁器形葬,modules: "auto"
則始終首選默認(rèn)值。
include
Array<string|RegExp>暮的,默認(rèn)為[]
始終包含的一系列插件笙以。exclude
Array<string|RegExp>,默認(rèn)為[]冻辩。
要始終排除/刪除的一系列插件猖腕。useBuiltIns
"usage"| "entry"| false,默認(rèn)為false恨闪。
此選項(xiàng)配置如何@babel/preset-env處理 polyfill倘感。
當(dāng)使用usage
或entry
選項(xiàng)時(shí),@babel/preset-env
會(huì)將對(duì)core-js
模塊的直接引用添加as bare imports (or requires)咙咽。這意味著core-js
將相對(duì)于文件本身進(jìn)行解析并且需要可訪問老玛。
由于@babel/polyfill
已在 7.4.0 中棄用,我們建議直接core-js
通過corejs
選項(xiàng)添加和設(shè)置版本。
corejs
string或{ version: string, proposals: boolean }蜡豹,默認(rèn)為"2.0"麸粮。該version字符串可以是任何受支持的core-js版本。例如镜廉,"3.8"或"2.0"弄诲。configPath
string
, 默認(rèn)為process.cwd()
開始對(duì) browserslist 進(jìn)行配置搜索的起點(diǎn),并上升到系統(tǒng)根目錄直到找到娇唯。
2.API 和全局對(duì)象轉(zhuǎn)譯器
負(fù)責(zé)轉(zhuǎn)譯新增的 API 和全局對(duì)象齐遵,保證在瀏覽器的兼容性。比如Promise,Iterator,Generator,Set,Maps,Proxy,Symbol 等全局對(duì)象视乐,以及一些定義在全局對(duì)象的方法(比如 includes/Object.assign 等)具體可查詢https://github.com/babel/babel/blob/master/packages/babel-plugin-transform-runtime/src/definitions.js
babel polyfill
相當(dāng)于一個(gè)墊片洛搀,可以轉(zhuǎn)譯所有 ES6 API 和全局對(duì)象。
缺點(diǎn):增加包體佑淀,比如僅是使用到一種 ES6 新增 API留美,他也會(huì)增加所有的轉(zhuǎn)移語法。
3.jsx,flow,TypeScript 等插件轉(zhuǎn)譯器
@babel/preset-react
當(dāng)你使用 react 項(xiàng)目時(shí)伸刃,需要使用此包配合轉(zhuǎn)譯
安裝:npm install --save-dev @babel/preset-react
引用:在 .babelrc 中添加配置
"presets": ["@babel/preset-react"]
@babel/preset-typescript
當(dāng)你項(xiàng)目是用 TypeScript 編寫時(shí)谎砾,需要使用此包配合轉(zhuǎn)譯
安裝:npm install --save-dev @babel/preset-typescript
引用:在 .babelrc 中添加配置
"presets": ["@babel/preset-typescript"]
參考:
https://www.babeljs.cn/docs/configuration
https://blog.csdn.net/weixin_45151873/article/details/118572216
https://zhuanlan.zhihu.com/p/84083454