BABEL轉碼解惑


眾所周知,解決Nodejs異步問題的終極方案就是使用async/await方案,但是每次在項目中配置都會或多或少有些問題,每次都會被幾個組件

  1. babel-core
  2. babel-polyfill
  3. babel-preset-es2015
  4. babel-preset-stage-0
  5. babel-plugin-*

搞的有點混淆不清,甚至不知所措,我們的項目環境利用expressjs搭建,不同程度的使用了es6甚至es7的語法特性和新的API,所以babel轉碼

我們先看下具體的CASE

CASE

nodejs 4.4.7

Case 1

去掉 app.js 里邊的 // import 'babel-polyfill'// import 'babel-core/register'.babelrc里邊需要有plugins

{
    "presets": [
        "es2015",
        "stage-0"
    ],
    "plugins": [
        ["transform-runtime", { "regenerator": true }]
    ]
}

帶有async的代碼正常能run起來。

Case 2

去掉 app.js 里邊加上 import 'babel-polyfill',babel里邊正常

{
    "presets": [
        "es2015",
        "stage-0"
    ],
    "plugins": [
    ]
}

帶有async的代碼能正常run

import 'babel-polyfill 換成 import "babel-core/register"代碼無法run起來,報錯

nodejs v7.4.0

Case 1

app.js 中引入import 'babel-polyfill'

而 .babelrc 如下

{
    "presets": [
        "es2015",
        "stage-0"
    ]
}

代碼能正常run起來。

去掉 import 'babel-polyfill' 或者替換為 import "babel-core/register" 代碼均不能正常run

Case 2

app.js 中去掉 import 'babel-polyfill',而 .babelrc 代碼加入

{
    "presets": [
        "es2015",
        "stage-0"
    ],
    "plugins": [
        ["transform-runtime", { "regenerator": true }]
    ]
}

代碼可以正常run。

得到結論

如果需要使用async和await有兩種方式,

  1. 在程序的入口處第一行引入 import babel-polyfill.
  2. 或者使用babel轉碼的時候引入插件 ["transform-runtime", { "regenerator": true }]

往下探索

首先我們要搞清楚async和await屬於es2016(es6實際上是2015年發布的,es6常被稱為es2015,而es2016其實就是es7)的特性,Nodejs在實現標准版本的進程上相對瀏覽器側要快,截止到nodejs6.x的版本上,想要使用async和await還需要babel的轉碼才能實現。

還是看Case

例如如下代碼

const fs = require('fs')

async function readFiles (fileName) {
  return new Promise(function(resolve, reject) {
    fs.readFile(fileName, function(error, data) {
      if (error) reject(error)
      resolve(data)
    })
  })
}

const start = async function() {
  const result = await readFiles('/Users/liujb/Desktop/aa.txt')
  console.log(result.toString())
}

start()

親測在v7.4.0下報語法錯誤,在v7.7.4下能run。

關於babel


from

以上內容還是很清晰的,通過babel轉碼會默認讀取babelrc設定的規則,同時會運用相應的插件。

關於插件

babel-register and babel-polyfill

仔細閱讀阮老師的博客

babel-register是一個鈎子,會對require的js、es、jsx、es6后綴的文件進行轉碼,且不會對當前文件進行轉碼,而且是實時轉碼所以只適合開發階段。

babel-polyfill對es6的API進行轉碼,bable只會對syntax進行轉碼。

babel-plugin-*

babel-plugin-* 代表了一系列的轉碼插件,如babel-plugin-transform-es2015-arrow-functions 用於轉碼 es6 中的箭頭函數,babel-plugin-transform-async-to-generator 用於將 es7 中的 async 轉成 generator。

babel-preset-*

我們現在有了 babel-plugin 系列,可以按需配置自己想要的特性。但若是想搭個 es6 環境,一個個地配置各個插件,我猜你會瘋掉。babel-preset 系列就可以滿足我們的需求,babel-preset 系列打包了一組插件,類似於餐廳的套餐。如 babel-preset-es2015 打包了 es6 的特性,babel-preset-stage-0 打包處於 strawman 階段的語法

babel-plugin-transform-runtime

以上內容來源於https://github.com/brunoyang/blog/issues/20

小結

這一路下來,發現了不少的好文章,終於解決了自己的一些困惑,還是那句廢話知易行難,學習總是靠一點點堅持。

參考

  1. http://stackoverflow.com/questions/33527653/babel-6-regeneratorruntime-is-not-defined-with-async-await
  2. http://stackoverflow.com/questions/28976748/regeneratorruntime-is-not-defined
  3. https://www.zfanw.com/blog/babel-6.html
  4. transform-runtime
  5. babel-plugin-transform-runtime
  6. https://github.com/lmk123/blog/issues/45


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM