wmr
wmr copied to clipboard
Styled Components not working
I was trying to adopt WMR in a personal project but kept running into issues. I've found that it has something to do with styled-components
, but I'm not sure what's happening.
Error (in browser)
Uncaught SyntaxError: The requested module '/@npm/react-is' does not provide an export named 'typeOf'
Steps to Reproduce
- Run
npm init wmr
- Run
npm i styled-components
- Import styled-components into the
index.js
file,import styled from 'styled-components';
- Run
npm start
, notice the page does not render and the error in the console
That's to be expected. WMR was built for modern ES-Module compatible libraries. There is some rough support for older commonjs and other formats in there, but that's not a high priority, given that native ES Modules are marked as stable in all current browsers and active node versions. Libraries like react-is
are only published as commonjs and don't include any ES-Module entries in their package.
Your best bet is to file an issue on the React repo or give Preact a try which supports 1:1 the same API as React does. Preact comes with ES Module support out of the box and works well with styled-components.
From my understanding, I am using Preact as that is the default when you run npm init wmr
, right? In package.json
,
"alias": {
"react": "preact/compat",
"react-dom": "preact/compat"
}
and in the default index.js
file these imports are there,
import hydrate from 'preact-iso/hydrate';
import { LocationProvider, Router } from 'preact-iso/router';
import lazy, { ErrorBoundary } from 'preact-iso/lazy';
import styled from 'styled-components'; // This causes the issue
Is there some other step I'm missing? I laid out the exact commands I used to create the error, so unless React is sneaking in somewhere I should be using Preact.
Alright, I finally chased this one down. It's a bug in styled-components, which uses a fairly old version of Rollup's commonjs plugin to generate its ESM bundles that is just producing a nonsensical import:
import { typeOf } from 'react-is'; // incorrect, fails everywhere except Webpack
They'd originally told folks to fix this in their own configurations, but having this be broken by default doesn't seem adequate. Instead, I've submitted a PR that implements the correct import generation in their build setup:
https://github.com/styled-components/styled-components/pull/3367
One thing I did find while digging is that this import was broken in 5.1.0 - [email protected]
should work.
It's good to know that this issue happens with more "react" libs. react-waypoint
for example, throws the exact same error.
The requested module '/@npm/react-is' does not provide an export named.
Indeed - the misuse of named imports and over-reliance on webpack-specific compatibility workarounds is basically universal. If we can find a way to patch these broken modules in WMR, I'm open to doing so, just not if it impacts performance or output quality for folks who aren't relying on the broken modules.
Would it be possible to simplify patch creation with something like https://www.npmjs.com/package/patch-package?
I'm just thinking out loud. If we could run something like the pseudo below to patch a broken module, then we would have an accessible performant fix.
npx fix-export react-is typeOf
The command would patch the module, after which patch-package could take over.
@smeijer we already transform npm modules, so there's not much need for module-specific patching. I can open a draft PR with the workaround I came up with, but we'd need something more generalizable for production quality.
same problem with @material-ui/utils: import { Memo, ForwardRef } from '/@npm/react-is';
=> utils:5 Uncaught SyntaxError: The requested module '/@npm/react-is' does not provide an export named 'Memo'
Same with jss
'/@npm/react' does not provide an export named 'createContext'
@developit this project is cool indeed, I'm probably replacing parcel as a whole with it in my starters and medium-sized projects 🚀
Same with Unistore:
The requested module '/@npm/unistore/react' does not provide an export named 'Provider'
If I use unistore/preact
instead of unistore/react
, still no joy...
The requested module '/@npm/preact' does not provide an export named 'default'
Styled-components fixed their import but haven't updated the npm package yet: https://github.com/styled-components/styled-components/pull/3367#issuecomment-838344194
A few other packages I'm using also had bad imports (I noticed when I was trying to convert my app to wmr) so I'm a +1 for the auto-fix if it can be done in a reliable way
Similar issue with react-redux
: Uncaught SyntaxError: The requested module '/@npm/react-is' does not provide an export named 'isValidElementType'
preact-redux now states "If you're using Preact X (preact@10+), please use the official react-redux library."
@developit I see the label "hasfix" but which is the intended one? I'd like to try again
@damianobarbati The has fix
tag is incorrect, I think we forgot to remove it.
I've been working on revamping the npm plugin and on the commonjs handling over the past days and got it to render. There is a bit of remaining work to be done before this can be PR'ed, but it's progressing well so far.
