本節配套代碼是github倉庫 https://github.com/jruit/babel-tutorial 的babel02例子
總體來說,Babel的主要工作有兩部分:
- 語法轉換
- 補齊API
上一節Babel快速入門我們講的是其實是用Babel進行語法轉換,把ES6的箭頭函數語法轉換成了ES5的函數定義語法。 箭頭函數語法、async函數語法、class定義類語法和解構賦值等等都是ES6新增的語法。
那什么是補齊API? 簡單解釋就是,通過 Polyfill 的方式在目標環境中添加缺失的特性 。
我們按照上一節的操作對var promise = Promise.resolve('ok')進行轉換,會發現轉換后的代碼並沒有改變,過程如下。
我們新建babel02文件夾,新建babel配置文件 babel.config.js ,內容如下
module.exports = {
presets: ["@babel/env"],
plugins: []
}
新建main.js文件,內容如下
var fn = (num) => num + 2;
var promise = Promise.resolve('ok')
然后執行下面的命令安裝三個npm包
// npm一次性安裝多個包,包名之間用空格隔開
npm install --save-dev @babel/cli @babel/core @babel/preset-env
然后執行命令
npx babel main.js -o compiled.js
整個過程與上一節基本一樣,只是main.js里的代碼多了一行
var promise = Promise.resolve('ok')
此時文件夾下會生成新的compiled.js,代碼如下:
"use strict";
var fn = function fn(num) {
return num + 2;
};
var promise = Promise.resolve('ok');
我們觀察轉換后生成的compiled.js代碼,發現Babel並沒有對ES6的Promise進行轉換 。
我們通過一個index.html文件引用轉碼后的 compiled.js ,在比較老的瀏覽器( 例如火狐27 )里打開HTML文件后后控制台報錯:Promise is not defined。
為何 Babel沒有對ES6的Promise進行轉換 ?
因為Babel默認只轉換新的JavaScript語法(syntax),而不轉換新的 API。
新的API分類兩類,一類是Promise、Map、Symbol、Proxy、Iterator等全局對象及其對象自身的方法,例如Object.assign,Promise.resolve;另一類是新的實例方法,例如數組實例方法[1, 4, -5, 10].find((item) => item < 0)
如果想讓ES6新的API在低版本瀏覽器正常運行,我們就不能只做語法轉換。
在前端web工程里,最常規的做法是使用polyfill,為當前環境提供一個墊片。所謂墊片,是指墊平不同瀏覽器之間差異的東西。polyfill提供了全局的ES6對象以及通過修改原型鏈Array.prototype等實現對實例的實現。
polyfill廣義上講是為環境提供不支持的特性的一類文件或庫,狹義上講是polyfill.js文件以及@babel/polyfill這個npm包。
我們可以直接在html文件引入polyfill.js文件來作為全局環境墊片, polyfill.js 有Babel官方的 polyfill.js,也有第三方的。我們引入一個Babel官方已經構建好的polyfill腳本。
簡單起見,我們通過在html里引入polyfill.js的方式。
<script src="https://cdn.bootcss.com/babel-polyfill/7.6.0/polyfill.js"></script>
我們在IE9打開驗證,也可以用Firefox27等低版本的瀏覽器驗證。這個時候發現可以正常運行了。
補齊API的方式除了通過引入 polyfill.js 文件 ,還有通過在構建工具入口文件(例如webapck),babel配置文件等方式進行。本節講的通過在HTML里直接引入 polyfill.js 文件 這種方式進行在現代前端工程里逐漸淘汰,很少使用了。但這種方式對初學者理解 polyfill 是做什么的是簡單直接的。后續章節我們會學習到其它補齊API的方式。
小結
本節講了通過 polyfill.js 文件來補齊代碼運行時環境所缺失的API。
通過上一節講的語法轉換和本節講的補齊API,就可以使一個使用ES6編寫項目完整運行了不支持ES6語言的環境上了。
注
1.可以在 https://ftp.mozilla.org/pub/firefox/releases/27.0.1/ 頁面下載對應操作系統的火狐27,如果長期使用該版本注意設置成不要自動更新,windows的話,左上角Firefox-選項-高級-更新里設置。
2.什么是API?初學編程的人看了百度百科這一類高大上的解釋會很迷惑。我們舉個簡單例子來解釋:JS里的數組有排序方法sort(),這個就是JS語言制定者給數組制定的API。引申一下,你使用了別人已經寫好的對象、類、函數或方法,那就是使用了API。
那ES6有哪些新的API呢?Promise對象,數組的Array.from()與Array.of()方法,數組實例的展平方法flat(),Object.assign()方法等等。只要是新的對象名、類名、函數名或方法名,就是ES6的新API。
博客:姜瑞濤的官方網站
原文鏈接:https://www.jiangruitao.com/babel/use-polyfill/
版權采用《署名-非商業性使用-禁止演繹 4.0 國際》許可協議 轉載需注明原文作者、鏈接與版權協議