[转] 以 async/await 为例,说明 babel 插件怎么搭
你一定碰到過這些庫
babel-polyfill
項目地址:https://github.com/babel/babel/blob/master/packages/babel-polyfill
通過兩個依賴實現功能
- core-js/shim?提供 ES5/6/7 標準方法的實現
- regenerate-runtime?提供 async 語法編譯后的的運行時環境(下文會專門說明)
babel-plugin-transform-runtime
項目地址:https://github.com/babel/babel/blob/master/packages/babel-plugin-transform-runtime
開發 ES6/7 新特性的庫推薦使用該插件,需要注意的是,安裝時,必須同時安裝?babel-runtime?作為依賴:
npm install --save-dev babel-plugin-transform-runtime npm install --save babel-runtime // `babel-plugin-transform-runtime` 插件本身其實是依賴于 `babel-runtime` 的,但為了適應 `npm install --production` 強烈建議添加該依賴。插件會將 es6/7 的語法轉化為 es5 兼容的格式,并提供運行時依賴。什么是運行時依賴?比如你要用 Array.from 方法,該方法的具體實現必須在代碼的執行環境中提供,這就是運行時依賴。
該插件在轉化語法時,不會污染全局環境。而?babel-polyfill?則會污染全局環境。
babel-plugin-external-helpers
項目地址:https://github.com/babel/babel/blob/master/packages/babel-plugin-external-helpers/
代碼很少,只依賴于?babel-runtime。相比較?babel-plugin-transform-runtime?會在每個模塊注入運行時代碼,該插件會將運行時代碼打包,類似封裝到一個對象下,這樣避免注入重復的代碼。
讓 async/await 跑起來
通過最簡單的一個函數:
async function foo() {return await 1 }foo().then(function(val) {console.log(val) // should output 1 })說明這些 babel 插件怎么搭配,三種方案:
方案一:regenerator
.babelrc?如下配置:
{"plugins": ["transform-runtime", "babel-plugin-transform-regenerator", "babel-plugin-transform-es2015-modules-commonjs"] }- babel-plugin-transform-regenerator 將?async/await?語法轉化成?regenerator?庫支持的語法
- transform-runtime 將運行時注入,類似:import regenerator from 'babel-runtime/regenerator'
- babel-plugin-transform-es2015-modules-commonjs 只是為了將 import 轉化為 require,便于在 node.js 模塊下執行(如果你的執行環境支持 es6 的模塊機制,則不需要該插件)。
方案二:generator
這種方式,最適合 node.js 環境,node.js 最早從 0.11 開始,便支持 generator。.babelrc?如下配置:
{"plugins": ["babel-plugin-transform-async-to-generator"] }生成的代碼,在 node.js 環境下可以直接執行,此時便不再需要 babel 提供任何有關 generator 相關的運行時環境了,直接 node.js 自帶~
方案三:babel-polyfill
.babelrc?如下配置:
{"plugins": ["babel-plugin-transform-regenerator"] }其實和前面?regenerate?一樣,去掉了?runtime?配置。編譯結束后,需要手動在結果文件的第一行加入:
require('babel-polyfill')通過?babel-polyfill?向全局注入運行時依賴。那什么時候該用?babel-polyfill?什么時候用?babel-runtime?官網給出了解釋:
This will emulate a full ES2015+ environment and is intended to be used in an application rather than a library/tool.
- 如果是應用級別的開發,可以考慮使用?babel-polyfill:大而全,支持所有的 es2015+ 特性。可以在項目入口處統一添加,也可以通過打包工具配置入口。
- 如果是開發一個庫,使用?babel-runtime,不會污染全局,而且是根據情況注入需要的運行時環境。
關于 babel-runtime 更多細節,強烈建議閱讀官方文檔:https://github.com/babel/babel/blob/master/packages/babel-plugin-transform-runtime/README.md
別忘了 externel-helpers
剛剛只是一個簡單的 foo 函數,一個文件。多個文件時,存在每個文件都注入類似?asyncToGenerator?等輔助方法,導致重復。舉例說明:
foo.js
'use strict'const bar = require('./bar')async function foo () {const val = await bar()console.log(val) }foo()bar.js
'use strict'module.exports = async function bar () {return await 'bar' }采用前文提到的?generator?方式,去編譯,會發現結果文件中,都有?_asyncToGenerator?定義。修改?.babelrc?如下:
{"plugins": ["babel-plugin-transform-async-to-generator", "babel-plugin-external-helpers"] }再編譯,_asyncToGenerator?都變成了?babelHelpers.asyncToGenerator。這樣,多個模塊之間沒有重復的代碼注入,更加干凈清爽。不過此時?babelHelpers?是未定義,仍然需要引入運行時環境:?transform-runtime,最終可以運行的配置如下:
{"plugins": ["babel-plugin-transform-async-to-generator","babel-plugin-external-helpers","transform-runtime","babel-plugin-transform-es2015-modules-commonjs"] }示例代碼見:https://github.com/sabakugaara/babel-example
本文整理自:https://github.com/sabakugaara/sabakugaara.github.io/issues/8
轉載于:https://www.cnblogs.com/chris-oil/p/10747527.html
總結
以上是生活随笔為你收集整理的[转] 以 async/await 为例,说明 babel 插件怎么搭的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: SpringBoot+webservic
- 下一篇: Kubernetes从懵圈到熟练:认证与