babel入門和那些坑
最初的babel只是單純的ES6轉ES5工具,隨著應用範圍越來越廣,最新的babel6已經變成了一個轉譯平臺,ES6轉ES5只是其中一個外掛的功能。
線上體驗babel5
一般的大型專案都是使用webpack配置babel,這裡為了便於學習,只簡單說下如何單獨使用babel和可能遇到的坑。
安裝方式
1. 進入專案目錄,安裝babel-cli (babel6 cli) 和 babel-preset-env(外掛集合)。
npm install --save-dev babel-cli
npm install --save-dev babel-preset-env
此處的坑:
- 官方推薦將babel-cli安裝在專案中,只在全域性安裝會導致專案對環境的依賴(當然專案裡和全域性都安裝一遍也是可以的)
- babel6需要額外的轉碼外掛才能實現轉譯,單獨用babel-cli是無法轉譯的(與babel5不同)
- env只是JS語法轉譯外掛,如果你需要使用ES6的API,必須另外安裝babel-polyfill;如果你需要使用babel的API,必須另外安裝babel-core;如果你需要轉譯JSX,需要另外安裝babel-preset-react
建議:
- 專案內安裝的babel無法在命令列使用babel命令(一般都是用package.json或webpack.conf.js來配置)。如果你想體驗babel命令,可以在全域性再次安裝babel
- env是babel presets的一種,這裡推薦使用env。它能針對特定的瀏覽器環境進行按需轉碼,通過配置env的targets,babel會只編譯那些目標環境還不支援的特性。
2.專案目錄內新建名為“.babelrc”的檔案,新增以下內容,指定要使用的presets,以及相關配置
{
"presets": [
["env", {
//如果不設定 targets 屬性,babel-preset-env 和 babel-preset-latest 效果相同
"targets": {
//轉碼後支援chrome 52
"chrome" : 52,
//轉碼後支援的瀏覽器:市場份額>1%, 最新2個版本,ie版本大於8
"browsers": ["> 1%", "last 2 versions", "not ie <= 8"]
}
}]
]
}
此處的坑:
- windows7下無法右鍵新建”.babelrc”檔名,會報錯“必須輸入檔名”,可以使用sublime,webstorm等ide新建。
- 假如你使用了多個presets,請注意,presets是按照陣列的index倒序(從陣列最後一個到第一個)進行編譯。所以請寫成[“env”, “stage-2”],而不是[“stage-2”, “env” ]。
3.在專案的package.json內新增一個script,配置babel命令
"scripts": {
//轉譯單個檔案
"build": "babel script.js --out-file script-compiled.js"
//你也可以轉譯整個資料夾
//"build": "babel src --out-dir lib"
//你也可以轉譯單個檔案並實時監控變化
//"build": "babel script.js --watch --out-file script-compiled.js"
}
//假如你在全域性也安裝了babel,可以不配置package.json,在命令列手動執行babel命令即可完成轉碼
//babel script.js --out-file script-compiled.js
4.執行build命令,生成轉碼檔案
npm run build
到這裡,我們便實現了babel的簡單應用。
如果你想了解babel的更多用法,比如babel-core, babel-register,請參考 阮一峰的Babel入門教程,和 babel官方文件
babel轉換ES6是否有相容性問題?
ES6的部分特性是無法用ES5的語法實現的,babel在轉譯這些內容時會直接跳過不轉,或者直接報錯。
ES6特性 | 相容性 |
---|---|
箭頭函式 | 支援 |
類的宣告和繼承 | 部分支援,IE8不支援 |
增強的物件字面量 | 支援 |
字串模板 | 支援 |
解構 | 支援,但注意使用方式 |
引數預設值,不定引數,拓展引數 | 支援 |
let與const | 支援 |
for of | IE不支援 |
iterator, generator | 不支援 |
模組 module、Proxies、Symbol | 不支援 |
Map,Set 和 WeakMap,WeakSet | 不支援 |
Promises、Math,Number,String,Object 的新API | 不支援 |
export & import | 支援 |
生成器函式 | 不支援 |
陣列拷貝 | 支援 |
使用babel時有哪些坑?
babel6 把 import 和 export 的轉碼邏輯都做了修改,轉碼後不再兼顧 commonJS。這對於那些同時使用commonJS模組語法和es6模組語法的同學來說, 簡直就是巨坑。
1. 對export default {}的轉碼
如果希望對它的轉碼符合 commonJS,請安裝 babel-plugin-add-module-exports外掛,並在.babelrc 檔案內宣告該外掛。
在 babel5 時代, export default {} 除了會被轉譯成 exports.default = {},還會加一句 module.exports = exports.default,這是為了兼顧commonJS規範。但在 babel6 時代,後面一句不再新增,這是為了區分commonJS和ES6的模組定義。
2. 對import xxx from xxx 的轉碼
import的模組所對應的js檔案必須用export default {}匯出,或者請參照第一條安裝 babel-plugin-add-module-exports 外掛。
道理同上,babel6重新定義了對 import 的轉碼,最終的轉碼相當於 require(xxx)[‘default’],相對應的, export default {} 會被轉譯成 exports.default = {},兩者通過 default 屬性匯出和取得值,不再使用module.exports
3. 除錯
JS轉碼之後除錯很不方便,可以通過source map解決。babel本身就有該功能,可以在轉譯時生成相應的source map
babel script.js --out-file script-compiled.js --source-maps