developit / microbundle

📦 Zero-configuration bundler for tiny modules.
https://npm.im/microbundle
MIT License
8.03k stars 362 forks source link

Uncaught TypeError: React__default.default is undefined when importing React in my source files #983

Closed bhch closed 2 years ago

bhch commented 2 years ago

When I use import React from 'react' in my source files, the umd build file shows this error in the browser:

Uncaught TypeError: React__default.default is undefined

If I remove the import statements, the error is gone and everything works perfectly.

Reproduce error

Clone this repo: https://github.com/bhch/react-microbundle-test/

Version info

bhch commented 2 years ago

Hi, can I please get some pointers to resolve this? It's been driving me mad for past four days.

rschristian commented 2 years ago

You're relying on globals but not telling Microbundle about them.

// package.json
{
  ...
  "scripts": {
-    "build": "microbundle --jsx React.createElement",
+    "build": "microbundle --jsx React.createElement --globals react=React,react-dom=ReactDOM",
    "dev": "microbundle watch --no-compress --sourcemap false --jsx React.createElement"
  }
}
bhch commented 2 years ago

Thank you. This has solved the issue.

However, can you please explain why we need to declare --globals? Shouldn't microbundle automatically infer this for variables imported from dependencies? Or is it only required for umd builds which rely on other scripts?

rschristian commented 2 years ago

This might be more clear if you run a build with & without --globals (toss the result into a diff tool).

Microbundle gives a good shot at assuming names for each, using global.react and global.reactDom. However, using the official React bundles, these of course are instead supplied as global.React and global.ReactDOM. They could just as easily be supplied as global.foo and global.bar though. There's no way of knowing how a package import might connect to globals. jQuery, quite (in)famously, is mapped to $. Hopefully you see how this is less "inference" and more "guessing game".

It doesn't necessarily only matter for UMD, but UMD (and old JS practices in general) rely on globals far more than they should. You can however use globals in any format.

I suppose one could argue though that import maps w/ ESM are sort of similar, but very different in execution obviously.