Microbundle: Mixed default and named exports changes default export

Created on 31 Aug 2020  路  8Comments  路  Source: developit/microbundle

Hey everyone! I am having the following issue, if I export like this:

import GoogleMap from './google_map';

export default GoogleMap;

It will build:

module.exports = GoogleMap;

However, when including named exports:

import GoogleMap from './google_map';

export { namedExport1, namedExport2 } from './named_exports;

export default GoogleMap;

it changes to:

exports.namedExport1 = namedExport1;
exports.namedExport2 = namedExport2;
...
exports.default = GoogleMap;

Which results in the following error:

Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object.

I am pretty sure you will ask why we do need default exports, in my case I've a library that is used by a lot of people, I switched to microbundle a bit ago and realized later on this was buggy and it won't work with SSR unless we do module.exports, thing is even if I want to change the way we import / export to work with microbundle, I need to provide backwards compatibility or something...

I think this might be related to #264 and #306 but I am not completely sure if that's the case.

known issue

Most helpful comment

I might add an option to do this automatically.

@developit would love this

All 8 comments

Hiya. This is done intentionally. Here's what you can do to produce CommonJS and UMD bundles that don't have the issue:

{
  "scripts": {
    "build": "microbundle -f cjs,umd src/index.cjs.js && microbundle -f es,modern src/index.js"
  }
}
// index.js
import GoogleMap from './google_map';
export { namedExport1, namedExport2 } from './named_exports;
export default GoogleMap;
// index.cjs.js
import GoogleMap from './google_map';
import { namedExport1, namedExport2 } from './named_exports;
Object.assign(GoogleMap, { namedExport1, namedExport2 });
export default GoogleMap;

Now require('your-lib') === GoogleMap, but require('your-lib').namedExport1 === namedExport1.

I might add an option to do this automatically.

Works like a charm, thanks for the quick response!

Would be awesome if you add an option to do this automatically! 馃帀

Feel free to close the issue, unless you want to keep it for that option you want to add.

@developit any implications why we don't do this behaviour by default if it's umd/cjs? Any reasons that make this a big nono?

TBH I don't think there would be any negative effects, it just hasn't been implemented.

I might add an option to do this automatically.

@developit would love this

same lol

I've been getting a lot of bug reports on how this works in markdown-to-jsx: https://github.com/probablyup/markdown-to-jsx/issues/333

https://github.com/probablyup/markdown-to-jsx/blob/676e53ff33036fd0527a9ea79cd478a74ea20513/index.cjs.tsx#L1-L3

Webpack doesn't seem to be able to resolve this

Couldn't you do this for both? Rather than having two different files?

import GoogleMap from './google_map';
import { namedExport1, namedExport2 } from './named_exports;
Object.assign(GoogleMap, { namedExport1, namedExport2 });
export default GoogleMap;
Was this page helpful?
0 / 5 - 0 ratings

Related issues

rzkhosroshahi picture rzkhosroshahi  路  5Comments

SleeplessByte picture SleeplessByte  路  3Comments

dmitrykurmanov picture dmitrykurmanov  路  3Comments

kesla picture kesla  路  4Comments

adriengibrat picture adriengibrat  路  4Comments