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

dum*_*ter 4 javascript babel async-await bluebird

我的目标是将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();
Run Code Online (Sandbox Code Playgroud)

而这个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"
        }
      ]
    ]
  }
}
Run Code Online (Sandbox Code Playgroud)

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

ReferenceError: regeneratorRuntime is not defined
Run Code Online (Sandbox Code Playgroud)

将regenerator添加到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"
        }
      ]
    ]
  }
}
Run Code Online (Sandbox Code Playgroud)

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

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

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

如果我忽略了你认为可以尝试的其他方法,请告诉我.

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

Tam*_*dus 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"
  ]
}
Run Code Online (Sandbox Code Playgroud)