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

babel-plugin-transform-async-to-module-method without regenerator

我的目标是将 async/await 编译成 Bluebird promises,对性能的影响最小。

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 编译它确实有效,但是 运行ning 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 - 欢迎 PRs!

您可以使用 async-to-generator plugin for this. But unfortunately the es2015 preset will still transform generators, so you will have to modify the es2015 preset. You could use 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"
  ]
}