From 1d0f9877d778353f801d703f58ec587a91c51c24 Mon Sep 17 00:00:00 2001 From: Sebastian Markbage Date: Wed, 31 Oct 2018 18:41:14 -0700 Subject: [PATCH 01/12] [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. --- packages/react-dom/fizz.js | 16 ++ packages/react-dom/npm/fizz.js | 7 + packages/react-dom/package.json | 1 + .../src/__tests__/ReactDOMFizzServer-test.js | 26 ++ .../src/server/ReactDOMFizzServer.js | 17 ++ .../server/ReactDOMFizzServerHostConfig.js | 14 + packages/react-noop-renderer/npm/server.js | 7 + packages/react-noop-renderer/package.json | 4 +- packages/react-noop-renderer/server.js | 16 ++ .../src/ReactNoopServer.js | 30 +++ packages/react-stream/README.md | 25 ++ packages/react-stream/index.js | 26 ++ packages/react-stream/inline-typed.js | 24 ++ packages/react-stream/inline.dom.js | 11 + packages/react-stream/npm/index.js | 7 + packages/react-stream/package.json | 35 +++ .../react-stream/src/ReactFizzHostConfig.js | 20 ++ .../react-stream/src/ReactFizzRenderer.js | 22 ++ .../src/__tests__/ReactServer-test.js | 27 ++ .../src/forks/ReactFizzHostConfig.custom.js | 30 +++ .../src/forks/ReactFizzHostConfig.dom.js | 10 + scripts/flow/createFlowConfigs.js | 8 +- scripts/jest/setupHostConfigs.js | 39 +++ scripts/rollup/bundles.js | 40 +++ scripts/rollup/forks.js | 30 +++ scripts/rollup/results.json | 242 +++++++++++------- scripts/shared/inlinedHostConfigs.js | 14 +- 27 files changed, 650 insertions(+), 98 deletions(-) create mode 100644 packages/react-dom/fizz.js create mode 100644 packages/react-dom/npm/fizz.js create mode 100644 packages/react-dom/src/__tests__/ReactDOMFizzServer-test.js create mode 100644 packages/react-dom/src/server/ReactDOMFizzServer.js create mode 100644 packages/react-dom/src/server/ReactDOMFizzServerHostConfig.js create mode 100644 packages/react-noop-renderer/npm/server.js create mode 100644 packages/react-noop-renderer/server.js create mode 100644 packages/react-noop-renderer/src/ReactNoopServer.js create mode 100644 packages/react-stream/README.md create mode 100644 packages/react-stream/index.js create mode 100644 packages/react-stream/inline-typed.js create mode 100644 packages/react-stream/inline.dom.js create mode 100644 packages/react-stream/npm/index.js create mode 100644 packages/react-stream/package.json create mode 100644 packages/react-stream/src/ReactFizzHostConfig.js create mode 100644 packages/react-stream/src/ReactFizzRenderer.js create mode 100644 packages/react-stream/src/__tests__/ReactServer-test.js create mode 100644 packages/react-stream/src/forks/ReactFizzHostConfig.custom.js create mode 100644 packages/react-stream/src/forks/ReactFizzHostConfig.dom.js diff --git a/packages/react-dom/fizz.js b/packages/react-dom/fizz.js new file mode 100644 index 00000000000..53eb1078b90 --- /dev/null +++ b/packages/react-dom/fizz.js @@ -0,0 +1,16 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @flow + */ + +'use strict'; + +const ReactDOMFizzServer = require('./src/server/ReactDOMFizzServer'); + +// TODO: decide on the top-level export form. +// This is hacky but makes it work with both Rollup and Jest +module.exports = ReactDOMFizzServer.default || ReactDOMFizzServer; diff --git a/packages/react-dom/npm/fizz.js b/packages/react-dom/npm/fizz.js new file mode 100644 index 00000000000..616592945b1 --- /dev/null +++ b/packages/react-dom/npm/fizz.js @@ -0,0 +1,7 @@ +'use strict'; + +if (process.env.NODE_ENV === 'production') { + module.exports = require('./cjs/react-dom-fizz.production.min.js'); +} else { + module.exports = require('./cjs/react-dom-fizz.development.js'); +} diff --git a/packages/react-dom/package.json b/packages/react-dom/package.json index 6c4e6255acc..1c513ee5d78 100644 --- a/packages/react-dom/package.json +++ b/packages/react-dom/package.json @@ -30,6 +30,7 @@ "server.js", "server.browser.js", "server.node.js", + "fizz.js", "test-utils.js", "unstable-fire.js", "unstable-native-dependencies.js", diff --git a/packages/react-dom/src/__tests__/ReactDOMFizzServer-test.js b/packages/react-dom/src/__tests__/ReactDOMFizzServer-test.js new file mode 100644 index 00000000000..91fe1bd2fe9 --- /dev/null +++ b/packages/react-dom/src/__tests__/ReactDOMFizzServer-test.js @@ -0,0 +1,26 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @emails react-core + * @jest-environment node + */ + +'use strict'; + +let React; +let ReactDOMFizzServer; + +describe('ReactDOMFizzServer', () => { + beforeEach(() => { + jest.resetModules(); + React = require('react'); + ReactDOMFizzServer = require('react-dom/fizz'); + }); + + it('should call render', () => { + ReactDOMFizzServer.render(
hello world
); + }); +}); diff --git a/packages/react-dom/src/server/ReactDOMFizzServer.js b/packages/react-dom/src/server/ReactDOMFizzServer.js new file mode 100644 index 00000000000..d760dfc3583 --- /dev/null +++ b/packages/react-dom/src/server/ReactDOMFizzServer.js @@ -0,0 +1,17 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @flow + */ + +import {createRequest, readBuffer} from 'react-stream/inline.dom'; + +function render() { + readBuffer(createRequest({})); +} +export default { + render, +}; diff --git a/packages/react-dom/src/server/ReactDOMFizzServerHostConfig.js b/packages/react-dom/src/server/ReactDOMFizzServerHostConfig.js new file mode 100644 index 00000000000..fae87abf486 --- /dev/null +++ b/packages/react-dom/src/server/ReactDOMFizzServerHostConfig.js @@ -0,0 +1,14 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @flow + */ + +export type RequestInfo = {}; + +export function ping(request: RequestInfo) {} + +export function write(request: RequestInfo) {} diff --git a/packages/react-noop-renderer/npm/server.js b/packages/react-noop-renderer/npm/server.js new file mode 100644 index 00000000000..1abd91cef12 --- /dev/null +++ b/packages/react-noop-renderer/npm/server.js @@ -0,0 +1,7 @@ +'use strict'; + +if (process.env.NODE_ENV === 'production') { + module.exports = require('./cjs/react-noop-renderer-server.production.min.js'); +} else { + module.exports = require('./cjs/react-noop-renderer-server.development.js'); +} diff --git a/packages/react-noop-renderer/package.json b/packages/react-noop-renderer/package.json index 51b668a366b..87f4ba431be 100644 --- a/packages/react-noop-renderer/package.json +++ b/packages/react-noop-renderer/package.json @@ -10,7 +10,8 @@ "object-assign": "^4.1.1", "prop-types": "^15.6.2", "regenerator-runtime": "^0.11.0", - "react-reconciler": "*" + "react-reconciler": "*", + "react-stream": "*" }, "peerDependencies": { "react": "^16.0.0" @@ -21,6 +22,7 @@ "build-info.json", "index.js", "persistent.js", + "server.js", "cjs/" ] } diff --git a/packages/react-noop-renderer/server.js b/packages/react-noop-renderer/server.js new file mode 100644 index 00000000000..1665a0767a0 --- /dev/null +++ b/packages/react-noop-renderer/server.js @@ -0,0 +1,16 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @flow + */ + +'use strict'; + +const ReactNoopServer = require('./src/ReactNoopServer'); + +// TODO: decide on the top-level export form. +// This is hacky but makes it work with both Rollup and Jest. +module.exports = ReactNoopServer.default || ReactNoopServer; diff --git a/packages/react-noop-renderer/src/ReactNoopServer.js b/packages/react-noop-renderer/src/ReactNoopServer.js new file mode 100644 index 00000000000..69b553071d0 --- /dev/null +++ b/packages/react-noop-renderer/src/ReactNoopServer.js @@ -0,0 +1,30 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @flow + */ + +/** + * This is a renderer of React that doesn't have a render target output. + * It is useful to demonstrate the internals of the reconciler in isolation + * and for testing semantics of reconciliation separate from the host + * environment. + */ + +import ReactFizzRenderer from 'react-stream'; + +const ReactNoopServer = ReactFizzRenderer({ + ping() {}, + write() {}, +}); + +function render(children: React$Element) { + ReactNoopServer.readBuffer(ReactNoopServer.createRequest({})); +} + +export default { + render, +}; diff --git a/packages/react-stream/README.md b/packages/react-stream/README.md new file mode 100644 index 00000000000..087175bb7dc --- /dev/null +++ b/packages/react-stream/README.md @@ -0,0 +1,25 @@ +# react-stream + +This is an experimental package for creating custom React streaming server renderers. + +**Its API is not as stable as that of React, React Native, or React DOM, and does not follow the common versioning scheme.** + +**Use it at your own risk.** + +## API + +```js +var Renderer = require('react-stream'); + +var HostConfig = { + // You'll need to implement some methods here. + // See below for more information and examples. +}; + +var MyRenderer = Renderer(HostConfig); + +var RendererPublicAPI = { +}; + +module.exports = RendererPublicAPI; +``` diff --git a/packages/react-stream/index.js b/packages/react-stream/index.js new file mode 100644 index 00000000000..c807d4ed5aa --- /dev/null +++ b/packages/react-stream/index.js @@ -0,0 +1,26 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +// This entry point is intentionally not typed. It exists only for third-party +// renderers. The renderers we ship (such as React DOM) instead import a named +// "inline" entry point (for example, `react-stream/inline.dom`). It uses +// the same code, but the Flow configuration redirects the host config to its +// real implementation so we can check it against exact intended host types. +// +// Only one renderer (the one you passed to `yarn flow `) is fully +// type-checked at any given time. The Flow config maps the +// `react-stream/inline.` import (which is *not* Flow typed) to +// `react-stream/inline-typed` (which *is*) for the current renderer. +// On CI, we run Flow checks for each renderer separately. + +'use strict'; + +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. +module.exports = ReactFizzRenderer.default || ReactFizzRenderer; diff --git a/packages/react-stream/inline-typed.js b/packages/react-stream/inline-typed.js new file mode 100644 index 00000000000..8bee7e9f3b4 --- /dev/null +++ b/packages/react-stream/inline-typed.js @@ -0,0 +1,24 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @flow + */ + +// This file must have the Flow annotation. +// +// This is the Flow-typed entry point for the renderer. It should not be +// imported directly in code. Instead, our Flow configuration uses this entry +// point for the currently checked renderer (the one you passed to `yarn flow`). +// +// For example, if you run `yarn flow dom`, `react-stream/inline.dom` points +// to this module (and thus will be considered Flow-typed). But other renderers +// (e.g. `react-test-renderer`) will see stream as untyped during the check. +// +// We can't make all entry points typed at the same time because different +// renderers have different host config types. So we check them one by one. +// We run Flow on all renderers on CI. + +export * from './src/ReactFizzRenderer'; diff --git a/packages/react-stream/inline.dom.js b/packages/react-stream/inline.dom.js new file mode 100644 index 00000000000..2516cd5d7fb --- /dev/null +++ b/packages/react-stream/inline.dom.js @@ -0,0 +1,11 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +// This file intentionally does *not* have the Flow annotation. +// Don't add it. See `./inline-typed.js` for an explanation. + +export * from './src/ReactFizzRenderer'; diff --git a/packages/react-stream/npm/index.js b/packages/react-stream/npm/index.js new file mode 100644 index 00000000000..fb7a252fd61 --- /dev/null +++ b/packages/react-stream/npm/index.js @@ -0,0 +1,7 @@ +'use strict'; + +if (process.env.NODE_ENV === 'production') { + module.exports = require('./cjs/react-stream.production.min.js'); +} else { + module.exports = require('./cjs/react-stream.development.js'); +} diff --git a/packages/react-stream/package.json b/packages/react-stream/package.json new file mode 100644 index 00000000000..3d005bd6407 --- /dev/null +++ b/packages/react-stream/package.json @@ -0,0 +1,35 @@ +{ + "name": "react-stream", + "description": "React package for creating custom streaming server renderers.", + "version": "0.16.0", + "keywords": [ + "react" + ], + "homepage": "https://reactjs.org/", + "bugs": "https://github.com/facebook/react/issues", + "license": "MIT", + "files": [ + "LICENSE", + "README.md", + "index.js", + "cjs/" + ], + "main": "index.js", + "repository": "facebook/react", + "engines": { + "node": ">=0.10.0" + }, + "peerDependencies": { + "react": "^16.0.0" + }, + "dependencies": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1", + "prop-types": "^15.6.2" + }, + "browserify": { + "transform": [ + "loose-envify" + ] + } +} diff --git a/packages/react-stream/src/ReactFizzHostConfig.js b/packages/react-stream/src/ReactFizzHostConfig.js new file mode 100644 index 00000000000..ae70ca5cda9 --- /dev/null +++ b/packages/react-stream/src/ReactFizzHostConfig.js @@ -0,0 +1,20 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @flow + */ + +import invariant from 'shared/invariant'; + +// We expect that our Rollup, Jest, and Flow configurations +// always shim this module with the corresponding host config +// (either provided by a renderer, or a generic shim for npm). +// +// We should never resolve to this file, but it exists to make +// sure that if we *do* accidentally break the configuration, +// the failure isn't silent. + +invariant(false, 'This module must be shimmed by a specific renderer.'); diff --git a/packages/react-stream/src/ReactFizzRenderer.js b/packages/react-stream/src/ReactFizzRenderer.js new file mode 100644 index 00000000000..d1cda1543e0 --- /dev/null +++ b/packages/react-stream/src/ReactFizzRenderer.js @@ -0,0 +1,22 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @flow + */ + +import type {RequestInfo} from './ReactFizzHostConfig'; +import {ping, write} from './ReactFizzHostConfig'; + +type OpaqueRequest = {requestInfo: RequestInfo}; + +export function createRequest(requestInfo: RequestInfo): OpaqueRequest { + return {requestInfo}; +} + +export function readBuffer(request: OpaqueRequest): void { + ping(request.requestInfo); + write(request.requestInfo); +} diff --git a/packages/react-stream/src/__tests__/ReactServer-test.js b/packages/react-stream/src/__tests__/ReactServer-test.js new file mode 100644 index 00000000000..20a85f77d32 --- /dev/null +++ b/packages/react-stream/src/__tests__/ReactServer-test.js @@ -0,0 +1,27 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @emails react-core + * @jest-environment node + */ + +'use strict'; + +let React; +let ReactNoopServer; + +describe('ReactServer', () => { + beforeEach(() => { + jest.resetModules(); + + React = require('react'); + ReactNoopServer = require('react-noop-renderer/server'); + }); + + it('can call render', () => { + ReactNoopServer.render(
hello world
); + }); +}); diff --git a/packages/react-stream/src/forks/ReactFizzHostConfig.custom.js b/packages/react-stream/src/forks/ReactFizzHostConfig.custom.js new file mode 100644 index 00000000000..4ee36f4cf41 --- /dev/null +++ b/packages/react-stream/src/forks/ReactFizzHostConfig.custom.js @@ -0,0 +1,30 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @flow + */ + +// This is a host config that's used for the `react-stream` package on npm. +// It is only used by third-party renderers. +// +// Its API lets you pass the host config as an argument. +// However, inside the `react-stream` we treat host config as a module. +// This file is a shim between two worlds. +// +// It works because the `react-stream` bundle is wrapped in something like: +// +// module.exports = function ($$$config) { +// /* renderer code */ +// } +// +// So `$$$config` looks like a global variable, but it's +// really an argument to a top-level wrapping function. + +declare var $$$hostConfig: any; +export opaque type RequestInfo = mixed; // eslint-disable-line no-undef + +export const ping = $$$hostConfig.ping; +export const write = $$$hostConfig.write; diff --git a/packages/react-stream/src/forks/ReactFizzHostConfig.dom.js b/packages/react-stream/src/forks/ReactFizzHostConfig.dom.js new file mode 100644 index 00000000000..493b887abc7 --- /dev/null +++ b/packages/react-stream/src/forks/ReactFizzHostConfig.dom.js @@ -0,0 +1,10 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @flow + */ + +export * from 'react-dom/src/server/ReactDOMFizzServerHostConfig'; diff --git a/scripts/flow/createFlowConfigs.js b/scripts/flow/createFlowConfigs.js index d02ba58c9b5..e7308fd7c21 100644 --- a/scripts/flow/createFlowConfigs.js +++ b/scripts/flow/createFlowConfigs.js @@ -18,7 +18,7 @@ const configTemplate = fs .readFileSync(__dirname + '/config/flowconfig') .toString(); -function writeConfig(renderer) { +function writeConfig(renderer, isFizzSupported) { const folder = __dirname + '/' + renderer; mkdirp.sync(folder); @@ -27,6 +27,10 @@ function writeConfig(renderer) { ` module.name_mapper='react-reconciler/inline.${renderer}$$' -> 'react-reconciler/inline-typed' module.name_mapper='ReactFiberHostConfig$$' -> 'forks/ReactFiberHostConfig.${renderer}' +module.name_mapper='react-stream/inline.${renderer}$$' -> 'react-stream/inline-typed' +module.name_mapper='ReactFizzHostConfig$$' -> 'forks/ReactFizzHostConfig.${ + isFizzSupported ? renderer : 'custom' + }' `.trim(), ); @@ -61,6 +65,6 @@ ${disclaimer} // so that we can run those checks in parallel if we want. inlinedHostConfigs.forEach(rendererInfo => { if (rendererInfo.isFlowTyped) { - writeConfig(rendererInfo.shortName); + writeConfig(rendererInfo.shortName, rendererInfo.isFizzSupported); } }); diff --git a/scripts/jest/setupHostConfigs.js b/scripts/jest/setupHostConfigs.js index 888fade8481..d0e9e405641 100644 --- a/scripts/jest/setupHostConfigs.js +++ b/scripts/jest/setupHostConfigs.js @@ -17,6 +17,13 @@ jest.mock('react-reconciler/persistent', () => { return require.requireActual('react-reconciler/persistent'); }; }); +const shimFizzHostConfigPath = 'react-stream/src/ReactFizzHostConfig'; +jest.mock('react-stream', () => { + return config => { + jest.mock(shimFizzHostConfigPath, () => config); + return require.requireActual('react-stream'); + }; +}); // But for inlined host configs (such as React DOM, Native, etc), we // mock their named entry points to establish a host config mapping. @@ -55,6 +62,38 @@ inlinedHostConfigs.forEach(rendererInfo => { return renderer; }); + + if (rendererInfo.isFizzSupported) { + jest.mock(`react-stream/inline.${rendererInfo.shortName}`, () => { + let hasImportedShimmedConfig = false; + + // We want the renderer to pick up the host config for this renderer. + jest.mock(shimFizzHostConfigPath, () => { + hasImportedShimmedConfig = true; + return require.requireActual( + `react-stream/src/forks/ReactFizzHostConfig.${ + rendererInfo.shortName + }.js` + ); + }); + + const renderer = require.requireActual('react-stream'); + // If the shimmed config factory function above has not run, + // it means this test file loads more than one renderer + // but doesn't reset modules between them. This won't work. + if (!hasImportedShimmedConfig) { + throw new Error( + `Could not import the "${rendererInfo.shortName}" renderer ` + + `in this suite because another renderer has already been ` + + `loaded earlier. Call jest.resetModules() before importing any ` + + `of the following entry points:\n\n` + + rendererInfo.entryPoints.map(entry => ` * ${entry}`) + ); + } + + return renderer; + }); + } }); // Make it possible to import this module inside diff --git a/scripts/rollup/bundles.js b/scripts/rollup/bundles.js index c250600b992..cf44a66d6a4 100644 --- a/scripts/rollup/bundles.js +++ b/scripts/rollup/bundles.js @@ -158,6 +158,15 @@ const bundles = [ externals: ['react', 'stream'], }, + /******* React DOM Fizz Server *******/ + { + bundleTypes: [NODE_DEV, NODE_PROD, FB_WWW_DEV, FB_WWW_PROD], + moduleType: RENDERER, + entry: 'react-dom/fizz', + global: 'ReactDOMFizzServer', + externals: ['react'], + }, + /******* React ART *******/ { bundleTypes: [ @@ -320,6 +329,28 @@ const bundles = [ }), }, + /******* React Noop Server Renderer (used for tests) *******/ + { + bundleTypes: [NODE_DEV, NODE_PROD], + moduleType: RENDERER, + entry: 'react-noop-renderer/server', + global: 'ReactNoopRendererServer', + externals: ['react', 'expect'], + // React Noop uses generators. However GCC currently + // breaks when we attempt to use them in the output. + // So we precompile them with regenerator, and include + // it as a runtime dependency of React Noop. In practice + // this isn't an issue because React Noop is only used + // in our tests. We wouldn't want to do this for any + // public package though. + babel: opts => + Object.assign({}, opts, { + plugins: opts.plugins.concat([ + require.resolve('babel-plugin-transform-regenerator'), + ]), + }), + }, + /******* React Reconciler *******/ { bundleTypes: [NODE_DEV, NODE_PROD], @@ -338,6 +369,15 @@ const bundles = [ externals: ['react'], }, + /******* React Stream *******/ + { + bundleTypes: [NODE_DEV, NODE_PROD], + moduleType: RECONCILER, + entry: 'react-stream', + global: 'ReactStream', + externals: ['react'], + }, + /******* Reflection *******/ { moduleType: RENDERER_UTILS, diff --git a/scripts/rollup/forks.js b/scripts/rollup/forks.js index bbb22d7a8c9..b19d7688cf9 100644 --- a/scripts/rollup/forks.js +++ b/scripts/rollup/forks.js @@ -272,6 +272,36 @@ const forks = Object.freeze({ ); }, + 'react-stream/src/ReactFizzHostConfig': ( + bundleType, + entry, + dependencies, + moduleType + ) => { + if (dependencies.indexOf('react-stream') !== -1) { + return null; + } + if (moduleType !== RENDERER && moduleType !== RECONCILER) { + return null; + } + // eslint-disable-next-line no-for-of-loops/no-for-of-loops + for (let rendererInfo of inlinedHostConfigs) { + if (rendererInfo.entryPoints.indexOf(entry) !== -1) { + if (!rendererInfo.isFizzSupported) { + return null; + } + return `react-stream/src/forks/ReactFizzHostConfig.${ + rendererInfo.shortName + }.js`; + } + } + throw new Error( + 'Expected ReactFizzHostConfig to always be replaced with a shim, but ' + + `found no mention of "${entry}" entry point in ./scripts/shared/inlinedHostConfigs.js. ` + + 'Did you mean to add it there to associate it with a specific renderer?' + ); + }, + // We wrap top-level listeners into guards on www. 'react-dom/src/events/EventListener': (bundleType, entry) => { switch (bundleType) { diff --git a/scripts/rollup/results.json b/scripts/rollup/results.json index dabd5feedda..9f08c72b671 100644 --- a/scripts/rollup/results.json +++ b/scripts/rollup/results.json @@ -46,29 +46,29 @@ "filename": "react-dom.development.js", "bundleType": "UMD_DEV", "packageName": "react-dom", - "size": 725515, - "gzip": 167737 + "size": 722087, + "gzip": 167270 }, { "filename": "react-dom.production.min.js", "bundleType": "UMD_PROD", "packageName": "react-dom", - "size": 100307, - "gzip": 32617 + "size": 100485, + "gzip": 32699 }, { "filename": "react-dom.development.js", "bundleType": "NODE_DEV", "packageName": "react-dom", - "size": 720713, - "gzip": 166331 + "size": 717285, + "gzip": 165860 }, { "filename": "react-dom.production.min.js", "bundleType": "NODE_PROD", "packageName": "react-dom", - "size": 100301, - "gzip": 32146 + "size": 100483, + "gzip": 32224 }, { "filename": "ReactDOM-dev.js", @@ -88,8 +88,8 @@ "filename": "react-dom-test-utils.development.js", "bundleType": "UMD_DEV", "packageName": "react-dom", - "size": 45937, - "gzip": 12585 + "size": 45943, + "gzip": 12588 }, { "filename": "react-dom-test-utils.production.min.js", @@ -102,8 +102,8 @@ "filename": "react-dom-test-utils.development.js", "bundleType": "NODE_DEV", "packageName": "react-dom", - "size": 45651, - "gzip": 12521 + "size": 45657, + "gzip": 12524 }, { "filename": "react-dom-test-utils.production.min.js", @@ -165,29 +165,29 @@ "filename": "react-dom-server.browser.development.js", "bundleType": "UMD_DEV", "packageName": "react-dom", - "size": 120524, - "gzip": 32011 + "size": 120452, + "gzip": 31996 }, { "filename": "react-dom-server.browser.production.min.js", "bundleType": "UMD_PROD", "packageName": "react-dom", - "size": 16402, - "gzip": 6237 + "size": 16379, + "gzip": 6228 }, { "filename": "react-dom-server.browser.development.js", "bundleType": "NODE_DEV", "packageName": "react-dom", - "size": 116562, - "gzip": 31037 + "size": 116490, + "gzip": 31019 }, { "filename": "react-dom-server.browser.production.min.js", "bundleType": "NODE_PROD", "packageName": "react-dom", - "size": 16301, - "gzip": 6233 + "size": 16278, + "gzip": 6228 }, { "filename": "ReactDOMServer-dev.js", @@ -207,43 +207,43 @@ "filename": "react-dom-server.node.development.js", "bundleType": "NODE_DEV", "packageName": "react-dom", - "size": 118530, - "gzip": 31584 + "size": 118458, + "gzip": 31567 }, { "filename": "react-dom-server.node.production.min.js", "bundleType": "NODE_PROD", "packageName": "react-dom", - "size": 17126, - "gzip": 6544 + "size": 17103, + "gzip": 6537 }, { "filename": "react-art.development.js", "bundleType": "UMD_DEV", "packageName": "react-art", - "size": 507548, - "gzip": 112066 + "size": 503592, + "gzip": 111526 }, { "filename": "react-art.production.min.js", "bundleType": "UMD_PROD", "packageName": "react-art", - "size": 92284, - "gzip": 28330 + "size": 92362, + "gzip": 28312 }, { "filename": "react-art.development.js", "bundleType": "NODE_DEV", "packageName": "react-art", - "size": 437685, - "gzip": 94610 + "size": 433726, + "gzip": 94096 }, { "filename": "react-art.production.min.js", "bundleType": "NODE_PROD", "packageName": "react-art", - "size": 56431, - "gzip": 17393 + "size": 56507, + "gzip": 17388 }, { "filename": "ReactART-dev.js", @@ -291,29 +291,29 @@ "filename": "react-test-renderer.development.js", "bundleType": "UMD_DEV", "packageName": "react-test-renderer", - "size": 450653, - "gzip": 97378 + "size": 446694, + "gzip": 96842 }, { "filename": "react-test-renderer.production.min.js", "bundleType": "UMD_PROD", "packageName": "react-test-renderer", - "size": 57674, - "gzip": 17698 + "size": 57752, + "gzip": 17656 }, { "filename": "react-test-renderer.development.js", "bundleType": "NODE_DEV", "packageName": "react-test-renderer", - "size": 445754, - "gzip": 96206 + "size": 441795, + "gzip": 95673 }, { "filename": "react-test-renderer.production.min.js", "bundleType": "NODE_PROD", "packageName": "react-test-renderer", - "size": 57342, - "gzip": 17539 + "size": 57418, + "gzip": 17523 }, { "filename": "ReactTestRenderer-dev.js", @@ -375,28 +375,28 @@ "filename": "react-reconciler.development.js", "bundleType": "NODE_DEV", "packageName": "react-reconciler", - "size": 435479, - "gzip": 93068 + "size": 431520, + "gzip": 92513 }, { "filename": "react-reconciler.production.min.js", "bundleType": "NODE_PROD", "packageName": "react-reconciler", - "size": 57593, + "size": 57675, "gzip": 17242 }, { "filename": "react-reconciler-persistent.development.js", "bundleType": "NODE_DEV", "packageName": "react-reconciler", - "size": 433889, - "gzip": 92426 + "size": 429930, + "gzip": 91872 }, { "filename": "react-reconciler-persistent.production.min.js", "bundleType": "NODE_PROD", "packageName": "react-reconciler", - "size": 57604, + "size": 57686, "gzip": 17248 }, { @@ -501,8 +501,8 @@ "filename": "React-dev.js", "bundleType": "FB_WWW_DEV", "packageName": "react", - "size": 58338, - "gzip": 15703 + "size": 58339, + "gzip": 15705 }, { "filename": "React-prod.js", @@ -515,15 +515,15 @@ "filename": "ReactDOM-dev.js", "bundleType": "FB_WWW_DEV", "packageName": "react-dom", - "size": 742105, - "gzip": 167549 + "size": 737575, + "gzip": 166976 }, { "filename": "ReactDOM-prod.js", "bundleType": "FB_WWW_PROD", "packageName": "react-dom", - "size": 318358, - "gzip": 58562 + "size": 303616, + "gzip": 55571 }, { "filename": "ReactTestUtils-dev.js", @@ -550,92 +550,92 @@ "filename": "ReactDOMServer-dev.js", "bundleType": "FB_WWW_DEV", "packageName": "react-dom", - "size": 117649, - "gzip": 30639 + "size": 117578, + "gzip": 30626 }, { "filename": "ReactDOMServer-prod.js", "bundleType": "FB_WWW_PROD", "packageName": "react-dom", - "size": 41626, - "gzip": 9808 + "size": 36376, + "gzip": 8710 }, { "filename": "ReactART-dev.js", "bundleType": "FB_WWW_DEV", "packageName": "react-art", - "size": 445159, - "gzip": 93560 + "size": 440023, + "gzip": 92845 }, { "filename": "ReactART-prod.js", "bundleType": "FB_WWW_PROD", "packageName": "react-art", - "size": 189135, - "gzip": 32266 + "size": 174075, + "gzip": 29293 }, { "filename": "ReactNativeRenderer-dev.js", "bundleType": "RN_FB_DEV", "packageName": "react-native-renderer", - "size": 573357, - "gzip": 124963 + "size": 568772, + "gzip": 124380 }, { "filename": "ReactNativeRenderer-prod.js", "bundleType": "RN_FB_PROD", "packageName": "react-native-renderer", - "size": 245987, - "gzip": 43227 + "size": 246039, + "gzip": 43290 }, { "filename": "ReactNativeRenderer-dev.js", "bundleType": "RN_OSS_DEV", "packageName": "react-native-renderer", - "size": 573046, - "gzip": 124866 + "size": 568461, + "gzip": 124285 }, { "filename": "ReactNativeRenderer-prod.js", "bundleType": "RN_OSS_PROD", "packageName": "react-native-renderer", - "size": 231080, - "gzip": 40077 + "size": 231135, + "gzip": 40179 }, { "filename": "ReactFabric-dev.js", "bundleType": "RN_FB_DEV", "packageName": "react-native-renderer", - "size": 563440, - "gzip": 122415 + "size": 558855, + "gzip": 121837 }, { "filename": "ReactFabric-prod.js", "bundleType": "RN_FB_PROD", "packageName": "react-native-renderer", - "size": 225188, - "gzip": 38730 + "size": 225246, + "gzip": 38817 }, { "filename": "ReactFabric-dev.js", "bundleType": "RN_OSS_DEV", "packageName": "react-native-renderer", - "size": 563475, - "gzip": 122429 + "size": 558890, + "gzip": 121851 }, { "filename": "ReactFabric-prod.js", "bundleType": "RN_OSS_PROD", "packageName": "react-native-renderer", - "size": 225224, - "gzip": 38745 + "size": 225282, + "gzip": 38831 }, { "filename": "ReactTestRenderer-dev.js", "bundleType": "FB_WWW_DEV", "packageName": "react-test-renderer", - "size": 453421, - "gzip": 95442 + "size": 448285, + "gzip": 94745 }, { "filename": "ReactShallowRenderer-dev.js", @@ -718,22 +718,22 @@ "filename": "react-dom.profiling.min.js", "bundleType": "NODE_PROFILING", "packageName": "react-dom", - "size": 103137, - "gzip": 32687 + "size": 103307, + "gzip": 32759 }, { "filename": "ReactNativeRenderer-profiling.js", "bundleType": "RN_OSS_PROFILING", "packageName": "react-native-renderer", - "size": 236392, - "gzip": 41298 + "size": 236436, + "gzip": 41394 }, { "filename": "ReactFabric-profiling.js", "bundleType": "RN_OSS_PROFILING", "packageName": "react-native-renderer", - "size": 229595, - "gzip": 40005 + "size": 229639, + "gzip": 40092 }, { "filename": "Scheduler-dev.js", @@ -767,22 +767,22 @@ "filename": "ReactDOM-profiling.js", "bundleType": "FB_WWW_PROFILING", "packageName": "react-dom", - "size": 324711, - "gzip": 59847 + "size": 309719, + "gzip": 56942 }, { "filename": "ReactNativeRenderer-profiling.js", "bundleType": "RN_FB_PROFILING", "packageName": "react-native-renderer", - "size": 251555, - "gzip": 44455 + "size": 251599, + "gzip": 44540 }, { "filename": "ReactFabric-profiling.js", "bundleType": "RN_FB_PROFILING", "packageName": "react-native-renderer", - "size": 229554, - "gzip": 39988 + "size": 229598, + "gzip": 40076 }, { "filename": "react.profiling.min.js", @@ -795,8 +795,8 @@ "filename": "react-dom.profiling.min.js", "bundleType": "UMD_PROFILING", "packageName": "react-dom", - "size": 103046, - "gzip": 33256 + "size": 103220, + "gzip": 33307 }, { "filename": "scheduler-tracing.development.js", @@ -922,7 +922,7 @@ "bundleType": "NODE_PROD", "packageName": "react-debug-tools", "size": 5402, - "gzip": 2187 + "gzip": 2188 }, { "filename": "eslint-plugin-react-hooks.development.js", @@ -937,6 +937,62 @@ "packageName": "eslint-plugin-react-hooks", "size": 4943, "gzip": 1815 + }, + { + "filename": "react-dom-fizz.development.js", + "bundleType": "NODE_DEV", + "packageName": "react-dom", + "size": 1182, + "gzip": 600 + }, + { + "filename": "react-dom-fizz.production.min.js", + "bundleType": "NODE_PROD", + "packageName": "react-dom", + "size": 346, + "gzip": 269 + }, + { + "filename": "ReactDOMFizzServer-dev.js", + "bundleType": "FB_WWW_DEV", + "packageName": "react-dom", + "size": 1168, + "gzip": 587 + }, + { + "filename": "ReactDOMFizzServer-prod.js", + "bundleType": "FB_WWW_PROD", + "packageName": "react-dom", + "size": 547, + "gzip": 302 + }, + { + "filename": "react-noop-renderer-server.development.js", + "bundleType": "NODE_DEV", + "packageName": "react-noop-renderer", + "size": 1254, + "gzip": 657 + }, + { + "filename": "react-noop-renderer-server.production.min.js", + "bundleType": "NODE_PROD", + "packageName": "react-noop-renderer", + "size": 457, + "gzip": 326 + }, + { + "filename": "react-stream.development.js", + "bundleType": "NODE_DEV", + "packageName": "react-stream", + "size": 2365, + "gzip": 1114 + }, + { + "filename": "react-stream.production.min.js", + "bundleType": "NODE_PROD", + "packageName": "react-stream", + "size": 608, + "gzip": 361 } ] } \ No newline at end of file diff --git a/scripts/shared/inlinedHostConfigs.js b/scripts/shared/inlinedHostConfigs.js index 2892a9abeb0..52119703b17 100644 --- a/scripts/shared/inlinedHostConfigs.js +++ b/scripts/shared/inlinedHostConfigs.js @@ -9,8 +9,9 @@ module.exports = [ { shortName: 'dom', - entryPoints: ['react-dom'], + entryPoints: ['react-dom', 'react-dom/fizz'], isFlowTyped: true, + isFizzSupported: true, }, { shortName: 'fire', @@ -21,25 +22,34 @@ module.exports = [ shortName: 'art', entryPoints: ['react-art'], isFlowTyped: false, // TODO: type it. + isFizzSupported: false, }, { shortName: 'native', entryPoints: ['react-native-renderer'], isFlowTyped: true, + isFizzSupported: false, }, { shortName: 'fabric', entryPoints: ['react-native-renderer/fabric'], isFlowTyped: true, + isFizzSupported: false, }, { shortName: 'test', entryPoints: ['react-test-renderer'], isFlowTyped: true, + isFizzSupported: false, }, { shortName: 'custom', - entryPoints: ['react-reconciler', 'react-reconciler/persistent'], + entryPoints: [ + 'react-reconciler', + 'react-reconciler/persistent', + 'react-stream', + ], isFlowTyped: true, + isFizzSupported: true, }, ]; From 690e7dee820d1f6b7eb54247886c0e6a015f1cf7 Mon Sep 17 00:00:00 2001 From: Sebastian Markbage Date: Thu, 1 Nov 2018 17:25:58 -0700 Subject: [PATCH 02/12] Add FormatConfig too We need to separate the format (DOM, React Native, etc) from the host running the server (Node, Browser, etc). --- packages/react-dom/fizz.js | 6 +--- packages/react-dom/fizz.node.js | 16 ++++++++++ .../server/ReactDOMFizzServerFormatConfig.js | 12 ++++++++ ...izzServer.js => ReactDOMFizzServerNode.js} | 4 +-- .../src/ReactNoopServer.js | 15 ++++++---- .../react-stream/src/ReactFizzFormatConfig.js | 20 +++++++++++++ .../src/ReactFizzHostConfigNode.js} | 4 +-- .../react-stream/src/ReactFizzRenderer.js | 12 +++++--- .../src/forks/ReactFizzFormatConfig.custom.js | 29 ++++++++++++++++++ .../src/forks/ReactFizzFormatConfig.dom.js | 10 +++++++ .../src/forks/ReactFizzHostConfig.custom.js | 4 +-- .../src/forks/ReactFizzHostConfig.dom.js | 2 +- scripts/flow/createFlowConfigs.js | 6 ++-- scripts/jest/setupHostConfigs.js | 12 +++++++- scripts/rollup/forks.js | 30 +++++++++++++++++++ scripts/rollup/results.json | 28 ++++++++--------- 16 files changed, 171 insertions(+), 39 deletions(-) create mode 100644 packages/react-dom/fizz.node.js create mode 100644 packages/react-dom/src/server/ReactDOMFizzServerFormatConfig.js rename packages/react-dom/src/server/{ReactDOMFizzServer.js => ReactDOMFizzServerNode.js} (72%) create mode 100644 packages/react-stream/src/ReactFizzFormatConfig.js rename packages/{react-dom/src/server/ReactDOMFizzServerHostConfig.js => react-stream/src/ReactFizzHostConfigNode.js} (64%) create mode 100644 packages/react-stream/src/forks/ReactFizzFormatConfig.custom.js create mode 100644 packages/react-stream/src/forks/ReactFizzFormatConfig.dom.js diff --git a/packages/react-dom/fizz.js b/packages/react-dom/fizz.js index 53eb1078b90..7376c1c8043 100644 --- a/packages/react-dom/fizz.js +++ b/packages/react-dom/fizz.js @@ -9,8 +9,4 @@ 'use strict'; -const ReactDOMFizzServer = require('./src/server/ReactDOMFizzServer'); - -// TODO: decide on the top-level export form. -// This is hacky but makes it work with both Rollup and Jest -module.exports = ReactDOMFizzServer.default || ReactDOMFizzServer; +module.exports = require('./fizz.node'); diff --git a/packages/react-dom/fizz.node.js b/packages/react-dom/fizz.node.js new file mode 100644 index 00000000000..ef943c74ecc --- /dev/null +++ b/packages/react-dom/fizz.node.js @@ -0,0 +1,16 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @flow + */ + +'use strict'; + +const ReactDOMFizzServerNode = require('./src/server/ReactDOMFizzServerNode'); + +// TODO: decide on the top-level export form. +// This is hacky but makes it work with both Rollup and Jest +module.exports = ReactDOMFizzServerNode.default || ReactDOMFizzServerNode; diff --git a/packages/react-dom/src/server/ReactDOMFizzServerFormatConfig.js b/packages/react-dom/src/server/ReactDOMFizzServerFormatConfig.js new file mode 100644 index 00000000000..ef94efc9ac1 --- /dev/null +++ b/packages/react-dom/src/server/ReactDOMFizzServerFormatConfig.js @@ -0,0 +1,12 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @flow + */ + +export function formatChunk(): Uint8Array { + return new Uint8Array(0); +} diff --git a/packages/react-dom/src/server/ReactDOMFizzServer.js b/packages/react-dom/src/server/ReactDOMFizzServerNode.js similarity index 72% rename from packages/react-dom/src/server/ReactDOMFizzServer.js rename to packages/react-dom/src/server/ReactDOMFizzServerNode.js index d760dfc3583..89fc8ce9292 100644 --- a/packages/react-dom/src/server/ReactDOMFizzServer.js +++ b/packages/react-dom/src/server/ReactDOMFizzServerNode.js @@ -7,10 +7,10 @@ * @flow */ -import {createRequest, readBuffer} from 'react-stream/inline.dom'; +import {createRequest, flushChunk} from 'react-stream/inline.dom'; function render() { - readBuffer(createRequest({})); + flushChunk(createRequest({})); } export default { render, diff --git a/packages/react-noop-renderer/src/ReactNoopServer.js b/packages/react-noop-renderer/src/ReactNoopServer.js index 69b553071d0..69a93299dbd 100644 --- a/packages/react-noop-renderer/src/ReactNoopServer.js +++ b/packages/react-noop-renderer/src/ReactNoopServer.js @@ -16,13 +16,18 @@ import ReactFizzRenderer from 'react-stream'; -const ReactNoopServer = ReactFizzRenderer({ - ping() {}, - write() {}, -}); +const ReactNoopServer = ReactFizzRenderer( + { + scheduleWork(callback) {}, + writeBuffer(request, buffer) {}, + }, + { + formatChunk() {}, + }, +); function render(children: React$Element) { - ReactNoopServer.readBuffer(ReactNoopServer.createRequest({})); + ReactNoopServer.flushChunk(ReactNoopServer.createRequest({})); } export default { diff --git a/packages/react-stream/src/ReactFizzFormatConfig.js b/packages/react-stream/src/ReactFizzFormatConfig.js new file mode 100644 index 00000000000..ae70ca5cda9 --- /dev/null +++ b/packages/react-stream/src/ReactFizzFormatConfig.js @@ -0,0 +1,20 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @flow + */ + +import invariant from 'shared/invariant'; + +// We expect that our Rollup, Jest, and Flow configurations +// always shim this module with the corresponding host config +// (either provided by a renderer, or a generic shim for npm). +// +// We should never resolve to this file, but it exists to make +// sure that if we *do* accidentally break the configuration, +// the failure isn't silent. + +invariant(false, 'This module must be shimmed by a specific renderer.'); diff --git a/packages/react-dom/src/server/ReactDOMFizzServerHostConfig.js b/packages/react-stream/src/ReactFizzHostConfigNode.js similarity index 64% rename from packages/react-dom/src/server/ReactDOMFizzServerHostConfig.js rename to packages/react-stream/src/ReactFizzHostConfigNode.js index fae87abf486..d5a9d5002b0 100644 --- a/packages/react-dom/src/server/ReactDOMFizzServerHostConfig.js +++ b/packages/react-stream/src/ReactFizzHostConfigNode.js @@ -9,6 +9,6 @@ export type RequestInfo = {}; -export function ping(request: RequestInfo) {} +export function scheduleWork(callback: () => void) {} -export function write(request: RequestInfo) {} +export function writeBuffer(request: RequestInfo, buffer: Uint8Array) {} diff --git a/packages/react-stream/src/ReactFizzRenderer.js b/packages/react-stream/src/ReactFizzRenderer.js index d1cda1543e0..f851df81c5a 100644 --- a/packages/react-stream/src/ReactFizzRenderer.js +++ b/packages/react-stream/src/ReactFizzRenderer.js @@ -8,7 +8,8 @@ */ import type {RequestInfo} from './ReactFizzHostConfig'; -import {ping, write} from './ReactFizzHostConfig'; +import {scheduleWork, writeBuffer} from './ReactFizzHostConfig'; +import {formatChunk} from './ReactFizzFormatConfig'; type OpaqueRequest = {requestInfo: RequestInfo}; @@ -16,7 +17,10 @@ export function createRequest(requestInfo: RequestInfo): OpaqueRequest { return {requestInfo}; } -export function readBuffer(request: OpaqueRequest): void { - ping(request.requestInfo); - write(request.requestInfo); +function performWork(request: OpaqueRequest): void { + writeBuffer(request.requestInfo, formatChunk()); +} + +export function flushChunk(request: OpaqueRequest): void { + scheduleWork(() => performWork(request)); } diff --git a/packages/react-stream/src/forks/ReactFizzFormatConfig.custom.js b/packages/react-stream/src/forks/ReactFizzFormatConfig.custom.js new file mode 100644 index 00000000000..dd0b57af485 --- /dev/null +++ b/packages/react-stream/src/forks/ReactFizzFormatConfig.custom.js @@ -0,0 +1,29 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @flow + */ + +// This is a host config that's used for the `react-stream` package on npm. +// It is only used by third-party renderers. +// +// Its API lets you pass the host config as an argument. +// However, inside the `react-stream` we treat host config as a module. +// This file is a shim between two worlds. +// +// It works because the `react-stream` bundle is wrapped in something like: +// +// module.exports = function ($$$config) { +// /* renderer code */ +// } +// +// So `$$$config` looks like a global variable, but it's +// really an argument to a top-level wrapping function. + +declare var $$$hostConfig: any; +export opaque type RequestInfo = mixed; // eslint-disable-line no-undef + +export const formatChunk = $$$hostConfig.formatChunk; diff --git a/packages/react-stream/src/forks/ReactFizzFormatConfig.dom.js b/packages/react-stream/src/forks/ReactFizzFormatConfig.dom.js new file mode 100644 index 00000000000..e3b8782adee --- /dev/null +++ b/packages/react-stream/src/forks/ReactFizzFormatConfig.dom.js @@ -0,0 +1,10 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @flow + */ + +export * from 'react-dom/src/server/ReactDOMFizzServerFormatConfig'; diff --git a/packages/react-stream/src/forks/ReactFizzHostConfig.custom.js b/packages/react-stream/src/forks/ReactFizzHostConfig.custom.js index 4ee36f4cf41..763a558ddf6 100644 --- a/packages/react-stream/src/forks/ReactFizzHostConfig.custom.js +++ b/packages/react-stream/src/forks/ReactFizzHostConfig.custom.js @@ -26,5 +26,5 @@ declare var $$$hostConfig: any; export opaque type RequestInfo = mixed; // eslint-disable-line no-undef -export const ping = $$$hostConfig.ping; -export const write = $$$hostConfig.write; +export const scheduleWork = $$$hostConfig.scheduleWork; +export const writeBuffer = $$$hostConfig.writeBuffer; diff --git a/packages/react-stream/src/forks/ReactFizzHostConfig.dom.js b/packages/react-stream/src/forks/ReactFizzHostConfig.dom.js index 493b887abc7..88d44bc2e45 100644 --- a/packages/react-stream/src/forks/ReactFizzHostConfig.dom.js +++ b/packages/react-stream/src/forks/ReactFizzHostConfig.dom.js @@ -7,4 +7,4 @@ * @flow */ -export * from 'react-dom/src/server/ReactDOMFizzServerHostConfig'; +export * from '../ReactFizzHostConfigNode'; diff --git a/scripts/flow/createFlowConfigs.js b/scripts/flow/createFlowConfigs.js index e7308fd7c21..f1ca3523c77 100644 --- a/scripts/flow/createFlowConfigs.js +++ b/scripts/flow/createFlowConfigs.js @@ -22,15 +22,15 @@ function writeConfig(renderer, isFizzSupported) { const folder = __dirname + '/' + renderer; mkdirp.sync(folder); + const fizzRenderer = isFizzSupported ? renderer : 'custom'; const config = configTemplate.replace( '%REACT_RENDERER_FLOW_OPTIONS%', ` module.name_mapper='react-reconciler/inline.${renderer}$$' -> 'react-reconciler/inline-typed' module.name_mapper='ReactFiberHostConfig$$' -> 'forks/ReactFiberHostConfig.${renderer}' module.name_mapper='react-stream/inline.${renderer}$$' -> 'react-stream/inline-typed' -module.name_mapper='ReactFizzHostConfig$$' -> 'forks/ReactFizzHostConfig.${ - isFizzSupported ? renderer : 'custom' - }' +module.name_mapper='ReactFizzHostConfig$$' -> 'forks/ReactFizzHostConfig.${fizzRenderer}' +module.name_mapper='ReactFizzFormatConfig$$' -> 'forks/ReactFizzFormatConfig.${fizzRenderer}' `.trim(), ); diff --git a/scripts/jest/setupHostConfigs.js b/scripts/jest/setupHostConfigs.js index d0e9e405641..c1cd767c19d 100644 --- a/scripts/jest/setupHostConfigs.js +++ b/scripts/jest/setupHostConfigs.js @@ -18,9 +18,11 @@ jest.mock('react-reconciler/persistent', () => { }; }); const shimFizzHostConfigPath = 'react-stream/src/ReactFizzHostConfig'; +const shimFizzFormatConfigPath = 'react-stream/src/ReactFizzFormatConfig'; jest.mock('react-stream', () => { - return config => { + return (config, configFormat) => { jest.mock(shimFizzHostConfigPath, () => config); + jest.mock(shimFizzFormatConfigPath, () => configFormat); return require.requireActual('react-stream'); }; }); @@ -76,6 +78,14 @@ inlinedHostConfigs.forEach(rendererInfo => { }.js` ); }); + jest.mock(shimFizzFormatConfigPath, () => { + hasImportedShimmedConfig = true; + return require.requireActual( + `react-stream/src/forks/ReactFizzFormatConfig.${ + rendererInfo.shortName + }.js` + ); + }); const renderer = require.requireActual('react-stream'); // If the shimmed config factory function above has not run, diff --git a/scripts/rollup/forks.js b/scripts/rollup/forks.js index b19d7688cf9..a6fa873078e 100644 --- a/scripts/rollup/forks.js +++ b/scripts/rollup/forks.js @@ -302,6 +302,36 @@ const forks = Object.freeze({ ); }, + 'react-stream/src/ReactFizzFormatConfig': ( + bundleType, + entry, + dependencies, + moduleType + ) => { + if (dependencies.indexOf('react-stream') !== -1) { + return null; + } + if (moduleType !== RENDERER && moduleType !== RECONCILER) { + return null; + } + // eslint-disable-next-line no-for-of-loops/no-for-of-loops + for (let rendererInfo of inlinedHostConfigs) { + if (rendererInfo.entryPoints.indexOf(entry) !== -1) { + if (!rendererInfo.isFizzSupported) { + return null; + } + return `react-stream/src/forks/ReactFizzFormatConfig.${ + rendererInfo.shortName + }.js`; + } + } + throw new Error( + 'Expected ReactFizzFormatConfig to always be replaced with a shim, but ' + + `found no mention of "${entry}" entry point in ./scripts/shared/inlinedHostConfigs.js. ` + + 'Did you mean to add it there to associate it with a specific renderer?' + ); + }, + // We wrap top-level listeners into guards on www. 'react-dom/src/events/EventListener': (bundleType, entry) => { switch (bundleType) { diff --git a/scripts/rollup/results.json b/scripts/rollup/results.json index 9f08c72b671..60165a161a4 100644 --- a/scripts/rollup/results.json +++ b/scripts/rollup/results.json @@ -942,8 +942,8 @@ "filename": "react-dom-fizz.development.js", "bundleType": "NODE_DEV", "packageName": "react-dom", - "size": 1182, - "gzip": 600 + "size": 988, + "gzip": 530 }, { "filename": "react-dom-fizz.production.min.js", @@ -956,43 +956,43 @@ "filename": "ReactDOMFizzServer-dev.js", "bundleType": "FB_WWW_DEV", "packageName": "react-dom", - "size": 1168, - "gzip": 587 + "size": 972, + "gzip": 517 }, { "filename": "ReactDOMFizzServer-prod.js", "bundleType": "FB_WWW_PROD", "packageName": "react-dom", - "size": 547, - "gzip": 302 + "size": 587, + "gzip": 307 }, { "filename": "react-noop-renderer-server.development.js", "bundleType": "NODE_DEV", "packageName": "react-noop-renderer", - "size": 1254, - "gzip": 657 + "size": 1326, + "gzip": 693 }, { "filename": "react-noop-renderer-server.production.min.js", "bundleType": "NODE_PROD", "packageName": "react-noop-renderer", - "size": 457, - "gzip": 326 + "size": 498, + "gzip": 344 }, { "filename": "react-stream.development.js", "bundleType": "NODE_DEV", "packageName": "react-stream", - "size": 2365, - "gzip": 1114 + "size": 3135, + "gzip": 1176 }, { "filename": "react-stream.production.min.js", "bundleType": "NODE_PROD", "packageName": "react-stream", - "size": 608, - "gzip": 361 + "size": 652, + "gzip": 391 } ] } \ No newline at end of file From baa36b8df64498fcef0ab36580eceab80112842e Mon Sep 17 00:00:00 2001 From: Sebastian Markbage Date: Tue, 6 Nov 2018 21:58:41 -0800 Subject: [PATCH 03/12] Basic wiring between Node, Noop and DOM configs The Node DOM API is pipeToNodeStream which accepts a writable stream. --- .../src/__tests__/ReactDOMFizzServer-test.js | 17 ++++- .../server/ReactDOMFizzServerFormatConfig.js | 11 ++- .../src/server/ReactDOMFizzServerNode.js | 18 +++-- .../src/ReactNoopServer.js | 27 ++++++-- .../src/ReactFizzHostConfigNode.js | 36 +++++++++- .../react-stream/src/ReactFizzRenderer.js | 69 +++++++++++++++++-- .../src/__tests__/ReactServer-test.js | 3 +- .../src/forks/ReactFizzFormatConfig.custom.js | 2 +- .../src/forks/ReactFizzHostConfig.custom.js | 8 ++- 9 files changed, 164 insertions(+), 27 deletions(-) diff --git a/packages/react-dom/src/__tests__/ReactDOMFizzServer-test.js b/packages/react-dom/src/__tests__/ReactDOMFizzServer-test.js index 91fe1bd2fe9..5a371f428c5 100644 --- a/packages/react-dom/src/__tests__/ReactDOMFizzServer-test.js +++ b/packages/react-dom/src/__tests__/ReactDOMFizzServer-test.js @@ -10,6 +10,7 @@ 'use strict'; +let Stream; let React; let ReactDOMFizzServer; @@ -18,9 +19,21 @@ describe('ReactDOMFizzServer', () => { jest.resetModules(); React = require('react'); ReactDOMFizzServer = require('react-dom/fizz'); + Stream = require('stream'); }); - it('should call render', () => { - ReactDOMFizzServer.render(
hello world
); + function getTestWritable() { + let writable = new Stream.PassThrough(); + writable.setEncoding('utf8'); + writable.result = ''; + writable.on('data', chunk => (writable.result += chunk)); + return writable; + } + + it('should call pipeToNodeWritable', () => { + let writable = getTestWritable(); + ReactDOMFizzServer.pipeToNodeWritable(
hello world
, writable); + jest.runAllTimers(); + expect(writable.result).toBe('
hello world
'); }); }); diff --git a/packages/react-dom/src/server/ReactDOMFizzServerFormatConfig.js b/packages/react-dom/src/server/ReactDOMFizzServerFormatConfig.js index ef94efc9ac1..a9c6dc79df8 100644 --- a/packages/react-dom/src/server/ReactDOMFizzServerFormatConfig.js +++ b/packages/react-dom/src/server/ReactDOMFizzServerFormatConfig.js @@ -7,6 +7,13 @@ * @flow */ -export function formatChunk(): Uint8Array { - return new Uint8Array(0); +import {convertStringToBuffer} from 'react-stream/src/ReactFizzHostConfig'; + +export function formatChunk(type: string, props: Object): Uint8Array { + let str = '<' + type + '>'; + if (typeof props.children === 'string') { + str += props.children; + } + str += ''; + return convertStringToBuffer(str); } diff --git a/packages/react-dom/src/server/ReactDOMFizzServerNode.js b/packages/react-dom/src/server/ReactDOMFizzServerNode.js index 89fc8ce9292..39947c4defc 100644 --- a/packages/react-dom/src/server/ReactDOMFizzServerNode.js +++ b/packages/react-dom/src/server/ReactDOMFizzServerNode.js @@ -7,11 +7,21 @@ * @flow */ -import {createRequest, flushChunk} from 'react-stream/inline.dom'; +import type {ReactNodeList} from 'shared/ReactTypes'; +import type {Writable} from 'stream'; -function render() { - flushChunk(createRequest({})); +import {createRequest, startWork, startFlowing} from 'react-stream/inline.dom'; + +function createDrainHandler(destination, request) { + return () => startFlowing(request, 0); +} + +function pipeToNodeWritable(children: ReactNodeList, destination: Writable) { + let request = createRequest(children, destination); + destination.on('drain', createDrainHandler(destination, request)); + startWork(request); } + export default { - render, + pipeToNodeWritable, }; diff --git a/packages/react-noop-renderer/src/ReactNoopServer.js b/packages/react-noop-renderer/src/ReactNoopServer.js index 69a93299dbd..6794919c4f3 100644 --- a/packages/react-noop-renderer/src/ReactNoopServer.js +++ b/packages/react-noop-renderer/src/ReactNoopServer.js @@ -16,18 +16,35 @@ import ReactFizzRenderer from 'react-stream'; +type Destination = Array; + const ReactNoopServer = ReactFizzRenderer( { - scheduleWork(callback) {}, - writeBuffer(request, buffer) {}, + scheduleWork(callback: () => void) { + callback(); + }, + beginWriting(destination: Destination): void {}, + writeChunk(destination: Destination, buffer: Uint8Array): void { + destination.push(JSON.parse(Buffer.from((buffer: any)).toString('utf8'))); + }, + completeWriting(destination: Destination): void {}, + flushBuffered(destination: Destination): void {}, + convertStringToBuffer(content: string): Uint8Array { + return Buffer.from(content, 'utf8'); + }, }, { - formatChunk() {}, + formatChunk(type: string, props: Object): Uint8Array { + return Buffer.from(JSON.stringify({type, props}), 'utf8'); + }, }, ); -function render(children: React$Element) { - ReactNoopServer.flushChunk(ReactNoopServer.createRequest({})); +function render(children: React$Element): Destination { + let destination: Destination = []; + let request = ReactNoopServer.createRequest(children, destination); + ReactNoopServer.startWork(request); + return destination; } export default { diff --git a/packages/react-stream/src/ReactFizzHostConfigNode.js b/packages/react-stream/src/ReactFizzHostConfigNode.js index d5a9d5002b0..d6622376e33 100644 --- a/packages/react-stream/src/ReactFizzHostConfigNode.js +++ b/packages/react-stream/src/ReactFizzHostConfigNode.js @@ -7,8 +7,38 @@ * @flow */ -export type RequestInfo = {}; +import type {Writable} from 'stream'; -export function scheduleWork(callback: () => void) {} +type MightBeFlushable = {flush?: () => void}; -export function writeBuffer(request: RequestInfo, buffer: Uint8Array) {} +export type Destination = Writable & MightBeFlushable; + +export function scheduleWork(callback: () => void) { + setImmediate(callback); +} + +export function flushBuffered(destination: Destination) { + // If we don't have any more data to send right now. + // Flush whatever is in the buffer to the wire. + if (typeof destination.flush === 'function') { + // By convention the Zlib streams provide a flush function for this purpose. + destination.flush(); + } +} + +export function beginWriting(destination: Destination) { + destination.cork(); +} + +export function writeChunk(destination: Destination, buffer: Uint8Array) { + let nodeBuffer = ((buffer: any): Buffer); // close enough + destination.write(nodeBuffer); +} + +export function completeWriting(destination: Destination) { + destination.uncork(); +} + +export function convertStringToBuffer(content: string): Uint8Array { + return Buffer.from(content, 'utf8'); +} diff --git a/packages/react-stream/src/ReactFizzRenderer.js b/packages/react-stream/src/ReactFizzRenderer.js index f851df81c5a..60480735356 100644 --- a/packages/react-stream/src/ReactFizzRenderer.js +++ b/packages/react-stream/src/ReactFizzRenderer.js @@ -7,20 +7,75 @@ * @flow */ -import type {RequestInfo} from './ReactFizzHostConfig'; -import {scheduleWork, writeBuffer} from './ReactFizzHostConfig'; +import type {Destination} from './ReactFizzHostConfig'; +import type {ReactNodeList} from 'shared/ReactTypes'; + +import { + scheduleWork, + beginWriting, + writeChunk, + completeWriting, + flushBuffered, +} from './ReactFizzHostConfig'; import {formatChunk} from './ReactFizzFormatConfig'; +import {REACT_ELEMENT_TYPE} from 'shared/ReactSymbols'; -type OpaqueRequest = {requestInfo: RequestInfo}; +type OpaqueRequest = { + destination: Destination, + children: ReactNodeList, + completedChunks: Array, + flowing: boolean, +}; -export function createRequest(requestInfo: RequestInfo): OpaqueRequest { - return {requestInfo}; +export function createRequest( + children: ReactNodeList, + destination: Destination, +): OpaqueRequest { + return {destination, children, completedChunks: [], flowing: false}; } function performWork(request: OpaqueRequest): void { - writeBuffer(request.requestInfo, formatChunk()); + let element = (request.children: any); + if (element.$$typeof !== REACT_ELEMENT_TYPE) { + return; + } + let type = element.type; + let props = element.props; + if (typeof type !== 'string') { + return; + } + request.completedChunks.push(formatChunk(type, props)); + if (request.flowing) { + flushCompletedChunks(request); + } + + flushBuffered(request.destination); } -export function flushChunk(request: OpaqueRequest): void { +function flushCompletedChunks(request: OpaqueRequest) { + let destination = request.destination; + let chunks = request.completedChunks; + + beginWriting(destination); + try { + for (let i = 0; i < chunks.length; i++) { + let chunk = chunks[i]; + writeChunk(destination, chunk); + } + } finally { + completeWriting(destination); + } +} + +export function startWork(request: OpaqueRequest): void { + request.flowing = true; scheduleWork(() => performWork(request)); } + +export function startFlowing( + request: OpaqueRequest, + desiredBytes: number, +): void { + request.flowing = false; + flushCompletedChunks(request); +} diff --git a/packages/react-stream/src/__tests__/ReactServer-test.js b/packages/react-stream/src/__tests__/ReactServer-test.js index 20a85f77d32..0c6c13c44f1 100644 --- a/packages/react-stream/src/__tests__/ReactServer-test.js +++ b/packages/react-stream/src/__tests__/ReactServer-test.js @@ -22,6 +22,7 @@ describe('ReactServer', () => { }); it('can call render', () => { - ReactNoopServer.render(
hello world
); + let result = ReactNoopServer.render(
hello world
); + expect(result).toEqual([{type: 'div', props: {children: 'hello world'}}]); }); }); diff --git a/packages/react-stream/src/forks/ReactFizzFormatConfig.custom.js b/packages/react-stream/src/forks/ReactFizzFormatConfig.custom.js index dd0b57af485..9c4e1816522 100644 --- a/packages/react-stream/src/forks/ReactFizzFormatConfig.custom.js +++ b/packages/react-stream/src/forks/ReactFizzFormatConfig.custom.js @@ -24,6 +24,6 @@ // really an argument to a top-level wrapping function. declare var $$$hostConfig: any; -export opaque type RequestInfo = mixed; // eslint-disable-line no-undef +export opaque type Destination = mixed; // eslint-disable-line no-undef export const formatChunk = $$$hostConfig.formatChunk; diff --git a/packages/react-stream/src/forks/ReactFizzHostConfig.custom.js b/packages/react-stream/src/forks/ReactFizzHostConfig.custom.js index 763a558ddf6..aca4559cd23 100644 --- a/packages/react-stream/src/forks/ReactFizzHostConfig.custom.js +++ b/packages/react-stream/src/forks/ReactFizzHostConfig.custom.js @@ -24,7 +24,11 @@ // really an argument to a top-level wrapping function. declare var $$$hostConfig: any; -export opaque type RequestInfo = mixed; // eslint-disable-line no-undef +export opaque type Destination = mixed; // eslint-disable-line no-undef export const scheduleWork = $$$hostConfig.scheduleWork; -export const writeBuffer = $$$hostConfig.writeBuffer; +export const beginWriting = $$$hostConfig.beginWriting; +export const writeChunk = $$$hostConfig.writeChunk; +export const completeWriting = $$$hostConfig.completeWriting; +export const flushBuffered = $$$hostConfig.flushBuffered; +export const convertStringToBuffer = $$$hostConfig.convertStringToBuffer; From dad379acc91bfb658d2e9fddfa44dc59621f2046 Mon Sep 17 00:00:00 2001 From: Sebastian Markbage Date: Wed, 7 Nov 2018 16:50:17 -0800 Subject: [PATCH 04/12] 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. --- .../src/ReactNoopServer.js | 34 ++++++++----------- scripts/jest/setupHostConfigs.js | 4 +-- 2 files changed, 17 insertions(+), 21 deletions(-) diff --git a/packages/react-noop-renderer/src/ReactNoopServer.js b/packages/react-noop-renderer/src/ReactNoopServer.js index 6794919c4f3..8fbcb320827 100644 --- a/packages/react-noop-renderer/src/ReactNoopServer.js +++ b/packages/react-noop-renderer/src/ReactNoopServer.js @@ -18,27 +18,23 @@ import ReactFizzRenderer from 'react-stream'; type Destination = Array; -const ReactNoopServer = ReactFizzRenderer( - { - scheduleWork(callback: () => void) { - callback(); - }, - beginWriting(destination: Destination): void {}, - writeChunk(destination: Destination, buffer: Uint8Array): void { - destination.push(JSON.parse(Buffer.from((buffer: any)).toString('utf8'))); - }, - completeWriting(destination: Destination): void {}, - flushBuffered(destination: Destination): void {}, - convertStringToBuffer(content: string): Uint8Array { - return Buffer.from(content, 'utf8'); - }, +const ReactNoopServer = ReactFizzRenderer({ + scheduleWork(callback: () => void) { + callback(); }, - { - formatChunk(type: string, props: Object): Uint8Array { - return Buffer.from(JSON.stringify({type, props}), 'utf8'); - }, + beginWriting(destination: Destination): void {}, + writeChunk(destination: Destination, buffer: Uint8Array): void { + destination.push(JSON.parse(Buffer.from((buffer: any)).toString('utf8'))); }, -); + completeWriting(destination: Destination): void {}, + flushBuffered(destination: Destination): void {}, + convertStringToBuffer(content: string): Uint8Array { + return Buffer.from(content, 'utf8'); + }, + formatChunk(type: string, props: Object): Uint8Array { + return Buffer.from(JSON.stringify({type, props}), 'utf8'); + }, +}); function render(children: React$Element): Destination { let destination: Destination = []; diff --git a/scripts/jest/setupHostConfigs.js b/scripts/jest/setupHostConfigs.js index c1cd767c19d..d7f4aab3674 100644 --- a/scripts/jest/setupHostConfigs.js +++ b/scripts/jest/setupHostConfigs.js @@ -20,9 +20,9 @@ jest.mock('react-reconciler/persistent', () => { const shimFizzHostConfigPath = 'react-stream/src/ReactFizzHostConfig'; const shimFizzFormatConfigPath = 'react-stream/src/ReactFizzFormatConfig'; jest.mock('react-stream', () => { - return (config, configFormat) => { + return config => { jest.mock(shimFizzHostConfigPath, () => config); - jest.mock(shimFizzFormatConfigPath, () => configFormat); + jest.mock(shimFizzFormatConfigPath, () => config); return require.requireActual('react-stream'); }; }); From 37b1031d7d3b6a9d183f6b859ee89030bd76936e Mon Sep 17 00:00:00 2001 From: Sebastian Markbage Date: Wed, 7 Nov 2018 17:19:12 -0800 Subject: [PATCH 05/12] Add setImmediate/Buffer globals to lint config Used by the server renderer --- scripts/rollup/validate/eslintrc.cjs.js | 2 ++ scripts/rollup/validate/eslintrc.fb.js | 3 +++ 2 files changed, 5 insertions(+) diff --git a/scripts/rollup/validate/eslintrc.cjs.js b/scripts/rollup/validate/eslintrc.cjs.js index a1b4a7fdfac..e23b7c68fce 100644 --- a/scripts/rollup/validate/eslintrc.cjs.js +++ b/scripts/rollup/validate/eslintrc.cjs.js @@ -18,6 +18,8 @@ module.exports = { __REACT_DEVTOOLS_GLOBAL_HOOK__: true, // CommonJS / Node process: true, + setImmediate: true, + Buffer: true, }, parserOptions: { ecmaVersion: 5, diff --git a/scripts/rollup/validate/eslintrc.fb.js b/scripts/rollup/validate/eslintrc.fb.js index 2e2949444f5..878a170a31b 100644 --- a/scripts/rollup/validate/eslintrc.fb.js +++ b/scripts/rollup/validate/eslintrc.fb.js @@ -18,6 +18,9 @@ module.exports = { __REACT_DEVTOOLS_GLOBAL_HOOK__: true, // FB __DEV__: true, + // Node.js Server Rendering + setImmediate: true, + Buffer: true, }, parserOptions: { ecmaVersion: 5, From a155b173aec23aff7c33c3dc40c180bed96099c1 Mon Sep 17 00:00:00 2001 From: Sebastian Markbage Date: Wed, 7 Nov 2018 19:07:05 -0800 Subject: [PATCH 06/12] Properly include fizz.node.js Also use forwarding to it from fizz.js in builds so that tests covers this. --- packages/react-dom/npm/fizz.js | 6 +----- packages/react-dom/npm/fizz.node.js | 7 +++++++ packages/react-dom/package.json | 1 + 3 files changed, 9 insertions(+), 5 deletions(-) create mode 100644 packages/react-dom/npm/fizz.node.js diff --git a/packages/react-dom/npm/fizz.js b/packages/react-dom/npm/fizz.js index 616592945b1..232f89cee21 100644 --- a/packages/react-dom/npm/fizz.js +++ b/packages/react-dom/npm/fizz.js @@ -1,7 +1,3 @@ 'use strict'; -if (process.env.NODE_ENV === 'production') { - module.exports = require('./cjs/react-dom-fizz.production.min.js'); -} else { - module.exports = require('./cjs/react-dom-fizz.development.js'); -} +module.exports = require('./fizz.node'); diff --git a/packages/react-dom/npm/fizz.node.js b/packages/react-dom/npm/fizz.node.js new file mode 100644 index 00000000000..616592945b1 --- /dev/null +++ b/packages/react-dom/npm/fizz.node.js @@ -0,0 +1,7 @@ +'use strict'; + +if (process.env.NODE_ENV === 'production') { + module.exports = require('./cjs/react-dom-fizz.production.min.js'); +} else { + module.exports = require('./cjs/react-dom-fizz.development.js'); +} diff --git a/packages/react-dom/package.json b/packages/react-dom/package.json index 1c513ee5d78..1b91f7630bd 100644 --- a/packages/react-dom/package.json +++ b/packages/react-dom/package.json @@ -31,6 +31,7 @@ "server.browser.js", "server.node.js", "fizz.js", + "fizz.node.js", "test-utils.js", "unstable-fire.js", "unstable-native-dependencies.js", From b0d61e3a77da535eee5c9d72ea508f656924e0b8 Mon Sep 17 00:00:00 2001 From: Sebastian Markbage Date: Wed, 7 Nov 2018 20:28:34 -0800 Subject: [PATCH 07/12] Make react-stream private since we're not ready to publish or even name it yet --- packages/react-stream/package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/react-stream/package.json b/packages/react-stream/package.json index 3d005bd6407..38dc3ad5ca7 100644 --- a/packages/react-stream/package.json +++ b/packages/react-stream/package.json @@ -2,6 +2,7 @@ "name": "react-stream", "description": "React package for creating custom streaming server renderers.", "version": "0.16.0", + "private": true, "keywords": [ "react" ], From 846e4a87c53e2802fde69cd9bfbbbbab5b559dbe Mon Sep 17 00:00:00 2001 From: Sebastian Markbage Date: Wed, 7 Nov 2018 20:30:29 -0800 Subject: [PATCH 08/12] Rename Renderer -> Streamer --- packages/react-noop-renderer/src/ReactNoopServer.js | 4 ++-- packages/react-stream/index.js | 4 ++-- packages/react-stream/inline-typed.js | 2 +- packages/react-stream/inline.dom.js | 2 +- .../src/{ReactFizzRenderer.js => ReactFizzStreamer.js} | 0 5 files changed, 6 insertions(+), 6 deletions(-) rename packages/react-stream/src/{ReactFizzRenderer.js => ReactFizzStreamer.js} (100%) diff --git a/packages/react-noop-renderer/src/ReactNoopServer.js b/packages/react-noop-renderer/src/ReactNoopServer.js index 8fbcb320827..491675dc73d 100644 --- a/packages/react-noop-renderer/src/ReactNoopServer.js +++ b/packages/react-noop-renderer/src/ReactNoopServer.js @@ -14,11 +14,11 @@ * environment. */ -import ReactFizzRenderer from 'react-stream'; +import ReactFizzStreamer from 'react-stream'; type Destination = Array; -const ReactNoopServer = ReactFizzRenderer({ +const ReactNoopServer = ReactFizzStreamer({ scheduleWork(callback: () => void) { callback(); }, diff --git a/packages/react-stream/index.js b/packages/react-stream/index.js index c807d4ed5aa..66445f67bf3 100644 --- a/packages/react-stream/index.js +++ b/packages/react-stream/index.js @@ -19,8 +19,8 @@ 'use strict'; -const ReactFizzRenderer = require('./src/ReactFizzRenderer'); +const ReactFizzStreamer = require('./src/ReactFizzStreamer'); // TODO: decide on the top-level export form. // This is hacky but makes it work with both Rollup and Jest. -module.exports = ReactFizzRenderer.default || ReactFizzRenderer; +module.exports = ReactFizzStreamer.default || ReactFizzStreamer; diff --git a/packages/react-stream/inline-typed.js b/packages/react-stream/inline-typed.js index 8bee7e9f3b4..32358e21e45 100644 --- a/packages/react-stream/inline-typed.js +++ b/packages/react-stream/inline-typed.js @@ -21,4 +21,4 @@ // renderers have different host config types. So we check them one by one. // We run Flow on all renderers on CI. -export * from './src/ReactFizzRenderer'; +export * from './src/ReactFizzStreamer'; diff --git a/packages/react-stream/inline.dom.js b/packages/react-stream/inline.dom.js index 2516cd5d7fb..9bae815dca1 100644 --- a/packages/react-stream/inline.dom.js +++ b/packages/react-stream/inline.dom.js @@ -8,4 +8,4 @@ // This file intentionally does *not* have the Flow annotation. // Don't add it. See `./inline-typed.js` for an explanation. -export * from './src/ReactFizzRenderer'; +export * from './src/ReactFizzStreamer'; diff --git a/packages/react-stream/src/ReactFizzRenderer.js b/packages/react-stream/src/ReactFizzStreamer.js similarity index 100% rename from packages/react-stream/src/ReactFizzRenderer.js rename to packages/react-stream/src/ReactFizzStreamer.js From dc27a9bbe21a098bc9b081fb36b910d5b8737f5c Mon Sep 17 00:00:00 2001 From: Sebastian Markbage Date: Wed, 7 Nov 2018 20:42:43 -0800 Subject: [PATCH 09/12] Prefix react-dom/fizz with react-dom/unstable-fizz --- packages/react-dom/npm/fizz.js | 3 - packages/react-dom/npm/fizz.node.js | 7 - packages/react-dom/npm/unstable-fizz.js | 3 + packages/react-dom/npm/unstable-fizz.node.js | 7 + packages/react-dom/package.json | 4 +- .../src/__tests__/ReactDOMFizzServer-test.js | 2 +- .../react-dom/{fizz.js => unstable-fizz.js} | 2 +- .../{fizz.node.js => unstable-fizz.node.js} | 0 scripts/rollup/bundles.js | 2 +- scripts/rollup/results.json | 242 +++++++++--------- scripts/shared/inlinedHostConfigs.js | 2 +- 11 files changed, 137 insertions(+), 137 deletions(-) delete mode 100644 packages/react-dom/npm/fizz.js delete mode 100644 packages/react-dom/npm/fizz.node.js create mode 100644 packages/react-dom/npm/unstable-fizz.js create mode 100644 packages/react-dom/npm/unstable-fizz.node.js rename packages/react-dom/{fizz.js => unstable-fizz.js} (81%) rename packages/react-dom/{fizz.node.js => unstable-fizz.node.js} (100%) diff --git a/packages/react-dom/npm/fizz.js b/packages/react-dom/npm/fizz.js deleted file mode 100644 index 232f89cee21..00000000000 --- a/packages/react-dom/npm/fizz.js +++ /dev/null @@ -1,3 +0,0 @@ -'use strict'; - -module.exports = require('./fizz.node'); diff --git a/packages/react-dom/npm/fizz.node.js b/packages/react-dom/npm/fizz.node.js deleted file mode 100644 index 616592945b1..00000000000 --- a/packages/react-dom/npm/fizz.node.js +++ /dev/null @@ -1,7 +0,0 @@ -'use strict'; - -if (process.env.NODE_ENV === 'production') { - module.exports = require('./cjs/react-dom-fizz.production.min.js'); -} else { - module.exports = require('./cjs/react-dom-fizz.development.js'); -} diff --git a/packages/react-dom/npm/unstable-fizz.js b/packages/react-dom/npm/unstable-fizz.js new file mode 100644 index 00000000000..ca4135d36b8 --- /dev/null +++ b/packages/react-dom/npm/unstable-fizz.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = require('./unstable-fizz.node'); diff --git a/packages/react-dom/npm/unstable-fizz.node.js b/packages/react-dom/npm/unstable-fizz.node.js new file mode 100644 index 00000000000..45babe4e005 --- /dev/null +++ b/packages/react-dom/npm/unstable-fizz.node.js @@ -0,0 +1,7 @@ +'use strict'; + +if (process.env.NODE_ENV === 'production') { + module.exports = require('./cjs/react-dom-unstable-fizz.production.min.js'); +} else { + module.exports = require('./cjs/react-dom-unstable-fizz.development.js'); +} diff --git a/packages/react-dom/package.json b/packages/react-dom/package.json index 1b91f7630bd..c0a6a94760f 100644 --- a/packages/react-dom/package.json +++ b/packages/react-dom/package.json @@ -30,10 +30,10 @@ "server.js", "server.browser.js", "server.node.js", - "fizz.js", - "fizz.node.js", "test-utils.js", "unstable-fire.js", + "unstable-fizz.js", + "unstable-fizz.node.js", "unstable-native-dependencies.js", "cjs/", "umd/" diff --git a/packages/react-dom/src/__tests__/ReactDOMFizzServer-test.js b/packages/react-dom/src/__tests__/ReactDOMFizzServer-test.js index 5a371f428c5..79fa80b322b 100644 --- a/packages/react-dom/src/__tests__/ReactDOMFizzServer-test.js +++ b/packages/react-dom/src/__tests__/ReactDOMFizzServer-test.js @@ -18,7 +18,7 @@ describe('ReactDOMFizzServer', () => { beforeEach(() => { jest.resetModules(); React = require('react'); - ReactDOMFizzServer = require('react-dom/fizz'); + ReactDOMFizzServer = require('react-dom/unstable-fizz'); Stream = require('stream'); }); diff --git a/packages/react-dom/fizz.js b/packages/react-dom/unstable-fizz.js similarity index 81% rename from packages/react-dom/fizz.js rename to packages/react-dom/unstable-fizz.js index 7376c1c8043..81d1ccee698 100644 --- a/packages/react-dom/fizz.js +++ b/packages/react-dom/unstable-fizz.js @@ -9,4 +9,4 @@ 'use strict'; -module.exports = require('./fizz.node'); +module.exports = require('./unstable-fizz.node'); diff --git a/packages/react-dom/fizz.node.js b/packages/react-dom/unstable-fizz.node.js similarity index 100% rename from packages/react-dom/fizz.node.js rename to packages/react-dom/unstable-fizz.node.js diff --git a/scripts/rollup/bundles.js b/scripts/rollup/bundles.js index cf44a66d6a4..3a6684beeca 100644 --- a/scripts/rollup/bundles.js +++ b/scripts/rollup/bundles.js @@ -162,7 +162,7 @@ const bundles = [ { bundleTypes: [NODE_DEV, NODE_PROD, FB_WWW_DEV, FB_WWW_PROD], moduleType: RENDERER, - entry: 'react-dom/fizz', + entry: 'react-dom/unstable-fizz', global: 'ReactDOMFizzServer', externals: ['react'], }, diff --git a/scripts/rollup/results.json b/scripts/rollup/results.json index 60165a161a4..b263a7dd276 100644 --- a/scripts/rollup/results.json +++ b/scripts/rollup/results.json @@ -46,29 +46,29 @@ "filename": "react-dom.development.js", "bundleType": "UMD_DEV", "packageName": "react-dom", - "size": 722087, - "gzip": 167270 + "size": 725813, + "gzip": 167799 }, { "filename": "react-dom.production.min.js", "bundleType": "UMD_PROD", "packageName": "react-dom", - "size": 100485, - "gzip": 32699 + "size": 99920, + "gzip": 32521 }, { "filename": "react-dom.development.js", "bundleType": "NODE_DEV", "packageName": "react-dom", - "size": 717285, - "gzip": 165860 + "size": 721011, + "gzip": 166399 }, { "filename": "react-dom.production.min.js", "bundleType": "NODE_PROD", "packageName": "react-dom", - "size": 100483, - "gzip": 32224 + "size": 99914, + "gzip": 32052 }, { "filename": "ReactDOM-dev.js", @@ -88,8 +88,8 @@ "filename": "react-dom-test-utils.development.js", "bundleType": "UMD_DEV", "packageName": "react-dom", - "size": 45943, - "gzip": 12588 + "size": 45937, + "gzip": 12585 }, { "filename": "react-dom-test-utils.production.min.js", @@ -102,8 +102,8 @@ "filename": "react-dom-test-utils.development.js", "bundleType": "NODE_DEV", "packageName": "react-dom", - "size": 45657, - "gzip": 12524 + "size": 45651, + "gzip": 12521 }, { "filename": "react-dom-test-utils.production.min.js", @@ -165,29 +165,29 @@ "filename": "react-dom-server.browser.development.js", "bundleType": "UMD_DEV", "packageName": "react-dom", - "size": 120452, - "gzip": 31996 + "size": 122056, + "gzip": 32469 }, { "filename": "react-dom-server.browser.production.min.js", "bundleType": "UMD_PROD", "packageName": "react-dom", - "size": 16379, - "gzip": 6228 + "size": 16402, + "gzip": 6237 }, { "filename": "react-dom-server.browser.development.js", "bundleType": "NODE_DEV", "packageName": "react-dom", - "size": 116490, - "gzip": 31019 + "size": 118094, + "gzip": 31495 }, { "filename": "react-dom-server.browser.production.min.js", "bundleType": "NODE_PROD", "packageName": "react-dom", - "size": 16278, - "gzip": 6228 + "size": 16301, + "gzip": 6233 }, { "filename": "ReactDOMServer-dev.js", @@ -207,43 +207,43 @@ "filename": "react-dom-server.node.development.js", "bundleType": "NODE_DEV", "packageName": "react-dom", - "size": 118458, - "gzip": 31567 + "size": 120062, + "gzip": 32036 }, { "filename": "react-dom-server.node.production.min.js", "bundleType": "NODE_PROD", "packageName": "react-dom", - "size": 17103, - "gzip": 6537 + "size": 17126, + "gzip": 6544 }, { "filename": "react-art.development.js", "bundleType": "UMD_DEV", "packageName": "react-art", - "size": 503592, - "gzip": 111526 + "size": 507846, + "gzip": 112120 }, { "filename": "react-art.production.min.js", "bundleType": "UMD_PROD", "packageName": "react-art", - "size": 92362, - "gzip": 28312 + "size": 91897, + "gzip": 28219 }, { "filename": "react-art.development.js", "bundleType": "NODE_DEV", "packageName": "react-art", - "size": 433726, - "gzip": 94096 + "size": 437983, + "gzip": 94680 }, { "filename": "react-art.production.min.js", "bundleType": "NODE_PROD", "packageName": "react-art", - "size": 56507, - "gzip": 17388 + "size": 56044, + "gzip": 17298 }, { "filename": "ReactART-dev.js", @@ -291,29 +291,29 @@ "filename": "react-test-renderer.development.js", "bundleType": "UMD_DEV", "packageName": "react-test-renderer", - "size": 446694, - "gzip": 96842 + "size": 450951, + "gzip": 97435 }, { "filename": "react-test-renderer.production.min.js", "bundleType": "UMD_PROD", "packageName": "react-test-renderer", - "size": 57752, - "gzip": 17656 + "size": 57293, + "gzip": 17617 }, { "filename": "react-test-renderer.development.js", "bundleType": "NODE_DEV", "packageName": "react-test-renderer", - "size": 441795, - "gzip": 95673 + "size": 446052, + "gzip": 96263 }, { "filename": "react-test-renderer.production.min.js", "bundleType": "NODE_PROD", "packageName": "react-test-renderer", - "size": 57418, - "gzip": 17523 + "size": 56955, + "gzip": 17453 }, { "filename": "ReactTestRenderer-dev.js", @@ -375,29 +375,29 @@ "filename": "react-reconciler.development.js", "bundleType": "NODE_DEV", "packageName": "react-reconciler", - "size": 431520, - "gzip": 92513 + "size": 435777, + "gzip": 93120 }, { "filename": "react-reconciler.production.min.js", "bundleType": "NODE_PROD", "packageName": "react-reconciler", - "size": 57675, - "gzip": 17242 + "size": 57202, + "gzip": 17158 }, { "filename": "react-reconciler-persistent.development.js", "bundleType": "NODE_DEV", "packageName": "react-reconciler", - "size": 429930, - "gzip": 91872 + "size": 434187, + "gzip": 92481 }, { "filename": "react-reconciler-persistent.production.min.js", "bundleType": "NODE_PROD", "packageName": "react-reconciler", - "size": 57686, - "gzip": 17248 + "size": 57213, + "gzip": 17164 }, { "filename": "react-reconciler-reflection.development.js", @@ -501,8 +501,8 @@ "filename": "React-dev.js", "bundleType": "FB_WWW_DEV", "packageName": "react", - "size": 58339, - "gzip": 15705 + "size": 58338, + "gzip": 15703 }, { "filename": "React-prod.js", @@ -515,15 +515,15 @@ "filename": "ReactDOM-dev.js", "bundleType": "FB_WWW_DEV", "packageName": "react-dom", - "size": 737575, - "gzip": 166976 + "size": 742241, + "gzip": 167544 }, { "filename": "ReactDOM-prod.js", "bundleType": "FB_WWW_PROD", "packageName": "react-dom", - "size": 303616, - "gzip": 55571 + "size": 317018, + "gzip": 58396 }, { "filename": "ReactTestUtils-dev.js", @@ -550,92 +550,92 @@ "filename": "ReactDOMServer-dev.js", "bundleType": "FB_WWW_DEV", "packageName": "react-dom", - "size": 117578, - "gzip": 30626 + "size": 119227, + "gzip": 31112 }, { "filename": "ReactDOMServer-prod.js", "bundleType": "FB_WWW_PROD", "packageName": "react-dom", - "size": 36376, - "gzip": 8710 + "size": 41626, + "gzip": 9808 }, { "filename": "ReactART-dev.js", "bundleType": "FB_WWW_DEV", "packageName": "react-art", - "size": 440023, - "gzip": 92845 + "size": 445295, + "gzip": 93558 }, { "filename": "ReactART-prod.js", "bundleType": "FB_WWW_PROD", "packageName": "react-art", - "size": 174075, - "gzip": 29293 + "size": 187912, + "gzip": 32090 }, { "filename": "ReactNativeRenderer-dev.js", "bundleType": "RN_FB_DEV", "packageName": "react-native-renderer", - "size": 568772, - "gzip": 124380 + "size": 573493, + "gzip": 124971 }, { "filename": "ReactNativeRenderer-prod.js", "bundleType": "RN_FB_PROD", "packageName": "react-native-renderer", - "size": 246039, - "gzip": 43290 + "size": 244566, + "gzip": 43021 }, { "filename": "ReactNativeRenderer-dev.js", "bundleType": "RN_OSS_DEV", "packageName": "react-native-renderer", - "size": 568461, - "gzip": 124285 + "size": 573182, + "gzip": 124874 }, { "filename": "ReactNativeRenderer-prod.js", "bundleType": "RN_OSS_PROD", "packageName": "react-native-renderer", - "size": 231135, - "gzip": 40179 + "size": 229659, + "gzip": 39880 }, { "filename": "ReactFabric-dev.js", "bundleType": "RN_FB_DEV", "packageName": "react-native-renderer", - "size": 558855, - "gzip": 121837 + "size": 563576, + "gzip": 122418 }, { "filename": "ReactFabric-prod.js", "bundleType": "RN_FB_PROD", "packageName": "react-native-renderer", - "size": 225246, - "gzip": 38817 + "size": 223730, + "gzip": 38540 }, { "filename": "ReactFabric-dev.js", "bundleType": "RN_OSS_DEV", "packageName": "react-native-renderer", - "size": 558890, - "gzip": 121851 + "size": 563611, + "gzip": 122433 }, { "filename": "ReactFabric-prod.js", "bundleType": "RN_OSS_PROD", "packageName": "react-native-renderer", - "size": 225282, - "gzip": 38831 + "size": 223766, + "gzip": 38555 }, { "filename": "ReactTestRenderer-dev.js", "bundleType": "FB_WWW_DEV", "packageName": "react-test-renderer", - "size": 448285, - "gzip": 94745 + "size": 453557, + "gzip": 95443 }, { "filename": "ReactShallowRenderer-dev.js", @@ -718,22 +718,22 @@ "filename": "react-dom.profiling.min.js", "bundleType": "NODE_PROFILING", "packageName": "react-dom", - "size": 103307, - "gzip": 32759 + "size": 102985, + "gzip": 32673 }, { "filename": "ReactNativeRenderer-profiling.js", "bundleType": "RN_OSS_PROFILING", "packageName": "react-native-renderer", - "size": 236436, - "gzip": 41394 + "size": 235342, + "gzip": 41248 }, { "filename": "ReactFabric-profiling.js", "bundleType": "RN_OSS_PROFILING", "packageName": "react-native-renderer", - "size": 229639, - "gzip": 40092 + "size": 228530, + "gzip": 39962 }, { "filename": "Scheduler-dev.js", @@ -767,22 +767,22 @@ "filename": "ReactDOM-profiling.js", "bundleType": "FB_WWW_PROFILING", "packageName": "react-dom", - "size": 309719, - "gzip": 56942 + "size": 323954, + "gzip": 59824 }, { "filename": "ReactNativeRenderer-profiling.js", "bundleType": "RN_FB_PROFILING", "packageName": "react-native-renderer", - "size": 251599, - "gzip": 44540 + "size": 250505, + "gzip": 44397 }, { "filename": "ReactFabric-profiling.js", "bundleType": "RN_FB_PROFILING", "packageName": "react-native-renderer", - "size": 229598, - "gzip": 40076 + "size": 228489, + "gzip": 39945 }, { "filename": "react.profiling.min.js", @@ -795,8 +795,8 @@ "filename": "react-dom.profiling.min.js", "bundleType": "UMD_PROFILING", "packageName": "react-dom", - "size": 103220, - "gzip": 33307 + "size": 102894, + "gzip": 33243 }, { "filename": "scheduler-tracing.development.js", @@ -922,7 +922,7 @@ "bundleType": "NODE_PROD", "packageName": "react-debug-tools", "size": 5402, - "gzip": 2188 + "gzip": 2187 }, { "filename": "eslint-plugin-react-hooks.development.js", @@ -938,61 +938,61 @@ "size": 4943, "gzip": 1815 }, - { - "filename": "react-dom-fizz.development.js", - "bundleType": "NODE_DEV", - "packageName": "react-dom", - "size": 988, - "gzip": 530 - }, - { - "filename": "react-dom-fizz.production.min.js", - "bundleType": "NODE_PROD", - "packageName": "react-dom", - "size": 346, - "gzip": 269 - }, { "filename": "ReactDOMFizzServer-dev.js", "bundleType": "FB_WWW_DEV", "packageName": "react-dom", - "size": 972, - "gzip": 517 + "size": 3660, + "gzip": 1408 }, { "filename": "ReactDOMFizzServer-prod.js", "bundleType": "FB_WWW_PROD", "packageName": "react-dom", - "size": 587, - "gzip": 307 + "size": 2092, + "gzip": 844 }, { "filename": "react-noop-renderer-server.development.js", "bundleType": "NODE_DEV", "packageName": "react-noop-renderer", - "size": 1326, - "gzip": 693 + "size": 1825, + "gzip": 864 }, { "filename": "react-noop-renderer-server.production.min.js", "bundleType": "NODE_PROD", "packageName": "react-noop-renderer", - "size": 498, - "gzip": 344 + "size": 785, + "gzip": 477 }, { "filename": "react-stream.development.js", "bundleType": "NODE_DEV", "packageName": "react-stream", - "size": 3135, - "gzip": 1176 + "size": 4508, + "gzip": 1650 }, { "filename": "react-stream.production.min.js", "bundleType": "NODE_PROD", "packageName": "react-stream", - "size": 652, - "gzip": 391 + "size": 1161, + "gzip": 631 + }, + { + "filename": "react-dom-unstable-fizz.development.js", + "bundleType": "NODE_DEV", + "packageName": "react-dom", + "size": 3663, + "gzip": 1417 + }, + { + "filename": "react-dom-unstable-fizz.production.min.js", + "bundleType": "NODE_PROD", + "packageName": "react-dom", + "size": 1073, + "gzip": 636 } ] } \ No newline at end of file diff --git a/scripts/shared/inlinedHostConfigs.js b/scripts/shared/inlinedHostConfigs.js index 52119703b17..457e50ddf64 100644 --- a/scripts/shared/inlinedHostConfigs.js +++ b/scripts/shared/inlinedHostConfigs.js @@ -9,7 +9,7 @@ module.exports = [ { shortName: 'dom', - entryPoints: ['react-dom', 'react-dom/fizz'], + entryPoints: ['react-dom', 'react-dom/unstable-fizz'], isFlowTyped: true, isFizzSupported: true, }, From ed1ed6752d6f7046520141895882e9be628d3605 Mon Sep 17 00:00:00 2001 From: Sebastian Markbage Date: Wed, 7 Nov 2018 23:20:37 -0800 Subject: [PATCH 10/12] 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. --- package.json | 3 +- .../react-dom/npm/unstable-fizz.browser.js | 7 ++ packages/react-dom/npm/unstable-fizz.node.js | 4 +- packages/react-dom/package.json | 4 +- .../ReactDOMFizzServerBrowser-test.js | 45 +++++++++++++ ...test.js => ReactDOMFizzServerNode-test.js} | 0 .../src/server/ReactDOMFizzServerBrowser.js | 34 ++++++++++ .../src/server/ReactDOMFizzServerNode.js | 5 +- packages/react-dom/unstable-fizz.browser.js | 16 +++++ .../src/ReactNoopServer.js | 1 + .../react-reconciler/inline.dom-browser.js | 11 ++++ .../forks/ReactFiberHostConfig.dom-browser.js | 10 +++ packages/react-stream/inline.dom-browser.js | 11 ++++ .../src/ReactFizzHostConfigBrowser.js | 37 +++++++++++ .../src/ReactFizzHostConfigNode.js | 4 ++ .../react-stream/src/ReactFizzStreamer.js | 6 +- .../ReactFizzFormatConfig.dom-browser.js | 10 +++ .../src/forks/ReactFizzHostConfig.custom.js | 1 + .../forks/ReactFizzHostConfig.dom-browser.js | 10 +++ scripts/rollup/bundles.js | 9 ++- scripts/rollup/results.json | 64 +++++++++++++------ scripts/shared/inlinedHostConfigs.js | 8 ++- yarn.lock | 12 ++++ 23 files changed, 286 insertions(+), 26 deletions(-) create mode 100644 packages/react-dom/npm/unstable-fizz.browser.js create mode 100644 packages/react-dom/src/__tests__/ReactDOMFizzServerBrowser-test.js rename packages/react-dom/src/__tests__/{ReactDOMFizzServer-test.js => ReactDOMFizzServerNode-test.js} (100%) create mode 100644 packages/react-dom/src/server/ReactDOMFizzServerBrowser.js create mode 100644 packages/react-dom/unstable-fizz.browser.js create mode 100644 packages/react-reconciler/inline.dom-browser.js create mode 100644 packages/react-reconciler/src/forks/ReactFiberHostConfig.dom-browser.js create mode 100644 packages/react-stream/inline.dom-browser.js create mode 100644 packages/react-stream/src/ReactFizzHostConfigBrowser.js create mode 100644 packages/react-stream/src/forks/ReactFizzFormatConfig.dom-browser.js create mode 100644 packages/react-stream/src/forks/ReactFizzHostConfig.dom-browser.js diff --git a/package.json b/package.json index f6829548c0a..eb5fe1324ba 100644 --- a/package.json +++ b/package.json @@ -84,7 +84,8 @@ "targz": "^1.0.1", "through2": "^2.0.0", "tmp": "~0.0.28", - "typescript": "~1.8.10" + "typescript": "~1.8.10", + "@mattiasbuelens/web-streams-polyfill": "0.1.0" }, "devEngines": { "node": "8.x || 9.x || 10.x" diff --git a/packages/react-dom/npm/unstable-fizz.browser.js b/packages/react-dom/npm/unstable-fizz.browser.js new file mode 100644 index 00000000000..976fac7eca5 --- /dev/null +++ b/packages/react-dom/npm/unstable-fizz.browser.js @@ -0,0 +1,7 @@ +'use strict'; + +if (process.env.NODE_ENV === 'production') { + module.exports = require('./cjs/react-dom-unstable-fizz.browser.production.min.js'); +} else { + module.exports = require('./cjs/react-dom-unstable-fizz.browser.development.js'); +} diff --git a/packages/react-dom/npm/unstable-fizz.node.js b/packages/react-dom/npm/unstable-fizz.node.js index 45babe4e005..038a3fd0fb4 100644 --- a/packages/react-dom/npm/unstable-fizz.node.js +++ b/packages/react-dom/npm/unstable-fizz.node.js @@ -1,7 +1,7 @@ 'use strict'; if (process.env.NODE_ENV === 'production') { - module.exports = require('./cjs/react-dom-unstable-fizz.production.min.js'); + module.exports = require('./cjs/react-dom-unstable-fizz.node.production.min.js'); } else { - module.exports = require('./cjs/react-dom-unstable-fizz.development.js'); + module.exports = require('./cjs/react-dom-unstable-fizz.node.development.js'); } diff --git a/packages/react-dom/package.json b/packages/react-dom/package.json index c0a6a94760f..c0c283ea04b 100644 --- a/packages/react-dom/package.json +++ b/packages/react-dom/package.json @@ -33,13 +33,15 @@ "test-utils.js", "unstable-fire.js", "unstable-fizz.js", + "unstable-fizz.browser.js", "unstable-fizz.node.js", "unstable-native-dependencies.js", "cjs/", "umd/" ], "browser": { - "./server.js": "./server.browser.js" + "./server.js": "./server.browser.js", + "./unstable-fizz.js": "./unstable-fizz.browser.js" }, "browserify": { "transform": [ diff --git a/packages/react-dom/src/__tests__/ReactDOMFizzServerBrowser-test.js b/packages/react-dom/src/__tests__/ReactDOMFizzServerBrowser-test.js new file mode 100644 index 00000000000..3d34b661104 --- /dev/null +++ b/packages/react-dom/src/__tests__/ReactDOMFizzServerBrowser-test.js @@ -0,0 +1,45 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @emails react-core + */ + +'use strict'; + +// Polyfills for test environment +global.ReadableStream = require('@mattiasbuelens/web-streams-polyfill/ponyfill/es6').ReadableStream; +global.TextEncoder = require('util').TextEncoder; + +let React; +let ReactDOMFizzServer; + +describe('ReactDOMFizzServer', () => { + beforeEach(() => { + jest.resetModules(); + React = require('react'); + ReactDOMFizzServer = require('react-dom/unstable-fizz.browser'); + }); + + async function readResult(stream) { + let reader = stream.getReader(); + let result = ''; + while (true) { + let {done, value} = await reader.read(); + if (done) { + return result; + } + result += Buffer.from(value).toString('utf8'); + } + } + + it('should call renderToReadableStream', async () => { + let stream = ReactDOMFizzServer.renderToReadableStream( +
hello world
, + ); + let result = await readResult(stream); + expect(result).toBe('
hello world
'); + }); +}); diff --git a/packages/react-dom/src/__tests__/ReactDOMFizzServer-test.js b/packages/react-dom/src/__tests__/ReactDOMFizzServerNode-test.js similarity index 100% rename from packages/react-dom/src/__tests__/ReactDOMFizzServer-test.js rename to packages/react-dom/src/__tests__/ReactDOMFizzServerNode-test.js diff --git a/packages/react-dom/src/server/ReactDOMFizzServerBrowser.js b/packages/react-dom/src/server/ReactDOMFizzServerBrowser.js new file mode 100644 index 00000000000..17da2d7e48e --- /dev/null +++ b/packages/react-dom/src/server/ReactDOMFizzServerBrowser.js @@ -0,0 +1,34 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @flow + */ + +import type {ReactNodeList} from 'shared/ReactTypes'; + +import { + createRequest, + startWork, + startFlowing, +} from 'react-stream/inline.dom-browser'; + +function renderToReadableStream(children: ReactNodeList): ReadableStream { + let request; + return new ReadableStream({ + start(controller) { + request = createRequest(children, controller); + startWork(request); + }, + pull(controller) { + startFlowing(request, controller.desiredSize); + }, + cancel(reason) {}, + }); +} + +export default { + renderToReadableStream, +}; diff --git a/packages/react-dom/src/server/ReactDOMFizzServerNode.js b/packages/react-dom/src/server/ReactDOMFizzServerNode.js index 39947c4defc..72b1bcb7427 100644 --- a/packages/react-dom/src/server/ReactDOMFizzServerNode.js +++ b/packages/react-dom/src/server/ReactDOMFizzServerNode.js @@ -16,7 +16,10 @@ function createDrainHandler(destination, request) { return () => startFlowing(request, 0); } -function pipeToNodeWritable(children: ReactNodeList, destination: Writable) { +function pipeToNodeWritable( + children: ReactNodeList, + destination: Writable, +): void { let request = createRequest(children, destination); destination.on('drain', createDrainHandler(destination, request)); startWork(request); diff --git a/packages/react-dom/unstable-fizz.browser.js b/packages/react-dom/unstable-fizz.browser.js new file mode 100644 index 00000000000..4fb175ec682 --- /dev/null +++ b/packages/react-dom/unstable-fizz.browser.js @@ -0,0 +1,16 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @flow + */ + +'use strict'; + +const ReactDOMFizzServerBrowser = require('./src/server/ReactDOMFizzServerBrowser'); + +// TODO: decide on the top-level export form. +// This is hacky but makes it work with both Rollup and Jest +module.exports = ReactDOMFizzServerBrowser.default || ReactDOMFizzServerBrowser; diff --git a/packages/react-noop-renderer/src/ReactNoopServer.js b/packages/react-noop-renderer/src/ReactNoopServer.js index 491675dc73d..2077687b9f9 100644 --- a/packages/react-noop-renderer/src/ReactNoopServer.js +++ b/packages/react-noop-renderer/src/ReactNoopServer.js @@ -27,6 +27,7 @@ const ReactNoopServer = ReactFizzStreamer({ destination.push(JSON.parse(Buffer.from((buffer: any)).toString('utf8'))); }, completeWriting(destination: Destination): void {}, + close(destination: Destination): void {}, flushBuffered(destination: Destination): void {}, convertStringToBuffer(content: string): Uint8Array { return Buffer.from(content, 'utf8'); diff --git a/packages/react-reconciler/inline.dom-browser.js b/packages/react-reconciler/inline.dom-browser.js new file mode 100644 index 00000000000..0d0c1546cc9 --- /dev/null +++ b/packages/react-reconciler/inline.dom-browser.js @@ -0,0 +1,11 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +// This file intentionally does *not* have the Flow annotation. +// Don't add it. See `./inline-typed.js` for an explanation. + +export * from './src/ReactFiberReconciler'; diff --git a/packages/react-reconciler/src/forks/ReactFiberHostConfig.dom-browser.js b/packages/react-reconciler/src/forks/ReactFiberHostConfig.dom-browser.js new file mode 100644 index 00000000000..d830c8501be --- /dev/null +++ b/packages/react-reconciler/src/forks/ReactFiberHostConfig.dom-browser.js @@ -0,0 +1,10 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @flow + */ + +export * from 'react-dom/src/client/ReactDOMHostConfig'; diff --git a/packages/react-stream/inline.dom-browser.js b/packages/react-stream/inline.dom-browser.js new file mode 100644 index 00000000000..9bae815dca1 --- /dev/null +++ b/packages/react-stream/inline.dom-browser.js @@ -0,0 +1,11 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +// This file intentionally does *not* have the Flow annotation. +// Don't add it. See `./inline-typed.js` for an explanation. + +export * from './src/ReactFizzStreamer'; diff --git a/packages/react-stream/src/ReactFizzHostConfigBrowser.js b/packages/react-stream/src/ReactFizzHostConfigBrowser.js new file mode 100644 index 00000000000..390a6efc827 --- /dev/null +++ b/packages/react-stream/src/ReactFizzHostConfigBrowser.js @@ -0,0 +1,37 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @flow + */ + +export type Destination = ReadableStreamController; + +export function scheduleWork(callback: () => void) { + callback(); +} + +export function flushBuffered(destination: Destination) { + // WHATWG Streams do not yet have a way to flush the underlying + // transform streams. https://github.com/whatwg/streams/issues/960 +} + +export function beginWriting(destination: Destination) {} + +export function writeChunk(destination: Destination, buffer: Uint8Array) { + destination.enqueue(buffer); +} + +export function completeWriting(destination: Destination) {} + +export function close(destination: Destination) { + destination.close(); +} + +const textEncoder = new TextEncoder(); + +export function convertStringToBuffer(content: string): Uint8Array { + return textEncoder.encode(content); +} diff --git a/packages/react-stream/src/ReactFizzHostConfigNode.js b/packages/react-stream/src/ReactFizzHostConfigNode.js index d6622376e33..2ee9ddec354 100644 --- a/packages/react-stream/src/ReactFizzHostConfigNode.js +++ b/packages/react-stream/src/ReactFizzHostConfigNode.js @@ -39,6 +39,10 @@ export function completeWriting(destination: Destination) { destination.uncork(); } +export function close(destination: Destination) { + destination.end(); +} + export function convertStringToBuffer(content: string): Uint8Array { return Buffer.from(content, 'utf8'); } diff --git a/packages/react-stream/src/ReactFizzStreamer.js b/packages/react-stream/src/ReactFizzStreamer.js index 60480735356..80239287c21 100644 --- a/packages/react-stream/src/ReactFizzStreamer.js +++ b/packages/react-stream/src/ReactFizzStreamer.js @@ -16,6 +16,7 @@ import { writeChunk, completeWriting, flushBuffered, + close, } from './ReactFizzHostConfig'; import {formatChunk} from './ReactFizzFormatConfig'; import {REACT_ELEMENT_TYPE} from 'shared/ReactSymbols'; @@ -36,7 +37,8 @@ export function createRequest( function performWork(request: OpaqueRequest): void { let element = (request.children: any); - if (element.$$typeof !== REACT_ELEMENT_TYPE) { + request.children = null; + if (element && element.$$typeof !== REACT_ELEMENT_TYPE) { return; } let type = element.type; @@ -55,6 +57,7 @@ function performWork(request: OpaqueRequest): void { function flushCompletedChunks(request: OpaqueRequest) { let destination = request.destination; let chunks = request.completedChunks; + request.completedChunks = []; beginWriting(destination); try { @@ -65,6 +68,7 @@ function flushCompletedChunks(request: OpaqueRequest) { } finally { completeWriting(destination); } + close(destination); } export function startWork(request: OpaqueRequest): void { diff --git a/packages/react-stream/src/forks/ReactFizzFormatConfig.dom-browser.js b/packages/react-stream/src/forks/ReactFizzFormatConfig.dom-browser.js new file mode 100644 index 00000000000..e3b8782adee --- /dev/null +++ b/packages/react-stream/src/forks/ReactFizzFormatConfig.dom-browser.js @@ -0,0 +1,10 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @flow + */ + +export * from 'react-dom/src/server/ReactDOMFizzServerFormatConfig'; diff --git a/packages/react-stream/src/forks/ReactFizzHostConfig.custom.js b/packages/react-stream/src/forks/ReactFizzHostConfig.custom.js index aca4559cd23..71d876a10e5 100644 --- a/packages/react-stream/src/forks/ReactFizzHostConfig.custom.js +++ b/packages/react-stream/src/forks/ReactFizzHostConfig.custom.js @@ -31,4 +31,5 @@ export const beginWriting = $$$hostConfig.beginWriting; export const writeChunk = $$$hostConfig.writeChunk; export const completeWriting = $$$hostConfig.completeWriting; export const flushBuffered = $$$hostConfig.flushBuffered; +export const close = $$$hostConfig.close; export const convertStringToBuffer = $$$hostConfig.convertStringToBuffer; diff --git a/packages/react-stream/src/forks/ReactFizzHostConfig.dom-browser.js b/packages/react-stream/src/forks/ReactFizzHostConfig.dom-browser.js new file mode 100644 index 00000000000..ff949e1c746 --- /dev/null +++ b/packages/react-stream/src/forks/ReactFizzHostConfig.dom-browser.js @@ -0,0 +1,10 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @flow + */ + +export * from '../ReactFizzHostConfigBrowser'; diff --git a/scripts/rollup/bundles.js b/scripts/rollup/bundles.js index 3a6684beeca..b599ea40554 100644 --- a/scripts/rollup/bundles.js +++ b/scripts/rollup/bundles.js @@ -159,10 +159,17 @@ const bundles = [ }, /******* React DOM Fizz Server *******/ + { + bundleTypes: [NODE_DEV, NODE_PROD, UMD_DEV, UMD_PROD], + moduleType: RENDERER, + entry: 'react-dom/unstable-fizz.browser', + global: 'ReactDOMFizzServer', + externals: ['react'], + }, { bundleTypes: [NODE_DEV, NODE_PROD, FB_WWW_DEV, FB_WWW_PROD], moduleType: RENDERER, - entry: 'react-dom/unstable-fizz', + entry: 'react-dom/unstable-fizz.node', global: 'ReactDOMFizzServer', externals: ['react'], }, diff --git a/scripts/rollup/results.json b/scripts/rollup/results.json index b263a7dd276..91d4f827bac 100644 --- a/scripts/rollup/results.json +++ b/scripts/rollup/results.json @@ -942,57 +942,85 @@ "filename": "ReactDOMFizzServer-dev.js", "bundleType": "FB_WWW_DEV", "packageName": "react-dom", - "size": 3660, - "gzip": 1408 + "size": 3772, + "gzip": 1432 }, { "filename": "ReactDOMFizzServer-prod.js", "bundleType": "FB_WWW_PROD", "packageName": "react-dom", - "size": 2092, - "gzip": 844 + "size": 2211, + "gzip": 874 }, { "filename": "react-noop-renderer-server.development.js", "bundleType": "NODE_DEV", "packageName": "react-noop-renderer", - "size": 1825, - "gzip": 864 + "size": 1861, + "gzip": 869 }, { "filename": "react-noop-renderer-server.production.min.js", "bundleType": "NODE_PROD", "packageName": "react-noop-renderer", - "size": 785, - "gzip": 477 + "size": 804, + "gzip": 482 }, { "filename": "react-stream.development.js", "bundleType": "NODE_DEV", "packageName": "react-stream", - "size": 4508, - "gzip": 1650 + "size": 4633, + "gzip": 1683 }, { "filename": "react-stream.production.min.js", "bundleType": "NODE_PROD", "packageName": "react-stream", - "size": 1161, - "gzip": 631 + "size": 1224, + "gzip": 655 }, { - "filename": "react-dom-unstable-fizz.development.js", + "filename": "react-dom-unstable-fizz.browser.development.js", + "bundleType": "UMD_DEV", + "packageName": "react-dom", + "size": 3704, + "gzip": 1463 + }, + { + "filename": "react-dom-unstable-fizz.browser.production.min.js", + "bundleType": "UMD_PROD", + "packageName": "react-dom", + "size": 1227, + "gzip": 697 + }, + { + "filename": "react-dom-unstable-fizz.browser.development.js", + "bundleType": "NODE_DEV", + "packageName": "react-dom", + "size": 3528, + "gzip": 1416 + }, + { + "filename": "react-dom-unstable-fizz.browser.production.min.js", + "bundleType": "NODE_PROD", + "packageName": "react-dom", + "size": 1063, + "gzip": 628 + }, + { + "filename": "react-dom-unstable-fizz.node.development.js", "bundleType": "NODE_DEV", "packageName": "react-dom", - "size": 3663, - "gzip": 1417 + "size": 3780, + "gzip": 1443 }, { - "filename": "react-dom-unstable-fizz.production.min.js", + "filename": "react-dom-unstable-fizz.node.production.min.js", "bundleType": "NODE_PROD", "packageName": "react-dom", - "size": 1073, - "gzip": 636 + "size": 1122, + "gzip": 659 } ] } \ No newline at end of file diff --git a/scripts/shared/inlinedHostConfigs.js b/scripts/shared/inlinedHostConfigs.js index 457e50ddf64..66c54963c7f 100644 --- a/scripts/shared/inlinedHostConfigs.js +++ b/scripts/shared/inlinedHostConfigs.js @@ -9,7 +9,13 @@ module.exports = [ { shortName: 'dom', - entryPoints: ['react-dom', 'react-dom/unstable-fizz'], + entryPoints: ['react-dom', 'react-dom/unstable-fizz.node'], + isFlowTyped: true, + isFizzSupported: true, + }, + { + shortName: 'dom-browser', + entryPoints: ['react-dom/unstable-fizz.browser'], isFlowTyped: true, isFizzSupported: true, }, diff --git a/yarn.lock b/yarn.lock index c9ffffa9fd9..5bb72e40fd3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -94,6 +94,18 @@ lodash "^4.17.10" to-fast-properties "^2.0.0" +"@mattiasbuelens/web-streams-polyfill@0.1.0": + version "0.1.0" + resolved "https://registry.yarnpkg.com/@mattiasbuelens/web-streams-polyfill/-/web-streams-polyfill-0.1.0.tgz#c06ebfa7e00cc512a878c3aaae4cf113ac89ac24" + integrity sha512-oMsvblvOezdM/j1ph0uU8s6Wm0EfCyMZtZcxQ232CqSpjm08lrKPizeMltN0eVv4dQf0DDFaxUFyiz8x51lgAA== + dependencies: + "@types/whatwg-streams" "^0.0.6" + +"@types/whatwg-streams@^0.0.6": + version "0.0.6" + resolved "https://registry.yarnpkg.com/@types/whatwg-streams/-/whatwg-streams-0.0.6.tgz#5062c67efb695c886fe3dbb9618df35aac418503" + integrity sha512-O4Hat94N1RUCObqAbVUtd6EcucseqBcpfbFXzy12CYF6BQVHWR+ztDA3YPjewCmdKHYZ5VA7TZ5hq2bMyqxiBw== + abab@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/abab/-/abab-1.0.4.tgz#5faad9c2c07f60dd76770f71cf025b62a63cfd4e" From 3d45ea1108d4c81296f5ee373c46207193efb248 Mon Sep 17 00:00:00 2001 From: Sebastian Markbage Date: Thu, 8 Nov 2018 00:20:45 -0800 Subject: [PATCH 11/12] Add Fizz Browser Fixture This is for testing server rendering - on the client. --- fixtures/fizz-ssr-browser/index.html | 40 ++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 fixtures/fizz-ssr-browser/index.html diff --git a/fixtures/fizz-ssr-browser/index.html b/fixtures/fizz-ssr-browser/index.html new file mode 100644 index 00000000000..aa522dfe836 --- /dev/null +++ b/fixtures/fizz-ssr-browser/index.html @@ -0,0 +1,40 @@ + + + + + Fizz Example + + +

Fizz Example

+
+

+ To install React, follow the instructions on + GitHub. +

+

+ If you can see this, React is not working right. + If you checked out the source from GitHub make sure to run npm run build. +

+
+ + + + + + From b1182d1b7e5c0cfa992192bfa95c3c431ce5b365 Mon Sep 17 00:00:00 2001 From: Sebastian Markbage Date: Mon, 26 Nov 2018 14:18:00 -0800 Subject: [PATCH 12/12] Lower version number to detach it from react-reconciler version --- packages/react-stream/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react-stream/package.json b/packages/react-stream/package.json index 38dc3ad5ca7..411dab92c01 100644 --- a/packages/react-stream/package.json +++ b/packages/react-stream/package.json @@ -1,7 +1,7 @@ { "name": "react-stream", "description": "React package for creating custom streaming server renderers.", - "version": "0.16.0", + "version": "0.1.0", "private": true, "keywords": [ "react"