-
Notifications
You must be signed in to change notification settings - Fork 10.3k
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
Use a WeakMap to store parent of subobjects in nodes #2812
Conversation
Deploy preview ready! Built with commit 11c2dd3 |
Deploy preview ready! Built with commit 11c2dd3 |
thanks for the PR! I think the better option to fix this is probably to have createNode not mutate the input in the first place...or whereever the mutation is happening. We don't necessarily want to work around that behavior when it probably isn't intentional in the first place |
f4e52bd
to
12d14d6
Compare
Updated PR with suggested change. Previous version of "fix" just in case for reference - pieh@f4e52bd |
packages/gatsby/src/redux/actions.js
Outdated
// Make deep copy of node before mutating it, this makes sure original object | ||
// will not fail validation due to unexpected fields. | ||
// (reference: https://github.com/gatsbyjs/gatsby/issues/2772 ) | ||
node = _.cloneDeep(node) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry! this isn't what I meant. I'd like to avoid a deep clone entirely because it can very expensive, and we have no idea what content or structure nodes will have. Instead I'd like to find the places where mutation is happening and remove them, rather then make mutation safe.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oh, right, I had brain lag or something - now i read your comment again and think to myself how did I understand it the way I did before ...
So if gatsby shouldn't mutate then you would have revert this - 656299d
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmmmm yeah we could move that code into a library that then is used in source/transformer plugins that need it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah this is a bit tough, since we sort of need to hope consumers play nice and don't mutate...the problem tho is that enforcing generally it is pretty costly especially here where nodes may be/are complex data structures.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you elaborate a little what problem 656299d fixed? Is it needed in all nodes or is just for source/transformers plugins? Maybe I could just change createNode and add argument to opt-out of adding _PARENT
fields and just opt-out of it for plugin data? This would avoid any cloning at all (obviously prefered solution).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See this comment #2567 (comment) It's basically a workaround for GraphQL as it doesn't let you know what the parent of a sub-object is which breaks Gatsby in subtle ways.
Avoiding mutating plugins would be a great start. So yeah, question is should we opt-in to adding _PARENT or opt-out.
I think it's a generally useful/needed pattern which is why I added it to actions.js so I'm leaning towards opt-out. Thoughts?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe instead of tagging each sub object we could use a WeakMap hashing objects to parent id? e.g. something like:
map = new WeakMap()
eachChildObject(node, obj => {
map.set(obj, node.id)
})
then expose a getParent api perhaps?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ooo that's good! Yeah, that sounds much nicer. @pieh you have time to work on this by chance? I'm pretty strapped for time over next few days / week.
…id as additional field in sub nodes
12d14d6
to
11c2dd3
Compare
updated PR tested against repository linked in #2567 (comment) to check if "parent fix" still works |
🙇 this is awesome! |
Hiya @pieh! 👋 This is definitely late, but on behalf of the entire Gatsby community, I wanted to say thank you for being here. Gatsby is built by awesome people like you. Let us say “thanks” in two ways:
If you have questions, please don’t hesitate to reach out to us: tweet at @gatsbyjs and we’ll come a-runnin’. Thanks again! 💪💜 |
this prevents mutating plugin data that is deeper in object properites
fixes #2772
For context check #2772 and my comment there