babel 的介紹及其配置
vue/cli -- babel
Babel 是一個工具鏈,主要用於將 ECMAScript 2015+ 版本的程式碼轉換為向後相容的 JavaScript 語法,以便能夠執行在當前和舊版本的瀏覽器或其他環境中。
1. babel的作用
- 語法轉換
- 通過 Polyfill 方式在目標環境中新增缺失的特性
- 原始碼轉換 (codemods)
為什麼要用babel轉換程式碼呢:
@babel/polyfill
例:如果我們要使用Array.prototype.find()
,但是某個版本的瀏覽器不支援此方法,我們可以通過babel引入相關的Polyfill檔案就可以了
注:Polyfill 是一塊程式碼(通常是 Web 上的 JavaScript),用來為舊瀏覽器提供它沒有原生支援的較新的功能。
@babel/preset-env
例:
1//箭頭函式
2letFn=()=>{
3//
4}
因為一些瀏覽器根本就不識別這些程式碼,這時候就需要把這些程式碼轉換成瀏覽器識別的程式碼。 babel就是做這個事情的。
2. babel的工作原理
Code => AST => new AST => new Code
為了轉換我們的程式碼, babel做了三件事:
- Parser:解析我們的程式碼轉換為 AST。(@babel/parser)
- Transformer:利用我們配置好的 plugins/presets把 Parser生成的 AST轉變為新的 AST。(@babel/preset-*)
- Generator:把轉換後的 AST生成新的程式碼(@babel/generator)
從圖上看 Transformer佔了很大一塊比重,這個轉換過程就是 babel中最複雜的部分,我們平時配置的 plugins/presets就是在這個模組起作用。
*注:抽象語法樹(AST)Abstract Syntax Tree是javascript的最底層結構,babel通過操作AST實現對原始碼的修改,可以通過recast外掛檢視AST的結構
3. babel的使用
- 正常我們需要安裝以下依賴
1npminstall--save-dev@babel/core@babel/cli@babel/preset-env
2 npminstall--save@babel/polyfill
- 建立一個名為config的配置檔案
1module.exports={
2presets:[
3[
4require('@babel/preset-env'),
5{
6targets:{
7edge:"17",
8firefox:"60",
9chrome:"67",
10safari:"11.1",
11},
12useBuiltIns:'usage'
13},
14],
15],
16//上面的瀏覽器列表只是一個任意示例。您將不得不對其進行調整以適合您要支援的瀏覽器。
17plugins:[
18//
19]
20}
- 執行此命令,將src目錄中的所有程式碼編譯為lib
1./node_modules/.bin/babelsrc--out-dirlib
@babel/cli
Babel帶有內建CLI,可用於從命令列編譯檔案。
@babel/core
@babel/core
包括了整個babel工作流,也就是說在@babel/core
裡面我們會使用到@babel/parser
、transformer[s]
、以及@babel/generator
。
所有的transformations都會使用babel.config.js檔案
@babel/parser
@babel/parser
的作用是將原始碼解析成 AST ,方便各個外掛分析語法進行相應的處理。
@babel/generator
@babel/generator
將修正後的AST解碼生成js程式碼。
@babel/preset-env
@babel/preset-env
是一個智慧預設,可讓您使用最新的JavaScript,轉化最新語法如箭頭函式, class, 擴充套件運算子,想要轉換最新的api還需引入@babel/polyfill
@babel/preset-env接受您指定的任何目標環境,並根據其對映檢查它們,以編譯外掛列表,並將其傳遞給Babel。
預設情況下,除非設定了target或ignoreBrowserslistConfig選項,@babel/preset-env
將使用browserslist配置源
browserslist配置源從以下位置讀取:
- package.json檔案中的browserslist欄位
- .browserslistrc配置檔案
- browserslist.config.js 配置檔案
- 執行環境變數BROWSERSLIST
- 預設如下
1"browserslist":[
2"defaults"
3]
4//defaults=>>0.5%,last2versions,FirefoxESR,notdead
useBuiltIns:
- 此選項配置如何@babel/preset-env處理polyfill
- 'usage':支援按需引入,優化了core-js匯入
@babel/polyfill
babel只負責語法轉換,比如將ES6的語法轉換成ES5。但如果有些物件、方法,瀏覽器本身不支援,比如:
- 全域性物件:Promise、WeakMap 等。
- 全域性靜態函式:Array.from、Object.assign 等。
- 例項方法:比如 Array.prototype.includes 等。
此時,需要引入@babel/polyfill
來模擬實現這些物件、方法。需要安裝在生產依賴中
3. @vue/cli中的babel
我們從package.json入手
1"dependencies":{
2"axios":"^0.19.1",
3"core-js":"^3.4.4",
4"vue":"^2.6.10",
5"vue-meta":"^2.3.2",
6"vue-router":"^3.1.3",
7"vuex":"^3.1.2"
8},
9"devDependencies":{
10"@vue/cli-plugin-babel":"^4.1.0",
11"@vue/cli-plugin-eslint":"^4.1.0",
12"@vue/cli-plugin-unit-jest":"^4.1.0",
13"@vue/cli-service":"^4.1.0",
14"@vue/eslint-config-standard":"^4.0.0",
15"@vue/test-utils":"1.0.0-beta.29",
16"babel-eslint":"^10.0.3",
17"babel-plugin-import":"^1.13.0",
18"eslint":"^5.16.0",
19"eslint-plugin-vue":"^5.0.0",
20"image-webpack-loader":"^6.0.0",
21}
core-js
由於自
@babel/polyfill7.4.0
起已棄用,可以直接新增core-js和設定版本。在@vue/cli
專案中,只安裝了core-jscore-js是我們能夠使用新的API的最重要的包,然而一般情況它隱藏在webpack編譯後的程式碼中,我們一般不會去檢視
- 它是JavaScript標準庫的polyfill
- 最新的 ECMAScript 標準
- ECMAScript 標準庫提案
- 一些 WHATGW / W3C 標準(跨平臺或者 ECMAScript 相關)
- 它儘可能的進行模組化,讓你能選擇你需要的功能
- 它可以不汙染全域性空間
- 它和babel高度整合,可以對core-js的引入進行最大程度的優化
@vue/cli-plugin-babel
這就是vue-cli特有的babel外掛,其中包括babel7
,babel-loader
,@vue/babel-preset-app
其中也載入了@babel/core
工作流,檢視./node_modules/@vue/babel-preset-app
,其中配置了:
1presets:[
2[require('@babel/preset-env'),{
3useBuiltIns,
4corejs:3
5}]
6]
babel-loader
則是webpack配置的前處理器
babel-plugin-import
babel-plugin-import
是一款 babel 外掛,它會在編譯過程中將 import 的寫法自動轉換為按需引入的方式
例:vant
1plugins:[
2['import',{
3libraryName:'vant',
4libraryDirectory:'es',
5style:true
6},'vant']
7]
babel-eslint
ESLint 預設使用Espree作為其解析器,你可以在配置檔案中指定一個不同的解析器
ESLint不支援Babel支援的某些語法節點。使用babel-eslint
時,將對ESLint進行修補,並將您的程式碼轉換為ESLint可以理解的程式碼。相關配置
.eslintrc.js中:
1parserOptions:{
2parser:'babel-eslint'
3}