Skip to content
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

[Fizz] New Server Rendering Infra #14144

Merged
merged 12 commits into from Nov 30, 2018
Merged

[Fizz] New Server Rendering Infra #14144

merged 12 commits into from Nov 30, 2018

Conversation

@sebmarkbage
Copy link
Member

sebmarkbage commented Nov 8, 2018

This adds a bunch of new stuff related to the build process for the new server renderer (Fizz).

It adds a new package react-stream. The name is temporary (but is nicely owned by @aickin).

This is equivalent to react-reconciler but for server rendering. I considered putting them in the same package but they really shouldn't share anything and splitting them up into folders just make both seem more complicated.

This is used to create a two new entry points.

react-dom/unstable-fizz which is a server renderer for DOM. Can run in Node for Node streams or browsers for WHATWG streams.

There is also a react-noop-rendering/server for tests.

The interesting new twist here is that there is not just a HostConfig (Node.js, Service Worker, other). There's also a FormatConfig (DOM, RN, possibly variations of DOM).

Currently I just copy pasted all the FiberHostConfig overrides to also account for FizzHostConfig and FizzFormatConfig.

The inlinedHostConfigs.js model starts breaking down though. Currently the dom configuration tests the DOM format config + Node host config. However, that means we wouldn't get coverage on DOM format config + Service Worker host config. Maybe that's fine as long as the Service Worker host config is covered by one of the other configurations?

@sebmarkbage sebmarkbage requested a review from gaearon Nov 8, 2018
@sizebot

This comment has been minimized.

Copy link

sizebot commented Nov 8, 2018

ReactDOM: size: 0.0%, gzip: -0.0%

Details of bundled changes.

Comparing: f1bf281...b1182d1

react-dom

File Filesize Diff Gzip Diff Prev Size Current Size Prev Gzip Current Gzip ENV
react-dom.production.min.js 0.0% -0.0% 97.8 KB 97.8 KB 31.84 KB 31.84 KB UMD_PROD
react-dom.profiling.min.js 0.0% -0.0% 100.69 KB 100.69 KB 32.52 KB 32.52 KB UMD_PROFILING
react-dom.production.min.js 0.0% 0.0% 97.79 KB 97.79 KB 31.38 KB 31.38 KB NODE_PROD
ReactDOM-prod.js 0.0% -0.0% 308.18 KB 308.18 KB 56.78 KB 56.78 KB FB_WWW_PROD
ReactDOM-profiling.js 0.0% -0.0% 314.96 KB 314.96 KB 58.17 KB 58.17 KB FB_WWW_PROFILING
react-dom-unstable-fire.production.min.js 0.0% -0.0% 97.81 KB 97.81 KB 31.85 KB 31.85 KB UMD_PROD
react-dom-unstable-fire.profiling.min.js 0.0% -0.0% 100.7 KB 100.7 KB 32.53 KB 32.53 KB UMD_PROFILING
react-dom-unstable-fire.profiling.min.js 0.0% 0.0% 100.8 KB 100.8 KB 31.98 KB 31.98 KB NODE_PROFILING
ReactFire-prod.js 0.0% -0.0% 296.77 KB 296.77 KB 54.35 KB 54.35 KB FB_WWW_PROD
ReactFire-profiling.js 0.0% -0.0% 303.48 KB 303.48 KB 55.8 KB 55.8 KB FB_WWW_PROFILING
react-dom-test-utils.development.js 0.0% -0.0% 44.87 KB 44.87 KB 12.3 KB 12.3 KB UMD_DEV
react-dom-unstable-native-dependencies.production.min.js 0.0% -0.0% 11.01 KB 11.01 KB 3.81 KB 3.81 KB UMD_PROD
react-dom-unstable-native-dependencies.development.js 0.0% 0.0% 60.29 KB 60.29 KB 15.79 KB 15.79 KB NODE_DEV
react-dom-unstable-native-dependencies.production.min.js 0.0% -0.0% 10.75 KB 10.75 KB 3.71 KB 3.7 KB NODE_PROD
react-dom-server.browser.development.js 0.0% -0.0% 123.82 KB 123.82 KB 33.07 KB 33.07 KB UMD_DEV
ReactDOMServer-dev.js 0.0% -0.0% 121.18 KB 121.18 KB 31.79 KB 31.79 KB FB_WWW_DEV
react-dom-unstable-fizz.browser.development.js n/a n/a 0 B 3.63 KB 0 B 1.44 KB UMD_DEV
react-dom-unstable-fizz.browser.production.min.js n/a n/a 0 B 1.21 KB 0 B 706 B UMD_PROD
react-dom-unstable-fizz.browser.development.js n/a n/a 0 B 3.45 KB 0 B 1.39 KB NODE_DEV
react-dom-unstable-fizz.browser.production.min.js n/a n/a 0 B 1.05 KB 0 B 637 B NODE_PROD
react-dom-unstable-fizz.node.development.js n/a n/a 0 B 3.7 KB 0 B 1.42 KB NODE_DEV
react-dom-unstable-fizz.node.production.min.js n/a n/a 0 B 1.1 KB 0 B 667 B NODE_PROD
ReactDOMFizzServer-dev.js n/a n/a 0 B 3.68 KB 0 B 1.4 KB FB_WWW_DEV
ReactDOMFizzServer-prod.js n/a n/a 0 B 2.16 KB 0 B 874 B FB_WWW_PROD

react-noop-renderer

File Filesize Diff Gzip Diff Prev Size Current Size Prev Gzip Current Gzip ENV
react-noop-renderer.development.js 0.0% -0.0% 28.16 KB 28.16 KB 6.15 KB 6.15 KB NODE_DEV
react-noop-renderer-server.development.js n/a n/a 0 B 1.83 KB 0 B 877 B NODE_DEV
react-noop-renderer-server.production.min.js n/a n/a 0 B 813 B 0 B 491 B NODE_PROD

react-stream

File Filesize Diff Gzip Diff Prev Size Current Size Prev Gzip Current Gzip ENV
react-stream.development.js n/a n/a 0 B 4.53 KB 0 B 1.65 KB NODE_DEV
react-stream.production.min.js n/a n/a 0 B 1.2 KB 0 B 664 B NODE_PROD

Generated by 🚫 dangerJS

@@ -0,0 +1,81 @@
/**

This comment has been minimized.

Copy link
@sebmarkbage

sebmarkbage Nov 8, 2018

Author Member

@gaearon I named this ReactFizzRenderer but I don't think it makes sense since we use the term "renderer" to refer to the compiled output or the HostConfig. But Reconciler doesn't make sense since that's exactly what it doesn't do. It does everything but reconcile. Ideas?

This comment has been minimized.

Copy link
@gaearon

gaearon Nov 8, 2018

Member

Umm.. Writer? Streamer? You know like cool kids on YouTube.

This comment has been minimized.

Copy link
@gaearon

gaearon Nov 8, 2018

Member

Or just Server.

const ReactFizzRenderer = require('./src/ReactFizzRenderer');

// TODO: decide on the top-level export form.
// This is hacky but makes it work with both Rollup and Jest.

This comment has been minimized.

Copy link
@acdlite

acdlite Nov 8, 2018

Member

Are we still doing this? I think we switched to

export * from './src/ReactFizzRenderer';

@gaearon

This comment has been minimized.

Copy link
@acdlite

acdlite Nov 8, 2018

Member

Oh, the other entries do that. Maybe I'm confused.

This comment has been minimized.

Copy link
@gaearon

gaearon Nov 8, 2018

Member

I think we do that for packages that are ready to be ESM. But here the actual output will be a function anyway so it doesn’t matter. I guess could work either way.

This comment has been minimized.

Copy link
@acdlite

acdlite Nov 8, 2018

Member

My understanding based on absolutely nothing was that old packages do this because to switch to ESM would be a breaking change. But new packages don't have that restriction.

This comment has been minimized.

Copy link
@sebmarkbage

sebmarkbage Nov 8, 2018

Author Member

I'd love to fix this though. This is probably really bad for inlining/DCE.

@gaearon
gaearon approved these changes Nov 8, 2018
Copy link
Member

gaearon left a comment

Seems legit

@@ -0,0 +1,12 @@
/**

This comment has been minimized.

Copy link
@gaearon

gaearon Nov 8, 2018

Member

Let’s add unstable to the entry point

This comment has been minimized.

Copy link
@sebmarkbage

sebmarkbage Nov 8, 2018

Author Member

To the file name or the method names?

This comment has been minimized.

Copy link
@gaearon

gaearon Nov 8, 2018

Member

I’d add to the file

@@ -29,6 +29,7 @@
"server.js",
"server.browser.js",
"server.node.js",
"fizz.js",

This comment has been minimized.

Copy link
@gaearon

gaearon Nov 8, 2018

Member

Also fizz.node.js?

This comment has been minimized.

Copy link
@sebmarkbage

sebmarkbage Nov 8, 2018

Author Member

hm. Why doesn't this break ReactDOMFizzServer-test.js in build tests? I'll need to look into that.

This comment has been minimized.

Copy link
@gaearon

gaearon Nov 8, 2018

Member

Because npm entry point (see npm folder) directly points the bundle. The entry point above (which you redirect) only used by Jest. So technically this change isn’t even necessary right now. But would be less confusing.

This comment has been minimized.

Copy link
@gaearon

gaearon Nov 8, 2018

Member

For consistency you can make npm/fizz also do a re export of ./fizz.node. Like npm/server does.

@@ -0,0 +1,35 @@
{
"name": "react-stream",

This comment has been minimized.

Copy link
@gaearon

gaearon Nov 8, 2018

Member

Set private to true to not block the sync?

This comment has been minimized.

Copy link
@sebmarkbage

sebmarkbage Nov 8, 2018

Author Member

You mean the release? We still want it in the sync so we can try it out at FB.

This comment has been minimized.

Copy link
@gaearon

gaearon Nov 8, 2018

Member

Ah yes I mean the release

@@ -0,0 +1,81 @@
/**

This comment has been minimized.

Copy link
@gaearon

gaearon Nov 8, 2018

Member

Or just Server.

@@ -0,0 +1,44 @@
/**

This comment has been minimized.

Copy link
@sebmarkbage

sebmarkbage Nov 8, 2018

Author Member

@gaearon I put this in react-stream/src/ which is a bit weird because it's not part of the core algorithm. It's part of a possible host config. I'm not sure this makes sense to put it here but it's not really shared and we really shouldn't make shared a dumping ground.

However, I guess in the future we could have react-stream export preconfigured environments and all you fill in is the format config. E.g. react-stream/index.node.js, react-stream/index.browser.js.

So maybe that makes sense.

This comment has been minimized.

Copy link
@gaearon

gaearon Nov 8, 2018

Member

Sure. We also never got these things quite right from first try so I wouldn’t expect to do it now.

This comment has been minimized.

Copy link
@gaearon

gaearon Nov 30, 2018

Member

Maybe you can add a comment about this? I was just puzzled over this because I forgot.

@sebmarkbage sebmarkbage force-pushed the sebmarkbage:fizz branch from 788de72 to a0fa6e0 Nov 8, 2018
@sebmarkbage sebmarkbage changed the title [WIP][Fizz] New Server Rendering Infra [Fizz] New Server Rendering Infra Nov 8, 2018
@sebmarkbage sebmarkbage force-pushed the sebmarkbage:fizz branch 2 times, most recently from 8bd123b to e65b22f Nov 8, 2018
@sebmarkbage

This comment has been minimized.

Copy link
Member Author

sebmarkbage commented Nov 8, 2018

I also added a browser build. e65b22f

@Ephem

This comment has been minimized.

Copy link
Contributor

Ephem commented Nov 9, 2018

I'm moderately familiar with the current server renderer and after having gone through this I just have to add that I really like this approach for a new renderer! Makes so much sense to me.

@sebmarkbage sebmarkbage force-pushed the sebmarkbage:fizz branch 2 times, most recently from 314a8e0 to 02e7020 Nov 19, 2018
sebmarkbage added 12 commits Nov 1, 2018
Add a new package for react-stream which allows for custom server renderer
outputs. I picked the name because it's a reasonable name but also
because the npm name is currently owned by a friend of the project.

The react-dom build has its own inlined server renderer under the
name `react-dom/fizz`.

There is also a noop renderer to be used for testing. At some point
we might add a public one to test-renderer but for now I don't want to have
to think about public API design for the tests.
We need to separate the format (DOM, React Native, etc) from the host
running the server (Node, Browser, etc).
The Node DOM API is pipeToNodeStream which accepts a writable stream.
Simpler API this way but also avoids having to fork the wrapper config.

Fixes noop builds.
Also use forwarding to it from fizz.js in builds so that tests covers
this.
This lets Fizz render to WHATWG streams. E.g. for rendering in a
Service Worker.

I added react-dom/unstable-fizz.browser as the entry point for this.

Since we now have two configurations of DOM. I had to add another
inlinedHostConfigs configuration called `dom-browser`. The reconciler
treats this configuration the same as `dom`. For stream it checks
against the ReactFizzHostConfigBrowser instead of the Node one.
This is for testing server rendering - on the client.
@sebmarkbage sebmarkbage force-pushed the sebmarkbage:fizz branch from a000c7b to b1182d1 Nov 30, 2018
@sebmarkbage

This comment has been minimized.

Copy link
Member Author

sebmarkbage commented Nov 30, 2018

Since we landed the Fire infra we can land this too.

@sebmarkbage sebmarkbage merged commit 1d25aa5 into facebook:master Nov 30, 2018
1 check passed
1 check passed
ci/circleci Your tests passed on CircleCI!
Details
@krazyjakee krazyjakee mentioned this pull request Dec 9, 2018
jetoneza added a commit to jetoneza/react that referenced this pull request Jan 23, 2019
* [Fizz] Add Flow/Jest/Rollup build infra

Add a new package for react-stream which allows for custom server renderer
outputs. I picked the name because it's a reasonable name but also
because the npm name is currently owned by a friend of the project.

The react-dom build has its own inlined server renderer under the
name `react-dom/fizz`.

There is also a noop renderer to be used for testing. At some point
we might add a public one to test-renderer but for now I don't want to have
to think about public API design for the tests.

* Add FormatConfig too

We need to separate the format (DOM, React Native, etc) from the host
running the server (Node, Browser, etc).

* Basic wiring between Node, Noop and DOM configs

The Node DOM API is pipeToNodeStream which accepts a writable stream.

* Merge host and format config in dynamic react-stream entry point

Simpler API this way but also avoids having to fork the wrapper config.

Fixes noop builds.

* Add setImmediate/Buffer globals to lint config

Used by the server renderer

* Properly include fizz.node.js

Also use forwarding to it from fizz.js in builds so that tests covers
this.

* Make react-stream private since we're not ready to publish

or even name it yet

* Rename Renderer -> Streamer

* Prefix react-dom/fizz with react-dom/unstable-fizz

* Add Fizz Browser host config

This lets Fizz render to WHATWG streams. E.g. for rendering in a
Service Worker.

I added react-dom/unstable-fizz.browser as the entry point for this.

Since we now have two configurations of DOM. I had to add another
inlinedHostConfigs configuration called `dom-browser`. The reconciler
treats this configuration the same as `dom`. For stream it checks
against the ReactFizzHostConfigBrowser instead of the Node one.

* Add Fizz Browser Fixture

This is for testing server rendering - on the client.

* Lower version number to detach it from react-reconciler version
n8schloss added a commit to n8schloss/react that referenced this pull request Jan 31, 2019
* [Fizz] Add Flow/Jest/Rollup build infra

Add a new package for react-stream which allows for custom server renderer
outputs. I picked the name because it's a reasonable name but also
because the npm name is currently owned by a friend of the project.

The react-dom build has its own inlined server renderer under the
name `react-dom/fizz`.

There is also a noop renderer to be used for testing. At some point
we might add a public one to test-renderer but for now I don't want to have
to think about public API design for the tests.

* Add FormatConfig too

We need to separate the format (DOM, React Native, etc) from the host
running the server (Node, Browser, etc).

* Basic wiring between Node, Noop and DOM configs

The Node DOM API is pipeToNodeStream which accepts a writable stream.

* Merge host and format config in dynamic react-stream entry point

Simpler API this way but also avoids having to fork the wrapper config.

Fixes noop builds.

* Add setImmediate/Buffer globals to lint config

Used by the server renderer

* Properly include fizz.node.js

Also use forwarding to it from fizz.js in builds so that tests covers
this.

* Make react-stream private since we're not ready to publish

or even name it yet

* Rename Renderer -> Streamer

* Prefix react-dom/fizz with react-dom/unstable-fizz

* Add Fizz Browser host config

This lets Fizz render to WHATWG streams. E.g. for rendering in a
Service Worker.

I added react-dom/unstable-fizz.browser as the entry point for this.

Since we now have two configurations of DOM. I had to add another
inlinedHostConfigs configuration called `dom-browser`. The reconciler
treats this configuration the same as `dom`. For stream it checks
against the ReactFizzHostConfigBrowser instead of the Node one.

* Add Fizz Browser Fixture

This is for testing server rendering - on the client.

* Lower version number to detach it from react-reconciler version
iyegoroff added a commit to iyegoroff/react that referenced this pull request Mar 9, 2019
* [Fizz] Add Flow/Jest/Rollup build infra

Add a new package for react-stream which allows for custom server renderer
outputs. I picked the name because it's a reasonable name but also
because the npm name is currently owned by a friend of the project.

The react-dom build has its own inlined server renderer under the
name `react-dom/fizz`.

There is also a noop renderer to be used for testing. At some point
we might add a public one to test-renderer but for now I don't want to have
to think about public API design for the tests.

* Add FormatConfig too

We need to separate the format (DOM, React Native, etc) from the host
running the server (Node, Browser, etc).

* Basic wiring between Node, Noop and DOM configs

The Node DOM API is pipeToNodeStream which accepts a writable stream.

* Merge host and format config in dynamic react-stream entry point

Simpler API this way but also avoids having to fork the wrapper config.

Fixes noop builds.

* Add setImmediate/Buffer globals to lint config

Used by the server renderer

* Properly include fizz.node.js

Also use forwarding to it from fizz.js in builds so that tests covers
this.

* Make react-stream private since we're not ready to publish

or even name it yet

* Rename Renderer -> Streamer

* Prefix react-dom/fizz with react-dom/unstable-fizz

* Add Fizz Browser host config

This lets Fizz render to WHATWG streams. E.g. for rendering in a
Service Worker.

I added react-dom/unstable-fizz.browser as the entry point for this.

Since we now have two configurations of DOM. I had to add another
inlinedHostConfigs configuration called `dom-browser`. The reconciler
treats this configuration the same as `dom`. For stream it checks
against the ReactFizzHostConfigBrowser instead of the Node one.

* Add Fizz Browser Fixture

This is for testing server rendering - on the client.

* Lower version number to detach it from react-reconciler version
let chunk = chunks[i];
writeChunk(destination, chunk);
}
} finally {

This comment has been minimized.

Copy link
@sompylasar

sompylasar Apr 22, 2019

Contributor

Why doesn't it keep the chunks that failed to be written (due to an exception) in completedChunks to be retried later?

} finally {
completeWriting(destination);
}
close(destination);

This comment has been minimized.

Copy link
@sompylasar

sompylasar Apr 22, 2019

Contributor

Why is close(destination) not called in case of an exception?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked issues

Successfully merging this pull request may close these issues.

None yet

7 participants
You can’t perform that action at this time.