react-async-ssr
react-async-ssr copied to clipboard
Error if module is compiled by webpack
Files for SSR are compiled by Webpack on our project. I am having the following error:
isReactClassComponent is not a function
in file shim.js. That is because Webpack prefer "module", not "main". If I change require('is-class-component')
to require('is-class-component').default
right in the shim.js file, it works fine.
There is an issue in webpack repository https://github.com/webpack/webpack/issues/5756 where author of Webpack writes that module should export the same API in es module and in commonjs module. http://prntscr.com/xox5qg
How to reproduce: Create a module, use react-async-ssr in it and compile that module by Webpack.
+1 Adding .default
worked
Sorry for slow reply. Been busy with other projects.
Yes, adding .default
would solve the problem in your case where you're bundling the code with Webpack. However, it would fail everywhere else because require('is-class-component')
returns a function which doesn't have a .default
property. So then using react-async-ssr
unbundled from NodeJS would be broken, which is the most common use case.
This is a really thorny issue and there are no easy answers. Personally, I think Webpack's behavior is incorrect. If you require()
a module it should use the main
field, and if you import
it should use module
. Their assertion that every package should have a CommonJS export which is an object with a .default
property is totally unrealistic. That's not how CommonJS works!
But I can also see the problem that Webpack is trying to solve - avoiding duplicate code in bundles where the same package is both require()
-ed and import
-ed in different places. In any case, by the looks of things, they're not going to change it, so whether they are correct or not is academic.
I understand Webpack 5 now supports the exports
field in package.json
. So perhaps the solution is to remove the module
field from package.json
entirely, so exports
will be used instead, and that's already correctly configured.
Could I ask a favour: Could you please edit node_modules/is-class-component/package.json
and remove the module
field, then try building with Webpack again? (you might need to clear Webpack's cache to make sure it picks up the change)
I am also the maintainer of is-class-component
so, if it works, I could make that change. I'm not sure how one could solve this problem if it was code under someone else's control.
From reading various issues in Webpack and ESBuild repos, it appears this is quite a common problem with various packages. Out of interest, have you run into this with any other packages?
Sorry for slow reply. Been busy with other projects.
Yes, adding
.default
would solve the problem in your case where you're bundling the code with Webpack. However, it would fail everywhere else becauserequire('is-class-component')
returns a function which doesn't have a.default
property. So then usingreact-async-ssr
unbundled from NodeJS would be broken, which is the most common use case.This is a really thorny issue and there are no easy answers. Personally, I think Webpack's behavior is incorrect. If you
require()
a module it should use themain
field, and if youimport
it should usemodule
. Their assertion that every package should have a CommonJS export which is an object with a.default
property is totally unrealistic. That's not how CommonJS works!But I can also see the problem that Webpack is trying to solve - avoiding duplicate code in bundles where the same package is both
require()
-ed andimport
-ed in different places. In any case, by the looks of things, they're not going to change it, so whether they are correct or not is academic.I understand Webpack 5 now supports the
exports
field inpackage.json
. So perhaps the solution is to remove themodule
field frompackage.json
entirely, soexports
will be used instead, and that's already correctly configured.Could I ask a favour: Could you please edit
node_modules/is-class-component/package.json
and remove themodule
field, then try building with Webpack again? (you might need to clear Webpack's cache to make sure it picks up the change)I am also the maintainer of
is-class-component
so, if it works, I could make that change. I'm not sure how one could solve this problem if it was code under someone else's control.From reading various issues in Webpack and ESBuild repos, it appears this is quite a common problem with various packages. Out of interest, have you run into this with any other packages?
Hi! As a matter of fact, I forked this repository and added a .default
on to the end of the import in shim.js as a gross hack and that worked for a while.
I've since done a fairly major upgrade to webpack and node, and my hack stopped working! reverting to use your library works without error...
I'm afraid my knowledge of webpack and node modules is pretty sketchy, but would be happy to provide info as needed!!