没有再生器的babel-plugin-transform-async-to-module-method

时间:2016-04-21 16:08:44

标签: javascript async-await bluebird babel

我的目标是将async / await编译成Bluebird承诺,同时将性能影响降至最低。

babel-plugin-transform-async-to-module-method似乎是编译async / await到Bluebird的最常用方法,但是它减慢了我的应用程序约10-20%,这是不可接受的。我怀疑这很多都是由于再生器,这似乎是babel-plugin-transform-async-to-module-method所必需的。

例如,我在index.js中有这段代码:

var Promise = require('bluebird');

async function foo() {
    console.log('foo');
    await Promise.delay(500);
    console.log('bar');
}

foo();

和这个package.json:

{
  "name": "async-regenerator",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "build": "browserify index.js -t babelify --outfile bundle.js"
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "babel-plugin-transform-async-to-module-method": "^6.7.0",
    "babel-preset-es2015": "^6.6.0",
    "babelify": "^7.2.0",
    "browserify": "^13.0.0"
  },
  "dependencies": {
    "bluebird": "^3.3.5"
  },
  "browserify": {
    "transform": [
      "babelify"
    ]
  },
  "babel": {
    "presets": [
      "es2015"
    ],
    "plugins": [
      [
        "transform-async-to-module-method",
        {
          "module": "bluebird",
          "method": "coroutine"
        }
      ]
    ]
  }
}

使用npm run build进行编译确实有效,但是运行bundle.js会产生错误:

ReferenceError: regeneratorRuntime is not defined

将再生器添加到package.json会修复错误:

{
  "name": "async-regenerator",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "build": "browserify index.js -t babelify --outfile bundle.js"
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "babel-plugin-transform-async-to-module-method": "^6.7.0",
    "babel-plugin-transform-runtime": "^6.7.5",
    "babel-preset-es2015": "^6.6.0",
    "babelify": "^7.2.0",
    "browserify": "^13.0.0"
  },
  "dependencies": {
    "babel-runtime": "^6.6.1",
    "bluebird": "^3.3.5"
  },
  "browserify": {
    "transform": [
      "babelify"
    ]
  },
  "babel": {
    "presets": [
      "es2015"
    ],
    "plugins": [
      [
        "transform-runtime",
        {
          "polyfill": false,
          "regenerator": true
        }
      ],
      [
        "transform-async-to-module-method",
        {
          "module": "bluebird",
          "method": "coroutine"
        }
      ]
    ]
  }
}

然后bundle.js成功运行,但它使我的构建体积增大了100kb,并可能引入上述性能问题。

我的问题是,为什么甚至还需要再生器呢?我的目标浏览器(Chrome和Firefox)支持生成器,因此必须有一些方法才能使用本机生成器,对吧?我不知道这是否能解决我的性能问题,但我想尝试一下。

我知道有一些其他类似的async / await方法:

如果我忽略了您认为尝试的其他方法,请告诉我。

我将示例代码放在https://github.com/dumbmatter/babel-async-await-regenerator上 - 欢迎PR!

1 个答案:

答案 0 :(得分:8)

您可以使用async-to-generator插件。但不幸的是,es2015预设仍将改变发电机,因此您必须修改es2015预设。您可以使用modify-babel-preset,或者只是简单地展开您的babel配置中的预设。

"babel": {
  "plugins": [    
    "transform-es2015-template-literals",
    "transform-es2015-literals",
    "transform-es2015-function-name",
    "transform-es2015-arrow-functions",
    "transform-es2015-block-scoped-functions",
    "transform-es2015-classes",
    "transform-es2015-object-super",
    "transform-es2015-shorthand-properties",
    "transform-es2015-duplicate-keys",
    "transform-es2015-computed-properties",
    "transform-es2015-for-of",
    "transform-es2015-sticky-regex",
    "transform-es2015-unicode-regex",
    "check-es2015-constants",
    "transform-es2015-spread",
    "transform-es2015-parameters",
    "transform-es2015-destructuring",
    "transform-es2015-block-scoping",
    "transform-es2015-typeof-symbol",
    "transform-es2015-modules-commonjs",

    "transform-async-to-generator"
  ]
}