-
-
Notifications
You must be signed in to change notification settings - Fork 852
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
immer is not properly exported to be used in Node.js ESM modules #901
Comments
Would you mind opening a PR for that?
…On Tue, Jan 25, 2022 at 10:34 AM Candid Dauth ***@***.***> wrote:
I am trying to use immer in the backend of a Node.js application. I am
currently in the process of migrating my backend to ESM modules
<https://nodejs.org/api/esm.html>, since some dependencies (in particular
node-fetch <https://github.com/node-fetch/node-fetch>) are starting to
ship only ESM modules.
Error description
When I try to import immer in an mjs module using import produce from
'immer';, produce will be an object instead of a function, with its
default property being the produce function.
I can access the produce function by using import { produce } from
'immer'; or by using import immer from 'immer'; and then using
immer.produce(). The problem is that the documentation uses import
produce from 'immer';, so there are libraries using this whose code I am
not in control of. This means that these libraries break when I migrate to
ESM modules.
Reason for the error
immer is bundled in several different formats, among them cjs and esm.
The bundles are referenced in package.json in the following way (index.js
being a wrapper that includes the cjs bundle):
"main": "dist/index.js",
"module": "dist/immer.esm.js",
While the module property is probably supported by webpack and other
bundlers, it does not seem to be supported by Node.js. Instead, Node.js
uses the exports property to support different main files for different
environments (see here
<https://nodejs.org/api/packages.html#nodejs-packagejson-field-definitions>.
Since that is not defined in this case, Node.js requires the file from the
main property, which is a CommonJS bundle.
Even forcing Node.js to use the ESM bundle by doing import produce from
'immer/dist/immer.esm.js'; does not solve the problem. The problem is
that Node.js interprets files as CommonJS unless they have a .jsm file
extension or "type": "module" is defined in package.json (which then
applies to all files in the package) (see here
<https://nodejs.org/api/packages.html#determining-module-system>.
Possible solution
Setting "type": "module" is probably not an option, since that will break
the CommonJS files.
The only solution that I can think of is to ship the ESM bundle as an .mjs
file, either by renaming the current one or by creating a copy. The file
can then be referenced in package.json like this:
"exports": {
"import": "./dist/immer.esm.mjs",
"require": "./dist/index.js"
},
Workaround
I have not yet found a workaround how I can migrate my app to ESM without
breaking dependencies that use immer. If I find one, I will update the
issue.
—
Reply to this email directly, view it on GitHub
<#901>, or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAN4NBCCBTWOJOXL262BYZDUXZ4CBANCNFSM5MX3RX2A>
.
Triage notifications on the go with GitHub Mobile for iOS
<https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675>
or Android
<https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub>.
You are receiving this because you are subscribed to this thread.Message
ID: ***@***.***>
|
I could do it, but I'm not sure which solution you prefer. I see that the ESM export used to have the |
After gaining some more experience with this, I think the way to go would be to add an For the next major release, the If you agree with this approach, I could work on a pull request. |
@cdauth sorry had to read a little bit up on that, looks like it is going to be messy indeed, but your solution sounds reasonable, so feel free to give it a shot :). I think introducing an exports field should be ok? with a copy of the module file with separate extension is probably the safest bet at the moment indeed, while crying a little inside. |
🎉 This issue has been resolved in version 9.0.13 🎉 The release is available on: Your semantic-release bot 📦🚀 |
I write an Expo application. I use
Maybe the warning is related to this issue. Let me know if you need additional information. |
@timur-svoboda : yeah, Immer 10 should fix that, but RTK 1.x needs Immer 9. Please try out our RTK 2.0 betas, which already are updated to use Immer 10 instead: https://github.com/reduxjs/redux-toolkit/releases/tag/v2.0.0-beta.1 |
I'm happy to patch 1.9 if someone can figure out in his local
node_modules/immer how the package.json should change, as afaic the react
native entry should already take care of it.
…On Sun, 3 Sept 2023, 12:13 Tuan Nguyen, ***@***.***> wrote:
I'm having the same issue with RTK 1.9.5 or event upgraded to RTK 2.0.0-beta
1 doesn't fix the issue.
I write application in Bare React Native with @callstack/repack
[image: Simulator Screenshot - iPhone 8 Plus - 2023-09-03 at 15 06 59]
<https://user-images.githubusercontent.com/3163410/265258003-a98afd69-b4fc-42de-9b10-9aedde011285.png>
—
Reply to this email directly, view it on GitHub
<#901 (comment)>, or
unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAN4NBBYFORS64W4UXL3S3TXYRJ5NANCNFSM5MX3RX2A>
.
You are receiving this because you modified the open/close state.Message
ID: ***@***.***>
|
I'm building an Expo app in an Nx repo and I also get the following warning:
For me though, it seems to be having some serious side effects because I can't modify state directly (should be handled by immer) in my reducers. I'm forced to do the following workaround:
Has anyone else experienced this side effect? Versions:
|
@techgerm : That's because RTK 1.9 uses Immer 9, and neither of them are updated to work correctly with Node + ESM. Please upgrade to our RTK 2.0 betas, which use Immer 10 and have specifically been updated for proper Node+ESM compatibility. I actually just published 2.0.0-beta.4 a few minutes ago: https://github.com/reduxjs/redux-toolkit/releases/tag/v2.0.0-beta.4 |
@markerikson ah gotcha okay thanks! |
I am trying to use immer in the backend of a Node.js application. I am currently in the process of migrating my backend to ESM modules, since some dependencies (in particular node-fetch) are starting to ship only ESM modules.
Error description
When I try to import immer in an mjs module using
import produce from 'immer';
,produce
will be an object instead of a function, with itsdefault
property being the produce function.I can access the produce function by using
import { produce } from 'immer';
or by usingimport immer from 'immer';
and then usingimmer.produce()
. The problem is that the documentation usesimport produce from 'immer';
, so there are libraries using this whose code I am not in control of. This means that these libraries break when I migrate to ESM modules.Reason for the error
immer is bundled in several different formats, among them
cjs
andesm
. The bundles are referenced inpackage.json
in the following way (index.js
being a wrapper that includes thecjs
bundle):While the
module
property is probably supported by webpack and other bundlers, it does not seem to be supported by Node.js. Instead, Node.js uses theexports
property to support different main files for different environments (see here. Since that is not defined in this case, Node.js requires the file from themain
property, which is a CommonJS bundle.Even forcing Node.js to use the ESM bundle by doing
import produce from 'immer/dist/immer.esm.js';
does not solve the problem. The problem is that Node.js interprets files as CommonJS unless they have a.jsm
file extension or"type": "module"
is defined inpackage.json
(which then applies to all files in the package) (see here).Possible solution
Setting
"type": "module"
is probably not an option, since that will break the CommonJS files.The only solution that I can think of is to ship the ESM bundle as an
.mjs
file, either by renaming the current one or by creating a copy. The file can then be referenced inpackage.json
like this:Workaround
If you are using immer yourself, use
import { produce } from 'immer';
rather thanimport produce from 'immer';
.I have not found a workaround for cases where dependencies whose code you don't control are using immer. A last resort is probably yarn patch.
The text was updated successfully, but these errors were encountered: