Babel介绍
Babel介紹
什么是Babel?
Babel是一套主要用來(lái)將使用ECMAScript2015+語(yǔ)法編寫的代碼轉(zhuǎn)換成純ES5的Javascript代碼的工具,以兼容任何老式瀏覽器與運(yùn)行環(huán)境。
Babel可以做什么?
Babel可以用來(lái)編譯ES6+的語(yǔ)法,它使所有ES6+規(guī)范新增的語(yǔ)法糖都可用,包括:類(class),箭頭函數(shù)(arrow function),多行字符串等等。它的功能包括但不限于:
1.Javascript語(yǔ)法轉(zhuǎn)換;
2.使用ployfill特性使你的瀏覽器兼容各類全局web api(例如:promise,async await);
3.源代碼轉(zhuǎn)換;
Babel代碼轉(zhuǎn)換流程
@babel/core作為Babel的核心包,主要負(fù)責(zé)代碼的轉(zhuǎn)換工作。其內(nèi)部使用了@babel/parser,@babel/traverse,@babel/generator三個(gè)工具來(lái)負(fù)責(zé)代碼的轉(zhuǎn)譯過程。
parser:內(nèi)部依賴acorn和acorn-jsx,將js代碼解析為抽象語(yǔ)法樹;
traverse:修改parser解析后的抽象語(yǔ)法樹;
generator:解析traverse編輯后的抽象語(yǔ)法樹,生成對(duì)應(yīng)的es5語(yǔ)法;
Babel的代碼轉(zhuǎn)換其實(shí)是一個(gè)線性的流程,依次經(jīng)歷解析,轉(zhuǎn)換,生成三個(gè)階段。
Plugins和Presets
Plugin是Babel提供的用來(lái)幫助代碼轉(zhuǎn)換的工具,它主要在抽象語(yǔ)法樹的轉(zhuǎn)換階段發(fā)揮作用,也就是traverse階段。如果我們不使用任何plugins,源代碼經(jīng)過babel編譯后會(huì)原樣輸出(不會(huì)保留原有代碼格式)。Plugin則會(huì)告知babel如何轉(zhuǎn)換我們的代碼。
Babel提供了很多的plugins用來(lái)轉(zhuǎn)換代碼,其細(xì)粒度精確到每一種ECMAScript2015+語(yǔ)法,例如@babel/plugin-transform-arrow-functions負(fù)責(zé)轉(zhuǎn)換箭頭函數(shù),@babel/plugin-proposal-object-rest-spread用來(lái)轉(zhuǎn)換對(duì)象擴(kuò)展運(yùn)算符。同時(shí)babel的plugin還做了對(duì)框架語(yǔ)法的兼容,比如對(duì)react的jsx的轉(zhuǎn)換。我們可以根據(jù)項(xiàng)目需求自行選定不同的插件。
上面提到了babel的plugins,plugins雖然功能豐富,但是es5+新出的語(yǔ)法還是比較多的,如果一個(gè)一個(gè)安裝的話未免太麻煩,幸好babel提供了另外一種工具——presets。
如果把一個(gè)plugin比作一種工具,則presets則是工具箱。Presets是一組plugins的集合,用來(lái)轉(zhuǎn)換一類語(yǔ)法。在實(shí)際項(xiàng)目中最常用preset便是@babel/preset-env了,它非常聰明可以幫助我們轉(zhuǎn)換所有最新的Ecmascirpt標(biāo)準(zhǔn)語(yǔ)法。因此再也不需要去根據(jù)項(xiàng)目中使用到的語(yǔ)法而一個(gè)一個(gè)的安裝插件,非常方便并且可以減小打包體積。
Polyfill
筆者曾經(jīng)在開發(fā)的時(shí)候遇到過一個(gè)問題,webpack和babel都已經(jīng)配置好,并且項(xiàng)目也可以在chrome中正常運(yùn)行,但是在ie瀏覽器中卻一直報(bào)錯(cuò)。找了一圈后來(lái)發(fā)現(xiàn)是項(xiàng)目中使用promise和async await的問題。于是我回頭看了項(xiàng)目?jī)?nèi)babel配置,該用的插件也都用了,那么問題到底出在哪里呢?后來(lái)回顧了一個(gè)babel文檔,才發(fā)現(xiàn)promise和async并不屬于ES規(guī)范語(yǔ)法,而是全局api。
Polyfill就是babel提供的可以幫助我們兼容這些內(nèi)建api的工具。這意味著您可以使用新的內(nèi)置函數(shù)(例如Promise或WeakMap),靜態(tài)方法(例如Array.from或Object.assign),實(shí)例方法(例如Array.prototype.includes)和生成器函數(shù)(前提是您使用了regenerator插件)。 為了做到這一點(diǎn),polyfill將諸如String之類的本地原型添加到了全局范圍。
Babel常用配置
Babel的配置可以說是非常簡(jiǎn)單了。Babel官方提供了兩種配置文件以供選擇:
babel.config.js: 使用編程的方式來(lái)進(jìn)行配置;
module.exports = function (api) {
api.cache(true);
const presets = [ ... ];
const plugins = [ ... ];
return {
presets,
plugins
};
.babelrc:靜態(tài)配置,僅適用于單個(gè)程序包;
{
"presets": [...],
"plugins": [...]
}
如果項(xiàng)目中使用了webpack,則需要在webpack配置文件內(nèi)配置babel-loader以啟用babel配置
//webpack.config.js
module: {
rules: [
{
test: /.js$/,
exclude: /node_modules/,
loader: 'babel-loader',
}
]
},
//.babelrc
{
"presets": [
["@babel/preset-env"],
["@babel/preset-react"]
]
}
或者
//webpack.config.js
module: {
rules: [
{
test: /.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env', "@babel/preset-react"],
}
}
}
]
},
(此種配置方式無(wú)需配置babel配置文件)
如果項(xiàng)目中需要用到polyfill,可以將其在項(xiàng)目入口文件頂部引入或者加入到webpack配置文件的入口配置:
//index.js
require('@babel/polyfill');
or
import '@babel/poltfill';
//webpack.config.js entry: ['@babel/polyfill', './index.js'],
注意在babel7.4.0之后的版本polyfill將會(huì)被棄用,建議您直接使用polyfill包含的core-js/stable和regenerator-runtime/runtime。
//index.js import "core-js/stable"; import "regenerator-runtime/runtime";
如果您覺得直接引入core-js會(huì)增大打包體積,也可以使用按需引入的方式:
//index.js import 'core-js/features/promise'; import 'core-js/features/array/from';
總結(jié)
- 上一篇: 北京公积金怎么提取出来 住房公积金怎么提
- 下一篇: 3DMAX怎么自定义设置场景撤销个数(s