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// 箭頭函數
2let Fn = () => {
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的使用
- 正常我們需要安裝以下依賴
1npm install --save-dev @babel/core @babel/cli @babel/preset-env
2npm install --save @babel/polyfill
- 創建一個名為config的配置文件
1module.exports = {
2 presets: [
3 [
4 require('@babel/preset-env'),
5 {
6 targets: {
7 edge: "17",
8 firefox: "60",
9 chrome: "67",
10 safari: "11.1",
11 },
12 useBuiltIns: 'usage'
13 },
14 ],
15 ],
16 // 上面的瀏覽器列表只是一個任意示例。您將不得不對其進行調整以適合您要支持的瀏覽器。
17 plugins: [
18 //
19 ]
20}
- 運行此命令,將src目錄中的所有代碼編譯為lib
1./node_modules/.bin/babel src --out-dir lib
@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%, last 2 versions, Firefox ESR, not dead
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'), {
3 useBuiltIns,
4 corejs: 3
5 }]
6]
babel-loader則是webpack配置的預處理器
babel-plugin-import
babel-plugin-import是一款 babel 插件,它會在編譯過程中將 import 的寫法自動轉換為按需引入的方式
例:vant
1plugins: [
2 ['import', {
3 libraryName: 'vant',
4 libraryDirectory: 'es',
5 style: true
6 }, 'vant']
7]
babel-eslint
ESLint 默認使用Espree作為其解析器,你可以在配置文件中指定一個不同的解析器
ESLint不支持Babel支持的某些語法節點。使用babel-eslint時,將對ESLint進行修補,並將您的代碼轉換為ESLint可以理解的代碼。相關配置
.eslintrc.js中:
1parserOptions: {
2 parser: 'babel-eslint'
3}
