简体   繁体   中英

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

My goal is to have async/await compiled down to Bluebird promises with minimal performance impact.

babel-plugin-transform-async-to-module-method appears to be the most common way to compile async/await to Bluebird, however it slows my application down by about 10-20% which is not acceptible. I suspect that muchfun of this is due to regenerator, which seems to be required for babel-plugin-transform-async-to-module-method .

For instance, I have this code in index.js:

var Promise = require('bluebird');

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

foo();

and this 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"
        }
      ]
    ]
  }
}

Compiling that with npm run build does work, but then running bundle.js produces an error:

ReferenceError: regeneratorRuntime is not defined

Adding regenerator to package.json does fix the error:

{
  "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"
        }
      ]
    ]
  }
}

Then bundle.js does successfully run, but it makes my build 100kb larger and possibly introduces the aforementioned performance problem.

My question is, why is regenerator even required for this? My target browsers (Chrome and Firefox) support generators, so there must be some way to just use native generators, right? I don't know if that'd fix my performance problem, but I'd like to try.

I know there are a couple other similar approaches to async/await:

If I'm neglecting some other approach that you think would be good to try, please let me know.

I put the example code on https://github.com/dumbmatter/babel-async-await-regenerator - PRs are welcome!

You can use the 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 , or just simply unfold the preset in your babel config.

"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"
  ]
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM