本指南基於 babel 7
安裝
yarn add babel-loader @babel/core -D
複製程式碼
使用
{
test: /\.js$/,
loader: 'babel-loader',
include: [
path.resolve(__dirname, '../src')
]
}
複製程式碼
該配置指明瞭使用 babel 翻譯 js 檔案,但僅是這樣 babel 並不知道該如何翻譯、翻譯什麼,要讓它正真工作起來,還需要其他外掛支援。
預設
上文說到我們需要使用一些外掛,但搜尋和選擇外掛是一個很浪費時間的事,為了在短時間內解決問題,我們就需要使用預設。
預設就是指外掛(及其配置)組成的陣列,它可以包含外掛和其他預設,例如:
yourPreset.js
module.exports = function() {
return {
presets: [
require('@babel/preset-env'),
],
plugins: [
require('pluginA'),
require('pluginB')
]
}
}
複製程式碼
babel 提供幾個官方預設供使用者使用,這裡舉例講解最常用的 @babel/preset-env,除此之外還有:
@babel/preset-env
會根據你的環境配置,把 ES6+ 程式碼翻譯成環境能支援的 ES5 程式碼,所以我們只需要配置專案的目標環境,就能放心地使用新語法特性。
-
安裝
yarn add @babel/preset-env -D 複製程式碼
-
配置
{ test: /\.js$/, loader: 'babel-loader', include: [ path.resolve(__dirname, '../src') ], // +++ options: { presets: [ [ '@babel/preset-env', { targets: { chrome: '51', ie: '9' }, modules: false, useBuiltIns: 'entry', corejs: 2 } ] ] } // +++ } 複製程式碼
useBuiltIns
值不為false
時需要指明corejs
版本,否則會有警告(雖然有預設值 2)corejs: 2
表示使用@babel/preset-env/lib/polyfills/corejs2
來翻譯 / 填充程式碼
useBuiltIns
選項說明:
false
預設值,babel 不自動匯入 polyfill ,你需要手動在專案全域性環境中匯入- 缺點:每個語法都去找其對應的 polyfill 很麻煩,直接
import babel-polyfill
時同useBuiltIns: entry
- 缺點:每個語法都去找其對應的 polyfill 很麻煩,直接
entry
需要你在入口檔案import @babel/polyfill'
,它會依據環境設定,僅匯入環境不支援的 polyfill- 優點:只匯入環境不支援的 polyfill
- 缺點:需要手動匯入
@babel/polyfill
usage
當每個檔案裡用到需要 polyfill 的特性時,在檔案中新增對應的 polyfill ,可以保證每個 polyfill 只 load 一次,縮小生產包體積- 優點:只匯入需要的 polyfill 並且是自動匯入
- 缺點:實驗中的屬性
@babel/preset-env
使用起來非常方便,但遺憾的是它並不能覆蓋所有開發場景,因為它存在兩個缺點:
- 重複填充:
@babel/preset-env
會填充每一個檔案,所以 a.js / b.js 如果同時用到了 Promise,那麼翻譯後兩個檔案均存在 Promise 的填充 - 全域性汙染:
@babel/preset-env
會將Promise
翻譯成全域性變數var _Promise
如果你打包生成的是公共庫,就不能僅僅使用 @babel/preset-env
,因為你不能控制這個包的使用環境,對全域性變數的汙染或許會製造一些問題。
transform-runtime
以上兩個問題我們可以藉助外掛 @babel/plugin-transform-runtime
來解決
This is where the @babel/plugin-transform-runtime plugin comes in: all of the helpers will reference the module @babel/runtime to avoid duplication across your compiled output. The runtime will be compiled into your build.
Another purpose of this transformer is to create a sandboxed environment for your code. If you use @babel/polyfill and the built-ins it provides such as Promise, Set and Map, those will pollute the global scope. While this might be ok for an app or a command line tool, it becomes a problem if your code is a library which you intend to publish for others to use or if you can't exactly control the environment in which your code will run.
- 安裝
yarn add @babel/plugin-transform-runtime -D // 開發依賴 yarn add @babel/runtime-corejs2 // 生產依賴 複製程式碼
- 配置
{ test: /\.js$/, loader: 'babel-loader', include: [ path.resolve(__dirname, '../src') ], // +++ options: { plugins: [ [ '@babel/plugin-transform-runtime', { 'corejs': 2, 'absoluteRuntime': false, 'helpers': true, 'regenerator': true, 'useESModules': false } ] ] } // +++ } 複製程式碼
'corejs': 2
表示使用@babel/runtime-corejs2
來翻譯 / 填充程式碼,預設false
表示自己引入 polyfill
需要注意的是, @babel/plugin-transform-runtime
由於其不汙染全域性變數的特性,無法翻譯物件的例項方法,比如 Array.includes
/ Array.from
等
如何選擇
如果專案是公共庫,使用 @babel/plugin-transform-runtime
,否則使用 @babel/preset-env
常用配置
yarn add babel-loader @babel/core @babel/preset-env @babel/plugin-syntax-dynamic-import -D
複製程式碼
在 .babelrc 中配置
.babelrc 放在專案根目錄
{
test: /\.js$/,
loader: 'babel-loader',
include: [
path.resolve(__dirname, '../src')
],
options: {
cacheDirectory: true
}
}
複製程式碼
.babelrc
{
"presets": [
[
"@babel/preset-env",
{
"modules": false,
"useBuiltIns": "usage",
"targets": {
"chrome": "58"
},
"corejs": 2
}
]
],
"plugins": [
"@babel/plugin-syntax-dynamic-import"
]
}
複製程式碼
在 JS 中配置
yarn add babel-loader @babel/core @babel/plugin-transform-runtime @babel/plugin-syntax-dynamic-import -D
yarn add @babel/runtime-corejs2
複製程式碼
{
test: /\.js$/,
loader: 'babel-loader',
include: [
path.resolve(__dirname, '../src')
],
options: {
cacheDirectory: true,
presets: [
[
'@babel/preset-env',
{
modules: false,
useBuiltIns: 'usage',
targets: {
chrome: '58'
},
corejs: 2
}
]
],
plugins: [
'@babel/plugin-syntax-dynamic-import'
]
}
}
複製程式碼