-
Notifications
You must be signed in to change notification settings - Fork 133
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix react import #1229
fix react import #1229
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice! Is there a simple-yet-exciting hello-world for react that we could use in lib/react.md?
fa0920d
to
a3f838c
Compare
Sigh, so I discovered two more issues. First, we also need to patch the import for |
Fixed with a more robust shim, and added a hello-world example. React isn’t really usable without JSX, though. |
external(source) { | ||
return source.startsWith("/_node/"); | ||
}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe this shouldn’t necessary since our importResolve
plugin already marks these as external: true
, but the commonjs plugin causes issues without it.
esbuild({ | ||
format: "esm", | ||
platform: "browser", | ||
target: ["es2022", "chrome96", "firefox96", "safari16", "node18"], | ||
exclude: [], // don’t exclude node_modules | ||
define: {"process.env.NODE_ENV": JSON.stringify("production")}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe in the future we could use development builds during preview here.
The tests seem flaky? I re-ran the one that failed and it passed. |
Yes, I don’t know why. |
The flakiness of the tests is because we run the tests in parallel, but we have a before hook that clears the cache: await rm("docs/.observablehq/cache/_node", {recursive: true, force: true}); That means when a new test starts, it can delete the cache of a test that’s already running. Not sure why it doesn’t happen locally but we’ll need to do something else here to isolate the tests. |
This took many hours. 😓 It’s important than
import "react"
works not just so that you can use React, but so you import React the same way whether you are running it in the browser or in Node. This allows us to use JSX components in server-side rendering (in Node) #1216, and then import the same JSX components in client-side rendering (in the browser) for hydration. (You can’t usenpm:react
in Node, at least not before we fix #288.)What makes this difficult is that React is still distributed as CommonJS modules, and worse, React’s CommonJS modules are too dynamic to be understood by cjs-module-lexer, which is the de facto standard of how CommonJS modules are exposed as ES modules. As a result, when you consume React’s CommonJS as an ES module, you only get a default export instead of named exports. And that means
import {useState} from "react"
etc. doesn’t work.I read a lot about various workarounds for this (such as rollup/plugins#423), but ultimately the only thing I got working was overriding the entry point into
react
(andreact-dom
andscheduler
) to the production bundle which is compatible with cjs-module-lexer. But this is just luck — hopefully luck that holds until React ships ES modules. If this didn’t work, we’d have to do something likerequire
the library and see what it exports at runtime, and then generate explicit named exports.My overall sense is that importing from node_modules won’t work for many (especially older) packages — though it’ll certainly work for some. I expect better support for
npm:
imports because jsDelivr (and esm.sh and others) likely has many workarounds to make +esm work — and even then, as we’ve seen, it sometimes doesn’t. We should continue to advocate for package authors to ship ES modules. And we should promote standards-based alternatives such as JSR #956. Let’s not bake too many more workarounds into Framework… I mean, okay, if it’s easy. It wasn’t easy here.