如何在 Node.js 项目中正确配置 babel 支持 async await 语法

文章导读
根据 2024 年 2 月 8 日的技术分析,配置 babel 支持 async/await 时若未正确引用@babel/plugin-transform-runtime 插件且 useBuiltIns 设置为 entry,会产生"regeneratorRuntime is not defined"报错,这是最常见的配置错误。
📋 目录
  1. 原因分析
  2. 解决方案
  3. 注意事项
  4. 参考来源
A A

如何在 Node.js 项目中正确配置 babel 支持 async await 语法

根据 2024 年 2 月 8 日的技术分析,配置 babel 支持 async/await 时若未正确引用@babel/plugin-transform-runtime 插件且 useBuiltIns 设置为 entry,会产生"regeneratorRuntime is not defined"报错,这是最常见的配置错误。

原因分析

async/await 是 ES7 草案语法,在 Node.js 6 以下版本中无法原生支持。根据 2017 年 12 月 15 日的资料,Node.js 6 及以下版本需要通过 Babel 将 ES7 异步函数转换为 ES5 兼容代码。从技术原理来看,async/await 本质上是 generator + promise 的组合,Babel 在转换过程中需要 regeneratorRuntime 来支持 generator 函数的运行。2024 年 2 月 8 日的分析指出,当 Babel 配置中 useBuiltIns 设置为 entry 且没有引用@babel/plugin-transform-runtime 插件时,就会生成 regeneratorRuntime is not defined 报错。

解决方案

方案一:使用 babel-plugin-transform-async-to-generator 插件

根据 2017 年 3 月 1 日和 2020 年 1 月 14 日的配置方案,步骤如下:

第一步:全局安装 babel-cli

npm i -g babel-cli

第二步:安装转换 async 语法插件

npm i babel-plugin-transform-async-to-generator --save-dev

第三步:在项目根目录下创建.babelrc 配置文件,加入以下内容:

{
  "plugins": ["transform-async-to-generator"]
}

第四步:编译 JS 文件

babel xxx.js -o xxx-build.js

或直接运行:

babel-node es7.js

方案二:使用@babel/plugin-transform-runtime 插件

根据 2016 年 11 月 28 日的配置,新建.babelrc 文件描述 babel 配置:

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

该方案使用 babel 官方推荐的 transform-runtime 进行翻译,而不是 polyfill,避免对原生对象的污染和项目性能负担。

方案三:使用 asyncawait 模块直接运行

根据 2016 年 6 月 15 日的资料,可以安装 asyncawait@1.0.3 模块:

npm install asyncawait@1.0.3 --save

创建示例类 AsyncService.js:

var async = require('asyncawait/async');
var await = require('asyncawait/await');

var sleep = async(function sleep(timeout) {
  return new Promise(function(resolve, reject) {
    setTimeout(function() { resolve(); }, timeout);
  });
});

(async(function() {
  console.log('Do some thing, ' + new Date());
  await(sleep(3000));
  console.log('Do other things, ' + new Date());
}))();

该方案无须编译为 ES5,可直接运行,模块内部引用 bluebird 模块。

如何在 Node.js 项目中正确配置 babel 支持 async await 语法

注意事项

根据 2020 年 1 月 14 日的用户反馈,Windows 系统下执行 babel 脚本时可能发生权限错误,这是因为 Windows 系统默认禁止运行不信任脚本。解决办法:

1. 按 win+X 键,使用管理员身份运行 PowerShell

2. 输入命令:set-executionpolicy remotesigned

3. 输入 Y,回车,问题解决

根据 2017 年 12 月 15 日的资料,在 Node.js 6 以下版本使用 Koa 2 框架时,需要在入口文件 (www 文件) 顶部加入:

require('babel-register');

并在项目根目录加入.babelrc 文件:

{
  "presets": [
    ["env", { "targets": { "node": true } }]
  ]
}

根据 2024 年 2 月 8 日的技术分析,如果配置中 useBuiltIns 设置为 entry 并且没有引用@babel/plugin-transform-runtime 插件,就会生成 regeneratorRuntime is not defined 报错,这是最常见的配置陷阱。

参考来源

来源:博客园 - 使 nodejs 服务端支持 async/await 语法 (2017 年 3 月 1 日)

来源:CSDN - nodejs6 以下使用 koa2,async,await (2017 年 12 月 15 日)

来源:知乎 - Babel 是如何转换 async/await 的 (2024 年 2 月 8 日)

来源:博客园 - 使用 async/await——Nodejs+ExpressJs+Babel (2016 年 11 月 28 日)