什麼是 babel-polyfill
透過 babel 將新版 JS 做相容性降轉時會產生問題,在降轉後的語法可能會有 ie 或是特別的瀏覽器上產生不支援的情形,解決這個問題可以透過 babel-polyfill 來做處理。
如果專案中不需要處理到舊版瀏覽器或是 ie,就可以不用掛載 babel-polyfill。
shim.js & polyfill.js 針對舊瀏覽器相關資料:
- Shim:shim 是一個庫,這個庫中的方法接收的參數與調用方法與標準的方法一樣,但是shim中的方法是自己實現邏輯處理的,因此在方法中加入了兼容性處理。所以方法的返回結果與標準方法相同。
- polyfill:指的是符合 shim 標準的 API。polyfill API 使用老方法來實現新功能,從而保證在低級瀏覽器中也能使用比較新的方法。例如:使用 ES5 中的方法來實現 ES6 中特定的方法,從而在原本不支持 ES6 的瀏覽器也能夠使用 ES6 中新增的特定方法。
polyfill 下的相關套件還不少,以幾個部份對應使用,如果有特定使用的方式不用整包 babel-polyfill 引入使用,可以取用特定的部份對應使用。
- es5-shim.js/es5-shim-min.js:低級的瀏覽器支持 ES5 中的一些特性。注意:由於 es5-shim.js 使用的是 EMCScript 的原生方法來實現的,因此必須放在所有外部導入js文件的最上面。
- es6-shim.js/es6-shim-min.js:可以讓一些低級的瀏覽器支持 ES6 中的一些特性。
- require(‘es6-promise’).polyfill();:polyfill() 方法能夠在全局範圍內處理 promise 方法。每當 promise 方法被調用,polyfill() 方法就會自動修改為在低版本瀏覽器中也能處理的語法。
資料來源:從shim & polyfill談瀏覽器兼容性、讀書筆記 —-《CSS揭秘》>> 6. shim和polyfill
安裝與設定 babel-polyfill
安裝 babel-polyfill
終端機下指令如下。
1 | npm install --save @babel/polyfill |
npm 指令安裝記錄套件參數 –save 與 –save-dev 的差別
--save-dev:開發用的套件與插件
原先透過 npm 指令參數 --save-dev 所安裝進 package.json 檔的記錄,都會記在 "devDependencies": {} 裡面,這部份主要是針對開發用的套件與插件。
--save:專案上線時會使用到的 plugin 插件
使用 --save 指令,會在 package.json 檔記錄到 "dependencies": {},這個記錄部份是專案上線時會使用到的 plugin 插件。
babel-polyfill 使用方式
直接在 JS 的 entry 注入點 index.js 加入使用。
1 | import '@babel/polyfill'; // 講義寫法 |
透過注入點引入使用後,就可以直接將 babel-polyfill 戴入到打包中的 JS 裡。
webpack 使用 babel-polyfill
安裝與使用 axios
這裡要先使用 axios 的套件,主要是要針對 axios 在瀏覽器相容性降轉處理,以早期的 IE 也要在處理降轉,不然無法使用 axios 套件。
為了讓舊的瀏覽器或是不支援 JS ES6 的 AJAX 語法,透過 polyfill 達到相容來使用。
如果不想使用 webpack 引入 可使用線上 CDN 的方式在 axios 套件執行前先戴入
1 <script src="https://cdn.jsdelivr.net/npm/promise-polyfill@8/dist/polyfill.min.js"></script>基本上現在新版的主流瀏覽器,都有支援 AJAX promise,除非過舊的瀏覽器可建議不加載 babel-polyfill 進模組,直接就可使用 axios 來處理 AJAX。
安裝 axios 套件,這裡是使用 --save 會直接記錄到 package.json 檔中的 "dependencies": {} 裡面。
1 | npm i axios -S |
IE 11 實際使用 babel-polyfill 與 axios 相容性處理
引入 axios 模組方式
在 index.js 注入點 import '@babel/polyfill'; 的後方加入 import axios from 'axios';,要給 polyfill 產生相容性處理的環境後在去執行 axios 。
透過 axios AJAX 取得 OpenData 遠端資料
準備二個 OpenData 的 API 路徑,用來測試 IE 11 在 axios 使用 promise 相容處理的情形。
1 2 3 4 | // 台灣空氣品質 http://opendata2.epa.gov.tw/AQI.json // randomuser 產假使用者資料 https://randomuser.me/api/ |
接著在 index.js 加入以 axios 打上面 OpenData API 的 AJAX,查看 IE 11 的執行結果。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | /* axios 打 API 方式一 ---------------------------------------------------------- */ async function asyncApiRes() { console.log('async: 1'); let res1 = await axios.get('http://opendata2.epa.gov.tw/AQI.json'); console.log('async: 2'); let res2 = await axios.get('https://randomuser.me/api/'); console.log('async: 3'); console.log({ res1: res1, res2: res2, }); console.log('async: 4'); } asyncApiRes(); /* /axios 打 API 方式一 ---------------------------------------------------------- */ /* axios 打 API 方式二 ---------------------------------------------------------- */ function apiRes() { let res1 = null; let res2 = null; console.log('res: 1'); axios .get('http://opendata2.epa.gov.tw/AQI.json') .then((res) => { console.log('res: 2', res); res1 = res; }) .catch((err) => console.error(err)); axios .get('https://randomuser.me/api/') .then((res) => { console.log('res: 3', res); res2 = res; }) .catch((err) => console.error(err)); console.log({ res1, res2 }); console.log('res: 4'); } apiRes(); /* /axios 打 API 方式二 ---------------------------------------------------------- */ |
沒使用 polyfill 的 IE 11 不支援 Promise 無法使用 axios
基本上沒有使用 polyfill 的 IE 是無法正常開啟頁面讓 AJAX 取得資料,而 IE 中的錯誤會出現 'Promise' 未經定義 上面,這也是因為 IE 11 不支援 ES6 的 Promise,另外也更別說是針對 AJAX 的 async 函式,讓 Promise 執行取得的 await 行為。
使用 polyfill 的 IE 11 使用 axios 與配合 async & await 的 AJAX 差別
上面二段 axios 打 API 的差別,主要是差在 AJAX 在執行堆疊時的前後順序。
如果沒有使用 async 與 await 的 AJAX 會被放在之後才取得遠端資料,外層的 let res1 = null; 與 let res2 = null; 也都會是 null。
有使用 async 與 await 的 AJAX,會依 JS 的行數一段一段的執行下來。
由下圖就可了解上面一段由 asios 結合 ES6 的 async 與 await 使用上的差別,絘色部份使用的是 async 與 await 會依序執行,紅色是直接使用 axios 只要處理 AJAX 就會置後。