Skip to content
This repository has been archived by the owner on Aug 4, 2021. It is now read-only.

minimal working example: rollup + babel + async/await #312

Closed
htho opened this issue Jun 28, 2019 · 19 comments
Closed

minimal working example: rollup + babel + async/await #312

htho opened this issue Jun 28, 2019 · 19 comments

Comments

@htho
Copy link

htho commented Jun 28, 2019

I saw some issues (#209, #306) and questions on stackoverflow about how to configure rollup and babel so I can use async and await. There are many (often outdated) answers and it is a tedious, difficult (but hopefully not impossible) task to create a working rollup.config.js. I was not able to do that.

My repository

https://github.com/htho/mweRollupBabelAsyncAwait

should become a minimal working example.

Right now it is a vanilla rollup.config.js based on the official rollup.js guide. https://rollupjs.org/guide/en/#babel
I understand that rollup is currently es6 only, and therefore does not support async/await natively. But I thought that this would be babel's job anyway. For the Developer Experience, setting up rollup+babel with async/await support, should be a no-brainer.

Please help me. Or integrate it into this repository. A set of minimally working examples would make developers lifes so much easier.

@Andarist
Copy link
Member

Andarist commented Jul 2, 2019

It all depends on what are your requirements and target format, you can make your example work by using such a setting:

{
  "presets": [
    ["@babel/env", { "modules": false, "useBuiltIns": "usage" }]
  ]
}

@htho
Copy link
Author

htho commented Jul 2, 2019

I am required to set the corejs version.

$ ./node_modules/.bin/rollup -c

src/BuildTest.js → dist/BuildTest.js...

WARNING: We noticed you're using the `useBuiltIns` option without declaring a core-js version. Currently, we assume version 2.x when no version is passed. Since this default version will likely change in
future versions of Babel, we recommend explicitly setting the core-js version you are using via the `corejs` option.

You should also be sure that the version you pass to the `corejs` option matches the version specified in your `package.json`'s `dependencies` section. If it doesn't, you need to run one of the following
commands:

  npm install --save core-js@2    npm install --save core-js@3
  yarn add core-js@2              yarn add core-js@3

(!) Unresolved dependencies
https://rollupjs.org/guide/en#warning-treating-module-as-external-dependency
regenerator-runtime/runtime (imported by src\BuildTest.js)
created dist/BuildTest.js in 2.3s

OK, which core-js should I use, and where do I "explicitely" set the corejs version via the corejs option?

I can not find the answer: https://duckduckgo.com/?q=babel+rollup+declare+the+core-js+version&t=ffab&ia=web

@Andarist
Copy link
Member

Andarist commented Jul 2, 2019

Use latest one:

{
  "presets": [
    ["@babel/env", { "modules": false, "useBuiltIns": "usage", "corejs": 3 }]
  ]
}

@htho
Copy link
Author

htho commented Jul 2, 2019

Still not sufficient:

./node_modules/.bin/rollup -c

src/BuildTest.js → dist/BuildTest.js...
(!) Unresolved dependencies
https://rollupjs.org/guide/en#warning-treating-module-as-external-dependency
regenerator-runtime/runtime (imported by src\BuildTest.js)
created dist/BuildTest.js in 2s

@Andarist
Copy link
Member

Andarist commented Jul 2, 2019

U have to install regenerator-runtime module and u should be ready to go

@htho
Copy link
Author

htho commented Jul 2, 2019

Thank you so far.
I have updated my repository in order to reflect the changes we discussed.
The regenerator is available now.

But IE still needs a Polyfill for Promise. I'd expect babel to include it aswell, but it isnt. Is it a problem with babel? To my understanding, the babel documentation suggests that the Promise polyfill is included aswell: https://babeljs.io/docs/usage/polyfill/
Well, there is the message, that says with useBuiltIns I should not import polyfills anymoren

@Andarist
Copy link
Member

Andarist commented Jul 2, 2019

In your example rhe reference to a Promise is only in so called babel helpers (asyncGeneratorStep & asyncToGenerator here). Those are insertes "as is" - without compilation, so preset-env doesn't visit it to see a Promise which would cause it to insert a ponyfill import. To work around this you can insert Promise.resolve() into your code, or you can just polyfill Promise globally.

@htho
Copy link
Author

htho commented Jul 2, 2019

Hi. Once someone (you) explained the internals to me, this seems totally logical. But in my opinion consumers of a tool should not need learn these internals. They should not be required to solve this problem on their own. The solution should not be a dummy call to Promise.resolve(). But that is another topic.

I really feel stupid for asking all these questions. On the other hand, I am really frustrated a task that is so basic, is so complicated. The documentation of all the releated tools and all the error messages are so useless. I really am someone who says and does RTFM ans STFI all the time, but I cant help myself here.

Manually including the polyfill circumvents the useful useBuiltIns. So I make the dummy call.

Guess what! It still does not work. The polyfill that is included uses calls to require() and of course they can not be resolved at runtime. Thats what rollup or babel should do.

I updated the repository again.

Please I really start doubting myself.

@Andarist
Copy link
Member

Andarist commented Jul 3, 2019

I agree with all of your points, this is a surprisingly hard thing to do for something supposedly that simple. Even I had to look through docs and babel source code to try find a good combo of options for various outputs which I have wanted to achieve here.

Problem is that requirements are different for people though, one is fine with polluting global namespace with polyfills, one is not and want to use ponyfill imports, other one doesn't want to polyfill at all or just want to handle on their own. That's why there is no one golden example for doing this. I've brought this up to a Babel team though and hopefully we should be able to figure out a better way of doing this like this.

I'll look at your repo at later time, unfortunately I don't have much time right now.

@renoirb
Copy link

renoirb commented Jul 4, 2019

Have a look at egoist/bili it removes a lot of the complexity. And uses rollup under the hood.

I've pulled my hair about this today, and I could have recent Babel 7, along with tests to work. Lots of things changed since Babel 6.

I pushed something that works with testing with recent config. Tests works woth modern async/await, uses modules and does transpilation in different targets (e.g. Node, Browser) and mimicks one module member of a monorepo. Try it out, maybe it'll help. https://github.com/renoirb/experiments-201907-bili-babel-preset-env-multiple-target-builds

@htho
Copy link
Author

htho commented Jul 5, 2019

Hi @renoirb,

bili sounds nice. But I am always sceptical when I need to put more and more parts of my build-process into someone elses hands. New systems introduce new problems. This speaks from my heart: https://bravenewgeek.com/tag/taco-bell-programming/
As long as I can, I want to use the cat, sed and grep of the bundle/transpile world.

Anyway, it is good to know that there is bili out there. Should I or the awsome devs at rollup and/or babel not find a solution in the next time, I need to reeavaluate it.

Thank you very much!

@FuJuntao
Copy link

FuJuntao commented Jul 8, 2019

 /dist/BuildTest.js

  ...
  var $ = require('../internals/export');
  var IS_PURE = require('../internals/is-pure');
  var global = require('../internals/global');
  var path = require('../internals/path');
  var redefineAll = require('../internals/redefine-all');
  ...

Hi,
I didn't find an "internals" directory, so where did it require internals?

@htho
Copy link
Author

htho commented Jul 8, 2019

Hi @FuJuntao as far as I understood the problem. This code is copied&pasted somwhere from within babels directory structure. Somewhere in there, there might be an internals directory. But the problem is, that the code is not transpiled/included before it is moved here.

@green-arrow
Copy link

I'm having the same kind of issues. I've tried just about every combination I can think of between rollup and babel, but still can't get it working properly.

rollup.config.js:

import pkg from './package.json';
import babel from 'rollup-plugin-babel';

export default [
  {
    input: 'src/index.js',
    output: [
      { file: pkg.browser, format: 'umd', name: 'MyLib' },
      { file: pkg.main, format: 'cjs' },
      { file: pkg.module, format: 'es' },
    ],
    plugins: [
      babel({
        babelrc: false,
        exclude: 'node_modules/**',
        presets: [
          [
            '@babel/preset-env',
            {
              corejs: 3,
              modules: false,
              useBuiltIns: 'usage',
              forceAllTransforms: true,
              targets: {
                node: 'current',
                ie: '11',
              },
            },
          ],
        ],
      }),
    ],
  },
];

The first few lines of my output file, however, contain references directly to core-js and regenerator-runtime. I have both of those installed as devDependencies.

require('core-js/modules/es.array.from');
require('core-js/modules/es.array.iterator');
require('core-js/modules/es.map');
require('core-js/modules/es.object.to-string');
require('core-js/modules/es.string.iterator');
require('core-js/modules/web.dom-collections.for-each');
require('core-js/modules/web.dom-collections.iterator');
require('regenerator-runtime/runtime');

@green-arrow
Copy link

green-arrow commented Aug 12, 2019

Update: Finally got it working with the following rollup.config.js (no babel config as it is inlined in the rollup config):

import pkg from './package.json';
import babel from 'rollup-plugin-babel';
import resolve from 'rollup-plugin-node-resolve';
import commonjs from 'rollup-plugin-commonjs';

export default [
  {
    input: 'src/index.js',
    output: [
      { file: pkg.browser, format: 'umd', name: 'MyLib' },
      { file: pkg.main, format: 'cjs' },
      { file: pkg.module, format: 'es' },
    ],
    plugins: [
      babel({
        babelrc: false,
        exclude: 'node_modules/**',
        presets: [
          [
            '@babel/preset-env',
            {
              corejs: 3,
              modules: false,
              useBuiltIns: 'usage',
              targets: {
                ie: '11',
              },
            },
          ],
        ],
      }),
      resolve(),
      commonjs(),
    ],
  },
];

The fix was adding rollup-plugin-node-resolve and rollup-plugin-commonjs. I didn't need any additional babel plugins like transform-runtime or transform-async-to-generator.

CC @FuJuntao - I had the same internals references as you after I added rollup-plugin-node-resolve. That was fixed and properly inlined once I added rollup-plugin-commonjs. Hope that fixes your problem as well.

@htho
Copy link
Author

htho commented Aug 19, 2019

Thank you @green-arrow now it works!

https://github.com/htho/mweRollupBabelAsyncAwait

@Andarist It still is necessary to include the dummy call to `Promise.resolve()``. Will there be a solution for this inconvenience?

@cynecx
Copy link

cynecx commented Dec 28, 2019

I am currently looking into that example: https://github.com/htho/mweRollupBabelAsyncAwait.

It kinda works but the Promise.resolve() hacks seems weird and confusing (Is it just Promise or are other things broken too?). Has there been any progress in finding the cause of that problem?

My current work around is basically @babel/plugin-transform-runtime. And honestly, I don't really understand the difference between babel's plugin-transform-runtime and preset-env's useBuiltIns set to usage. The former one seems to produce slightly smaller output than the latter one.

@renoirb
Copy link

renoirb commented Dec 28, 2019

I have a running example of async/await written in TypeScript, and multiple build outputs. It's also using @babel/plugin-transform-runtime.

Regarding the confusion about preset-env and transform-runtime plugin. Look at my notes in @renoirb/conventions-use-bili (they're what's hidden behind my bili.conf.js).

@F1LT3R
Copy link

F1LT3R commented Feb 5, 2020

Thanks for putting this together guys! Awesome stuff. This was a confusing process indeed.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants