-
Notifications
You must be signed in to change notification settings - Fork 2.4k
Description
🐛 bug report
Description of the problem
My team publishes a package that provides a path to an ESM build via "module" in package.json. It looks something like this: "module": "./esm/index.js". Note, we don't specify "browser" or "main" and our package runs on both client and server environments.
The package is a React component library. We have a BaseProvider that we ask users to place at the root of their app. The BaseProvider sets up the theme for the app as well as some other things like layer and focus management.
There seems to be an issue with how CodeSandbox imports our BaseProvider (or any of our providers). For instance, the theme object passed to our BaseProvider will not be available via context to descendants of the provider. Or rather, it is available to components defined in the sandbox, but any component imported from our package which uses the same provider has a different context. All of this works as expected when you run the code outside of CodeSandbox (say in a fresh CRA setup).
I'm not really sure what the issue is, but reading through previous issues, it seemed like the sandbox was potentially importing both ESM and non ESM code, which would be problematic with a singleton (such as a React Context Provider).
To try and force Codesandbox to use the ESM build, I added a "browser" key to our package.json, pointing to the same ESM build "module" does, and this did seem to fix things. Our context based functionality worked as expected.
Unfortunately, this change would break many of our users' tests because it causes Jest to pull the ESM build rather then the fully transpiled build. Dependent projects could update their Jest config but it is essentially a breaking change. There is also the possibility someone has some weird bundling configuration that breaks with this change. Additionally, since our package runs on both the client and server, a "browser" key is supposedly redundant. All that is to say, I'd rather not add "browser" to our package.json if it only exists to get things working on CodeSandbox.
The last thing I'll add to this is that we set up CodeSandbox CI so we could test each PR. I was suprised to see that in the CI generated sandbox, the providers work as expected WITHOUT adding the "browser" key. I'm not sure how/why that could be since we run our exact pre-release build step in .codesandbox/ci.json (and .npmignore doesn't omit anything relevant).
How has this issue affected you? What are you trying to accomplish?
We use CodeSandbox liberally for both examples and bug reproductions. It's been somewhat common recently for folks to report bugs about theming not working, layer context issues, or focus management issues. All of these are handled in our code by React Providers (namely our root BaseProvider). We have to verify each time if these issues are legitimate or just due to the ESM importing problem.
The secondary effect is that until recently I had been doing all my testing in PRs against the CodeSandbox CI generated sandbox. But yesterday I realized that for some reason the one-off sandbox generated for the PR is not an indication of how the importing works against a published package. This makes testing the changes a bit precarious. Edit: This seems to be due to us using webpack in the CI sandbox vs the normal bundler.
Link to sandboxes
Here is a sandbox using a version of our package that has "browser" specified. It works as expected. The main thing to notice is that DarkTheme is imported from "baseui" and passed to BaseProvider. This makes the theme object passed around by context, "dark-theme", which in our library makes the button have a white background:
https://codesandbox.io/s/esm-9710-7oqv2?file=/index.js
Here we use a version of our package that does not have "browser" specified, only "module". It does not work as expected. The DarkTheme is passed to our root provider, but the button, imported from baseui/button, does not seem to pick it up:
https://codesandbox.io/s/esm-9720-u2hz1?file=/index.js
Now, here is the same example, but against a CodeSandbox CI generated sandbox using webpack. It works as expected, even though it has the same package.json as our second sandbox.
https://codesandbox.io/s/fast-resonance-1kv8x?file=/index.js
Your Environment
| Software | Name/Version |
|---|---|
| Сodesandbox | ,953dd0e69 |
| Browser | Chrome 81.0.4044.122 |
| Operating System | Mac OS 10.15.4 |