关于javascript:ES7异步等待功能与babel-loader不起作用

ES7 async await functions with babel-loader not working

我正在尝试使用webpack的babel-loader在JavaScript中运行异步等待函数。 我正在使用以下配置:

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
{
  name: 'client',
  context: path.join(__dirname, 'src', 'static', 'scripts'),
  entry: {
    index: './index.js'
  },
  output: {
    path: path.join(__dirname, 'src', 'static', 'bundles'),
    filename: '[name].js'
  },
  module: {
    loaders: [
      {
        test: /\\.js$/,
        loader: 'babel',
        query: {
          presets: ['es2015', 'stage-0']
        }
      }
    ]
  },
  resolve: {
    root: path.join(__dirname),
    fallback: path.join(__dirname, 'node_modules'),
    modulesDirectories: ['node_modules'],
  }
}

但它不断通过以下消息推送错误:

Module build failed: Error: ./src/static/scripts/index.js: Expected type"Identifier" with option {}

我的index.js具有以下内容:

1
2
3
4
5
6
7
8
9
10
console.log('hi from app');

async function hello() {
  return Promise.resolve('hi')
}

async function conversation () {
  const hi = await hello()
  console.log(hi);
}

首先,请确保您正在使用所有最新版本的babel插件:

npm i -D babel-loader babel-polyfill babel-preset-es2015 babel-preset-stage-0 babel-runtime

(我不确定是否确实需要babel-runtime-YMMV)

在Webpack的entry中,使用以下命令:

1
2
3
4
  entry: [
    'babel-polyfill',
    './index.js'
  ]

您需要将babel-polyfill添加到您的输入脚本中以启用" regeneratorRuntime",这对于异步/等待是必需的。

然后在module部分中使用babel-loader(而不是babel)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
  module: {
    loaders: [
      {
        test: /\\.js$/,
        exclude: /(node_modules|bower_components)/,
        loader: 'babel-loader',
        query: {
          presets: [
            'es2015',
            'stage-0'
          ]
        }
      }
    ]

那应该解决它。

注意:如果在服务器端使用Node,则需要在输入脚本的顶部添加一个显式的require('babel-polyfill');,以确保识别出任何异步/等待语法。

es2015和stage-0不足以填充节点5-而是在.babelrc中使用它

1
2
3
4
5
{
 "presets": [
   "node5"
  ]
}

node5是babel插件的集合,我维护这些插件以仅填充那些缺少的Node5.x。它也应该也可以与Node 4.x一起使用(在稍有变化的情况下,ES6兼容性现在几乎相同)。

您需要先通过NPM安装它:

npm i -D babel-preset-node5


看来您遇到了错误。它似乎已解决,但尚未发布。

如果您不能等到发布它,则可以应用与解决该问题的提交相对应的补丁。

应用补丁的一种方法:

将以下差异保存到包根文件夹中的文件中(例如,visit.patch)。然后使用git apply visit.patch应用补丁。

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
From 940b86dadbd0151c33c02e89f0b5ff61077c9214 Mon Sep 17 00:00:00 2001
From: Henry Zhu <hi@henryzoo.com>
Date: Thu, 5 Nov 2015 20:10:15 -0500
Subject: [PATCH] transform-regenerator: set node.id to an identifier if null -
 fixes #2835

---
 packages/babel-plugin-transform-regenerator/lib/visit.js | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/node_modules/babel-preset-es2015/node_modules/babel-plugin-transform-regenerator/lib/visit.js b/node_modules/babel-preset-es2015/node_modules/babel-plugin-transform-regenerator/lib/visit.js
index 0f68ffc..c4a0d2e 100644
--- a/node_modules/babel-preset-es2015/node_modules/babel-plugin-transform-regenerator/lib/visit.js
+++ b/node_modules/babel-preset-es2015/node_modules/babel-plugin-transform-regenerator/lib/visit.js
@@ -146,6 +146,10 @@ function getOuterFnExpr(funPath) {
   var node = funPath.node;
   t.assertFunction(node);

+  if (!node.id) {
+    node.id = funPath.scope.parent.generateUidIdentifier("callee");
+  }
+
   if (node.generator && // Non-generator functions don't need to be marked.
       t.isFunctionDeclaration(node)) {
     var pp = funPath.findParent(function (path) {
@@ -171,9 +175,7 @@ function getOuterFnExpr(funPath) {
     );
   }

-  return node.id || (
-    node.id = funPath.scope.parent.generateUidIdentifier("callee")
-  );
+  return node.id;
 }

 function getRuntimeMarkDecl(blockPath) {

更新:

似乎该错误未正确修复,并且提交已还原。看起来这是由于此请求中已解决的另一个问题所致。


对于节点v8.11上的预设env,我遇到了异步功能问题,即永远不会运行,也不例外。

然后,我参考官方文档,并将target添加到.babelrc,现在可以使用了。

1
2
3
4
5
6
7
8
9
{
 "presets": [
    ["env", {
     "targets": {
       "node":"current"
      }
    }]
  ]
}

Babel文档