rollup icon indicating copy to clipboard operation
rollup copied to clipboard

Usage with commonjs default exports and ES output

Open 43081j opened this issue 4 years ago • 2 comments

Documentation Is:

  • [ ] Missing
  • [ ] Needed
  • [ ] Confusing
  • [x] Not Sure?

Please Explain in Detail...

If you could document how to deal with a mixed commonjs/esm situation, that would be so nice.

Basically, I have a project which is as follows:

  • Written in typescript (ES modules)
  • Transpiled to common JS (because of the following points)
  • Has a single dependency which is [unfortunately] a common JS module
  • This single dependency has commonjs-style default export (module.exports = function() { ... })

Given this example source:

export async function test() {
  const dep = await import('cjs-dependency');
  ...
};

Keep in mind, cjs-dependency has an awful default export:

module.exports = function() { ... }

At this point, typescript is happy (with module: commonjs) as the typescript types of that module specify export = someFunction;.

Where I'm stuck and where doesn't seem documented is how to bundle this for a browser while maintaining the interface...

Note that the obvious mess here is that the dependency should be using a named or default export. Dynamic imports in browsers should resolve to a module, not a function (in an ideal would it would be const {default: dep} = await import(...)).

Using the typescript plugin

If I use your typescript plugin, combined with the commonjs plugin, this single dependency is output like so:

export default index;
export { dist as __moduleExports };

However, now this means the interface has changed, so the consumer looks like this:

const dep = await import('./index-89d9a024.js');
dep(); // ERROR, you can't call a module...

Which won't be right anymore, as the function which used to exist there in commonjs-world now exists at default (i.e. const {default: dep} = ...).

Consuming transpiled code directly

I've also tried (my preference) building my sources normally via tsc, and having rollup consume the built javascript as-is with the commonjs/resolve plugins.

This results in consumption looking like so:

    const dep = await Promise.resolve().then(() => dist);

Which is a pain, since here rollup has inlined the dependency and not cared about making a chunk at all.

But at least the interface is correct/maintained!

However, it also replaced my own exports with a default:

export default index;

so now my own interface is wrong...


Is there any solution to this? and is any of this documented anywhere? i've struggled for days now to find any place you've documented this mixture of commonjs and esm. It seems either way is a loss, the interface of either my own module or the dependency is mangled by rollup.

Your Proposal for Changes

Introduce documentation specifying how on earth to achieve this use case, or specify that it isn't possible.

The bot closed my original issue which was nice, so here it is again. It is not only support, the fact that I have been unable to find a solution for this use case shows you clearly have no documentation for it. So here we are.

43081j avatar Jun 14 '20 18:06 43081j