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

React Reconciler Package #10758

Merged
merged 25 commits into from Oct 11, 2017

Conversation

Projects
None yet
@iamdustan
Contributor

iamdustan commented Sep 20, 2017

Alternative approach to #10641. Rather than create the entire packaging and bundling script this exposes the React Reconciler as a factory package so all private+global state is unique per reconciler which solves the original concerns raised by @gaearon in #9103 (comment).

I think it also solves the open question How should we handle React-specific stuff pretty well since it doesn’t change the current rollup/build script at this point.

I added a really cheap fixtures/reconciler/* directory that requires some manual node_modules/react-reconciler/cjs/*.js modifications to test for now, but did test both versions.

This also (rather sloppily) modifies the scripts/rollup tasks to special case the react-reconciler wrapping.

TODO:

  • Generate a react-reconciler.js.flow file in the output package so external reconcilers can use flow for writing and maintaining reconcilers.
  • Versioning scheme? I would suspect this to have separate versioning from React and ReactDOM (#10758 (comment))
  • Change rollup/bundle regex match to a bundle type enum #10758 (comment)
  • Unbreak the build

cc @gaearon @bvaughn

@bvaughn

Some thoughts 😄

Show outdated Hide outdated packages/react-reconciler/package.json
Show outdated Hide outdated fixtures/reconciler/README.md
Show outdated Hide outdated packages/react-reconciler/README.md
Show outdated Hide outdated fixtures/reconciler/package.json
@gaearon

This comment has been minimized.

Show comment
Hide comment
@gaearon

gaearon Sep 20, 2017

Member

Looks like this broke the core build? yarn build -- core --type=FB

Member

gaearon commented Sep 20, 2017

Looks like this broke the core build? yarn build -- core --type=FB

@iamdustan

This comment has been minimized.

Show comment
Hide comment
@iamdustan

iamdustan Sep 21, 2017

Contributor

cc-ing @sebmarkbage / @sophiebits from convo in #9103 in case you didn’t see this PR which is more or less the model Dan was referring to at #9103 (comment)

Contributor

iamdustan commented Sep 21, 2017

cc-ing @sebmarkbage / @sophiebits from convo in #9103 in case you didn’t see this PR which is more or less the model Dan was referring to at #9103 (comment)

@iamdustan

This comment has been minimized.

Show comment
Hide comment
@iamdustan

iamdustan Sep 21, 2017

Contributor

Only thing left that I know that would be nice is generating the index.js.flow file in the output package, but everything else should be covered.

Contributor

iamdustan commented Sep 21, 2017

Only thing left that I know that would be nice is generating the index.js.flow file in the output package, but everything else should be covered.

@gaearon

This comment has been minimized.

Show comment
Hide comment
@gaearon

gaearon Sep 21, 2017

Member

Can you fix the CI?

Member

gaearon commented Sep 21, 2017

Can you fix the CI?

@iamdustan

This comment has been minimized.

Show comment
Hide comment
@iamdustan

iamdustan Sep 21, 2017

Contributor
Error: spawnSync ~/react/node_modules/.bin/prettier E2BIG
    at exports._errnoException (util.js:1022:11)
    ...

getting this error when prettier is ran. 🤔

Contributor

iamdustan commented Sep 21, 2017

Error: spawnSync ~/react/node_modules/.bin/prettier E2BIG
    at exports._errnoException (util.js:1022:11)
    ...

getting this error when prettier is ran. 🤔

@gaearon

This comment has been minimized.

Show comment
Hide comment
@gaearon

gaearon Sep 22, 2017

Member

I don't think we call the result of calling the reconciler "a reconciler" :-) Sorry for the confusion.

The result is a Renderer. Maybe the exported thing could be called RendererPublicAPI?

Member

gaearon commented Sep 22, 2017

I don't think we call the result of calling the reconciler "a reconciler" :-) Sorry for the confusion.

The result is a Renderer. Maybe the exported thing could be called RendererPublicAPI?

@bvaughn

This comment has been minimized.

Show comment
Hide comment
@bvaughn

bvaughn Sep 22, 2017

Contributor

Agreed! "reconciler" may not be the most user-friendly name for the API.

Just an idea, but what about something like create-react-renderer (following the create-react-app name)? Too different from all of the other react-* names?

import createReactRenderer from 'create-react-renderer';

const Renderer = createReactRenderer(config);
Contributor

bvaughn commented Sep 22, 2017

Agreed! "reconciler" may not be the most user-friendly name for the API.

Just an idea, but what about something like create-react-renderer (following the create-react-app name)? Too different from all of the other react-* names?

import createReactRenderer from 'create-react-renderer';

const Renderer = createReactRenderer(config);
@iamdustan

This comment has been minimized.

Show comment
Hide comment
@iamdustan

iamdustan Sep 22, 2017

Contributor

I would imagine a create-react-renderer to be similar to the original proposal that includes all the rollup/dev tooling to package and publish a renderer.

Contributor

iamdustan commented Sep 22, 2017

I would imagine a create-react-renderer to be similar to the original proposal that includes all the rollup/dev tooling to package and publish a renderer.

@gaearon

This comment has been minimized.

Show comment
Hide comment
@gaearon

gaearon Sep 25, 2017

Member

I'd like to figure out a way to have a testing procedure that doesn't ask folks to edit node_modules. It should be possible to write a smoke test that creates two renderers (e.g. A and B), and then renders something with A while we're inside a component being rendered by B. I think this should be enough to mess up the (shared) context stack.

Member

gaearon commented Sep 25, 2017

I'd like to figure out a way to have a testing procedure that doesn't ask folks to edit node_modules. It should be possible to write a smoke test that creates two renderers (e.g. A and B), and then renders something with A while we're inside a component being rendered by B. I think this should be enough to mess up the (shared) context stack.

@gaearon

This comment has been minimized.

Show comment
Hide comment
@gaearon

gaearon Sep 25, 2017

Member

Or, perhaps, we shouldn't focus on the context at all. After all this particular case can be fixed. If you manually verified wrapping it in a closure works (why wouldn't it), this should be enough for now.

Instead we should have a fixture that lets us check that the reconciler package is not completely borked. For example by declaring a very simple renderer and writing a Node script that verifies it renders something.

Member

gaearon commented Sep 25, 2017

Or, perhaps, we shouldn't focus on the context at all. After all this particular case can be fixed. If you manually verified wrapping it in a closure works (why wouldn't it), this should be enough for now.

Instead we should have a fixture that lets us check that the reconciler package is not completely borked. For example by declaring a very simple renderer and writing a Node script that verifies it renders something.

@iamdustan

This comment has been minimized.

Show comment
Hide comment
@iamdustan

iamdustan Sep 25, 2017

Contributor

Do you want that done before this is merged?

Two ideas:

  • do something like what you’ve done for dev mode testing for react devtools. E.g. add an empty assignment on to the exports so we can check it from the outside.
  • have the test-renderer use this package to dogfood it and verify it works. (or just copy-paste the non-internals part of the test-renderer out into the test fixture)
Contributor

iamdustan commented Sep 25, 2017

Do you want that done before this is merged?

Two ideas:

  • do something like what you’ve done for dev mode testing for react devtools. E.g. add an empty assignment on to the exports so we can check it from the outside.
  • have the test-renderer use this package to dogfood it and verify it works. (or just copy-paste the non-internals part of the test-renderer out into the test fixture)
@gaearon

This comment has been minimized.

Show comment
Hide comment
@gaearon

gaearon Sep 25, 2017

Member

I want to have some way to test it before this is merged since we're going to start doing releases very soon. I would suggest copy-pasting noop renderer and having a simple test that verifies it works.

Member

gaearon commented Sep 25, 2017

I want to have some way to test it before this is merged since we're going to start doing releases very soon. I would suggest copy-pasting noop renderer and having a simple test that verifies it works.

@iamdustan

This comment has been minimized.

Show comment
Hide comment
@iamdustan

iamdustan Sep 25, 2017

Contributor

Something like 2b196c4? It’s still not fully automatic so I could look into running the ReactIncremental-test.js there too since that is the only consumer I could find of ReactNoop in the codebase.

Also, ReactInstanceMap is private (as far as I know) so I simply commented out the findInstance method of the public interface with a comment s that the drift from the actual noop renderer has some sort of paper trail.

Contributor

iamdustan commented Sep 25, 2017

Something like 2b196c4? It’s still not fully automatic so I could look into running the ReactIncremental-test.js there too since that is the only consumer I could find of ReactNoop in the codebase.

Also, ReactInstanceMap is private (as far as I know) so I simply commented out the findInstance method of the public interface with a comment s that the drift from the actual noop renderer has some sort of paper trail.

@gaearon

This comment has been minimized.

Show comment
Hide comment
@gaearon

gaearon Sep 26, 2017

Member

I don't think we need to port the unit test. A simple smoke test verifying it doesn't instacrash rendering a simple component is enough. You can also delete all irrelevant code there.

Member

gaearon commented Sep 26, 2017

I don't think we need to port the unit test. A simple smoke test verifying it doesn't instacrash rendering a simple component is enough. You can also delete all irrelevant code there.

@iamdustan

This comment has been minimized.

Show comment
Hide comment
@iamdustan

iamdustan Sep 26, 2017

Contributor

To make sure I’m understanding you, is something like this in the fixtures renderer what you’re thinking?

const Renderer = require('./noop');

expect(() => Renderer.render(<element />)).not.toThrow();

Do I need to tie that into any other command that is run during releases?

Contributor

iamdustan commented Sep 26, 2017

To make sure I’m understanding you, is something like this in the fixtures renderer what you’re thinking?

const Renderer = require('./noop');

expect(() => Renderer.render(<element />)).not.toThrow();

Do I need to tie that into any other command that is run during releases?

@iamdustan

This comment has been minimized.

Show comment
Hide comment
@iamdustan

iamdustan Sep 27, 2017

Contributor

@gaearon pinging in case you missed --^. Happy to make the change as soon as I know I’m doing what you expect 😄

Contributor

iamdustan commented Sep 27, 2017

@gaearon pinging in case you missed --^. Happy to make the change as soon as I know I’m doing what you expect 😄

@gaearon

This comment has been minimized.

Show comment
Hide comment
@gaearon

gaearon Sep 27, 2017

Member

Noop renderer renders to a tree in memory. It would just be nice to verify basic sanity of that tree. e.g. that it created "hello world" host instance.

Member

gaearon commented Sep 27, 2017

Noop renderer renders to a tree in memory. It would just be nice to verify basic sanity of that tree. e.g. that it created "hello world" host instance.

@iamdustan

This comment has been minimized.

Show comment
Hide comment
@iamdustan

iamdustan Sep 28, 2017

Contributor

Should I delete most of the noop renderer as well to simplify that? Or will it be useful to expand this test to include some of the async rendering tests as those become solidified?

Contributor

iamdustan commented Sep 28, 2017

Should I delete most of the noop renderer as well to simplify that? Or will it be useful to expand this test to include some of the async rendering tests as those become solidified?

@worawit15379

This comment has been minimized.

Show comment
Hide comment
@worawit15379

worawit15379 Nov 1, 2017

เปิด

worawit15379 commented on scripts/rollup/results.json in a935605 Nov 1, 2017

เปิด

@dakom

This comment has been minimized.

Show comment
Hide comment
@dakom

dakom Nov 13, 2017

woohoo, just noticed this is live: https://www.npmjs.com/package/react-reconciler :)

dakom commented Nov 13, 2017

woohoo, just noticed this is live: https://www.npmjs.com/package/react-reconciler :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment