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
Using immer from libraries can lead to silent bugs in downstream projects #322
Comments
Thanks for reporting this! 👍 You want The problem (as you've identified) is that To avoid this, we can use the global scope to share Immer's internal symbols between all installations of For |
The `nothing` symbol is still not portable across installations, since it never escapes any producer that returns it. The only reason this could be an issue is if an Immer-using library transparently wraps a user's function and asks them to install their own copy of Immer if they want to return `nothing` (in that case, the library should instead re-export `nothing` for its users). Fixes #322
I Agree :)
…On Tue, Mar 5, 2019 at 2:36 PM Alec Larson ***@***.***> wrote:
Thanks for reporting this! 👍
You want capitalizeNameSubreducer to behave differently based on whether
the object passed to it is a draft. When a draft is passed, mutate it
directly. Otherwise, produce a copy.
The problem (as you've identified) is that isDraft always returns false
for drafts created by a separate installation of immer. This is
unintended behavior, and I consider it a bug.
To avoid this, we can use the global scope to share Immer's internal
symbols between all installations of immer. Thoughts on this, @mweststrate
<https://github.com/mweststrate>?
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#322 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/ABvGhMn6DcyLZtfA3OozdQZ7D_hzT-gAks5vTnL2gaJpZM4beTDG>
.
|
The `nothing` symbol is still not portable across installations, since it never escapes any producer that returns it. The only reason this could be an issue is if an Immer-using library transparently wraps a user's function and asks them to install their own copy of Immer if they want to return `nothing` (in that case, the library should instead re-export `nothing` for its users). Fixes #322
🎉 This issue has been resolved in version 2.1.1 🎉 The release is available on: Your semantic-release bot 📦🚀 |
Fantastic, thank you! |
setUseProxies(true)
)setUseProxies(false)
)Context: I have a Redux subreducer that uses immer and I'm making it available to other Redux projects as a packaged library. It's up to downstream whether to also use immer or not. This sort of works, with some precautions, but I suspect I'll hit serious trouble later.
A contrived example of a downstream project that uses both immer and the library:
Downstream project that uses the library but doesn't use immer:
(Downstream projects know that
capitalizeNameSubreducer
expects a certain state shape and are fine with that.)The subreducer itself:
The problem is in how to deal with the dependency on immer within the
capitalize-name-subreducer
package.The short story is that any scenario that leads to two copies of immer (
project/node_modules/immer
andproject/node_modules/library/node_modules/immer
) won't work, because (if I get it right) immer uses symbols to mark objects as drafts and they are not===
across modules.If immer is among the library's peerDependencies...
It works but it's one more thing for downstream authors to be aware of and fairly arbitrary if they're not using immer already.
If immer is among the library's dependencies...
It works if:
capitalize-name-subreducer
It does not work if:
yarn link
ornpm link
(which always leads to two installations of immer being present, even when they can in principle de-duplicated)Case 2 is an annoyance but case 1 is a potentially life endangering threat. (Ok, slightly exaggerating here.) Imagine downstream project and library using
immer@2
. Two months later library usesimmer@3
. Project does an upgrade and brings inimmer@3
as transitive dependency, whileimmer@2
still is present. Stuff stops working with no clear indication as to why.If immer is among the library's devDependencies...
This works if:
This does not work if:
The reason it does not work is, of course, that installing the library doesn't bring its devDependencies into the downstream project, so if immer isn't already there, it will be missing.
Reproduction for (working) scenario "immer not in library's node_modules, immer in project's node_modules":
Reproduction for (non-working) scenario "immer in library's node_modules, immer in project's_modules" (note: this leverages the bug^Wfact that adding a local dependency with yarn doesn't dedupe modules no-matter-what, to simulate the scenario):
Apologies for the lengthy description but it was either giving up length or accuracy.
Is there some strategy to address the issue?
The text was updated successfully, but these errors were encountered: