iT邦幫忙

0

[JS]使用babel 轉譯 ES7 的 Async function(適用於瀏覽器)--3(完)

本篇主旨:透過babel轉譯使用Async function的js檔,使其可在瀏覽器(非Node環境)運行
上篇

閱前注意:

本篇為個人使用筆記,為供未來使用,會包含一些瑣碎的設定
新手發文,還請多多包涵並給予指教
流程為個人嘗試以及思考的脈絡,未必是最佳化的流程

Step0 思考

既然babel透過@babel/plugin-transform-runtime這個plugin轉譯後的js會使用require來引入額外的function,我們退回到在第0章Step4轉譯出regeneratorRuntime卻找不到的階段,試圖用其他方法找出該如何使用regeneratorRuntime

Solution0 npm!

歷經幾番周折,查閱google與npm,發現不只我也這個疑問,故有大神將regeneratorRuntime抽出來作為套件發佈在npm上,他所提供的用法為:

// CommonJS
require("regenerator-runtime/runtime");
 
// ECMAScript 2015
import "regenerator-runtime/runtime.js";

然而我們的目的是不用require/import的狀況下使用regeneratorRuntime,所以我們把透過npm載下來的runtime.js以一般的js引入index.html

<!--大神的套件-->
<script src="./node_modules/regenerator-runtime/runtime.js" defer></script>
<!--babel轉譯後包含async function的js-->
<script src="./dist/index.js" defer></script>

成功拉!

我在async function中寫了一個fetch function取得資料並輸出至console,在經歷以上操作後,終於在console中見到廬山真面目!
succ1
然而事情並沒有那麼簡單,這個套件雖然解決了在轉譯後的文件require/import的問題,然而,這個套件本身適用於ES6的環境,也就是說,在不支援ES6的瀏覽器中既使引入該套件,亦無法正常執行,只能說這是允許在ES6環境時的一個解決方案。

Solution1 Webpack

第二個思路是將regeneratorRuntime注入轉譯後的js,有些朋友或許能心有靈犀的想到Webpack專門恰好在此,礙於篇幅,我們略過webpack的基本環境建置。

以下為webpack的基本環境建置後的步驟:

  1. 安裝babel-loader-讓webpack在打包js時先透過babel轉譯,.babelrc已在前面設定過
  2. 編輯webpack.config.js
var path = require("path");

module.exports = {
  entry: {
    //為index.js注入包含regeneratorRuntime的polyfill
    index: ["@babel/polyfill",path.resolve(__dirname, "src/index.js")]
  },
  output: {
    path: path.join(__dirname, "dist"),
    filename: "[name].js",
  },
  module: {
    rules: [
      {
        //透過babel轉譯js檔
        test: /\.js$/,
        loaders: ["babel-loader"],
        include: path.join(__dirname, "src"),
      },
    ],
  }
};
  1. 執行webpack
npx webpack

成功拉!

完成上述步驟後便可以得到dist/index.js,可以正常運行於瀏覽器啦!

Summary

經歷一番周折,今天總結出:

  1. 太新的js特性(async等)透過babel轉譯後未必能直接使用
  2. 官方為補足新特性所提供的解決方案適用於CommonJS環境(會使用require),不適用於瀏覽器
  3. Webpack方案雖可以解決所有問題,同時衍伸出問題
    1. @babel/core作為依賴注入js,造成轉譯後的檔案十分肥大(包含regeneratorRuntime以外的功能都會注入)
    2. 若多個檔案都需要參考到@babel/core建議將@babel/core單獨輸出成一個js,在需要他的js前引入他
  4. 今天就研究這麼多吧!希望有觀眾有更好的解決方案,大家一起進步吧!

尚未有邦友留言

立即登入留言