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
.defaultwould 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.defaultproperty. So then usingreact-async-ssrunbundled 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 themainfield, and if youimportit should usemodule. Their assertion that every package should have a CommonJS export which is an object with a.defaultproperty 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
exportsfield inpackage.json. So perhaps the solution is to remove themodulefield frompackage.jsonentirely, soexportswill be used instead, and that's already correctly configured.Could I ask a favour: Could you please edit
node_modules/is-class-component/package.jsonand remove themodulefield, 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-componentso, 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!!