mirror of
https://github.com/zebrajr/react.git
synced 2025-12-07 00:20:28 +01:00
* Update build size * [CS] Clone container instead of new root concept The extra "root" concept is kind of unnecessary. Instead of having a mutable container even in the persistent mode, I'll instead make the container be immutable too and be cloned. Then the "commit" just becomes swapping the previous container for the new one. * Change the signature or persistence again We may need to clone without any updates, e.g. when the children are changed. Passing in the previous node is not enough to recycle since it won't have the up-to-date props and children. It's really only useful to for allocation pooling. * Implement persistent updates This forks the update path for host fibers. For mutation mode we mark them as having an effect. For persistence mode, we clone the stateNode with new props/children. Next I'll do HostRoot and HostPortal. * Refine protocol into a complete and commit phase finalizeContainerChildren will get called at the complete phase. replaceContainer will get called at commit. Also, drop the keepChildren flag. We'll never keep children as we'll never update a container if none of the children has changed. * Implement persistent updates of roots and portals These are both "containers". Normally we rely on placement/deletion effects to deal with insertions into the containers. In the persistent mode we need to clone the container and append all the changed children to it. I needed somewhere to store these new containers before they're committed so I added another field. * Commit persistent work at the end by swapping out the container * Unify cloneOrRecycle Originally I tried to make the recyclable instance nullable but Flow didn't like that and it's kind of sketchy since the instance type might not be nullable. However, the real difference which one we call is depending on whether they are equal. We can just offload that to the renderer. Most of them won't need to know about this at all since they'll always clone or just create new. The ones that do know now have to be careful to compare them so they don't reuse an existing instance but that's probably fine to simplify the implementation and API. * Add persistent noop renderer for testing * Add basic persistent tree test * Test bail out This adds a test for bailouts. This revealed a subtle bug. We don't set the return pointer when stepping into newly created fibers because there can only be one. However, since I'm reusing this mechanism for persistent updates, I'll need to set the return pointer because a bailed out tree won't have the right return pointer. * Test persistent text nodes Found another bug. * Add persistent portal test This creates a bit of an unfortunate feature testing in the unmount branch. That's because we want to trigger nested host deletions in portals in the mutation mode. * Don't consider container when determining portal identity Basically, we can't use the container to determine if we should keep identity and update an existing portal instead of recreate it. Because for persistent containers, there is no permanent identity. This makes it kind of strange to even use portals in this mode. It's probably more ideal to have another concept that has permanent identity rather than trying to swap out containers. * Clear portals when the portal is deleted When a portal gets deleted we need to create a new empty container and replace the current one with the empty one. * Add renderer mode flags for dead code elimination * Simplify ReactNoop fix * Add new type to the host config for persistent configs We need container to stay as the persistent identity of the root atom. So that we can refer to portals over time. Instead, I'll introduce a new type just to temporarily hold the children of a container until they're ready to be committed into the permanent container. Essentially, this is just a fancy array that is not an array so that the host can choose data structure/allocation for it. * Implement new hooks Now containers are singletons and instead their children swap. That way portals can use the container as part of their identity again. * Update build size and error codes * Address comment * Move new files to new location |
||
|---|---|---|
| .. | ||
| __tests__ | ||
| codes.json | ||
| extract-errors.js | ||
| invertObject.js | ||
| README.md | ||
| replace-invariant-error-codes.js | ||
| Types.js | ||
The error code system substitutes React's invariant error messages with error IDs to provide a better debugging support in production. Check out the blog post here.
Note for cutting a new React release
- For each release, we run
yarn build -- --extract-errorsto update the error codes before callingyarn build. The build step usescodes.jsonfor a production (minified) build; there should be no warning likeError message "foo" cannot be foundfor a successful release. - The updated
codes.jsonfile should be synced back to the master branch. The error decoder page in our documentation site usescodes.jsonfrom master; if the json file has been updated, the docs site should also be rebuilt (rake copy_error_codesis included in the defaultrake releasetask). - Be certain to run
yarn build -- --extract-errorsdirectly in the release branch (if not master) to ensure the correct error codes are generated. These error messages might be changed/removed before cutting a new release, and we don't want to add intermediate/temporary error messages tocodes.json. However, if a PR changes an existing error message and there's a specific production test (which is rare), it's ok to updatecodes.jsonfor that. Please useyarn build -- --extract-errorsand don't edit the file manually.
Structure
The error code system consists of 5 parts:
codes.jsoncontains the mapping from IDs to error messages. This file is generated by the Gulp plugin and is used by both the Babel plugin and the error decoder page in our documentation. This file is append-only, which means an existing code in the file will never be changed/removed.extract-errors.jsis an node script that traverses our codebase and updatescodes.json. Use it by callingyarn build -- --extract-errors.replace-invariant-error-codes.jsis a Babel pass that rewrites error messages to IDs for a production (minified) build.reactProdInvariant.jsis the replacement forinvariantin production. This file gets imported by the Babel plugin and should not be used manually.ErrorDecoderComponentis a React component that lives at https://reactjs.org/docs/error-decoder.html. This page takes parameters like?invariant=109&args[]=Fooand displays a corresponding error message. Our documentation site'sRakefilehas a task (bundle exec rake copy_error_codes) for adding the latestcodes.jsonto the error decoder page. This task is included in the defaultbundle exec rake releasetask.