diff --git a/packages/react-dom/server.browser.js b/packages/react-dom/server.browser.js
index df45b9fa9fd63..c57063649a9f0 100644
--- a/packages/react-dom/server.browser.js
+++ b/packages/react-dom/server.browser.js
@@ -7,10 +7,10 @@
* @flow
*/
-'use strict';
-
-const ReactDOMServer = require('./src/server/ReactDOMServerBrowser');
-
-// TODO: decide on the top-level export form.
-// This is hacky but makes it work with both Rollup and Jest
-module.exports = ReactDOMServer.default || ReactDOMServer;
+export {
+ renderToString,
+ renderToStaticMarkup,
+ renderToNodeStream,
+ renderToStaticNodeStream,
+ version,
+} from './src/server/ReactDOMServerBrowser';
diff --git a/packages/react-dom/server.js b/packages/react-dom/server.js
index 03006336ba4fe..6010f4e3d5b22 100644
--- a/packages/react-dom/server.js
+++ b/packages/react-dom/server.js
@@ -7,6 +7,4 @@
* @flow
*/
-'use strict';
-
-module.exports = require('./server.node');
+export * from './server.node';
diff --git a/packages/react-dom/server.node.js b/packages/react-dom/server.node.js
index 66e1ea1f0f9ad..e610a8818f961 100644
--- a/packages/react-dom/server.node.js
+++ b/packages/react-dom/server.node.js
@@ -7,10 +7,11 @@
* @flow
*/
-'use strict';
-
-const ReactDOMServer = require('./src/server/ReactDOMServerNode');
-
-// TODO: decide on the top-level export form.
-// This is hacky but makes it work with both Rollup and Jest
-module.exports = ReactDOMServer.default || ReactDOMServer;
+// For some reason Flow doesn't like export * in this file. I don't know why.
+export {
+ renderToString,
+ renderToStaticMarkup,
+ renderToNodeStream,
+ renderToStaticNodeStream,
+ version,
+} from './src/server/ReactDOMServerNode';
diff --git a/packages/react-dom/src/__tests__/ReactTestUtils-test.js b/packages/react-dom/src/__tests__/ReactTestUtils-test.js
index 540f23edd17c0..b0ac326e9573e 100644
--- a/packages/react-dom/src/__tests__/ReactTestUtils-test.js
+++ b/packages/react-dom/src/__tests__/ReactTestUtils-test.js
@@ -9,11 +9,11 @@
'use strict';
-let createRenderer;
-let React;
-let ReactDOM;
-let ReactDOMServer;
-let ReactTestUtils;
+import ReactShallowRenderer from 'react-test-renderer/shallow';
+import * as React from 'react';
+import * as ReactDOM from 'react-dom';
+import * as ReactDOMServer from 'react-dom/server';
+import * as ReactTestUtils from 'react-dom/test-utils';
function getTestDocument(markup) {
const doc = document.implementation.createHTMLDocument('');
@@ -27,14 +27,6 @@ function getTestDocument(markup) {
}
describe('ReactTestUtils', () => {
- beforeEach(() => {
- createRenderer = require('react-test-renderer/shallow').createRenderer;
- React = require('react');
- ReactDOM = require('react-dom');
- ReactDOMServer = require('react-dom/server');
- ReactTestUtils = require('react-dom/test-utils');
- });
-
it('Simulate should have locally attached media events', () => {
expect(Object.keys(ReactTestUtils.Simulate).sort()).toMatchSnapshot();
});
@@ -403,7 +395,7 @@ describe('ReactTestUtils', () => {
}
const handler = jest.fn().mockName('spy');
- const shallowRenderer = createRenderer();
+ const shallowRenderer = ReactShallowRenderer.createRenderer();
const result = shallowRenderer.render(
,
);
diff --git a/packages/react-dom/src/server/ReactDOMFizzServerBrowser.js b/packages/react-dom/src/server/ReactDOMFizzServerBrowser.js
index 93419fa27194b..cbf83b1b71aed 100644
--- a/packages/react-dom/src/server/ReactDOMFizzServerBrowser.js
+++ b/packages/react-dom/src/server/ReactDOMFizzServerBrowser.js
@@ -29,6 +29,4 @@ function renderToReadableStream(children: ReactNodeList): ReadableStream {
});
}
-export default {
- renderToReadableStream,
-};
+export {renderToReadableStream};
diff --git a/packages/react-dom/src/server/ReactDOMFizzServerNode.js b/packages/react-dom/src/server/ReactDOMFizzServerNode.js
index 3815e1f958ef8..154b4fff204a6 100644
--- a/packages/react-dom/src/server/ReactDOMFizzServerNode.js
+++ b/packages/react-dom/src/server/ReactDOMFizzServerNode.js
@@ -25,6 +25,4 @@ function pipeToNodeWritable(
startWork(request);
}
-export default {
- pipeToNodeWritable,
-};
+export {pipeToNodeWritable};
diff --git a/packages/react-dom/src/server/ReactDOMServerBrowser.js b/packages/react-dom/src/server/ReactDOMServerBrowser.js
index 58f04b4960b31..4424040496b99 100644
--- a/packages/react-dom/src/server/ReactDOMServerBrowser.js
+++ b/packages/react-dom/src/server/ReactDOMServerBrowser.js
@@ -26,11 +26,10 @@ function renderToStaticNodeStream() {
);
}
-// Note: when changing this, also consider https://github.com/facebook/react/issues/11526
-export default {
+export {
renderToString,
renderToStaticMarkup,
renderToNodeStream,
renderToStaticNodeStream,
- version: ReactVersion,
+ ReactVersion as version,
};
diff --git a/packages/react-dom/src/server/ReactDOMServerNode.js b/packages/react-dom/src/server/ReactDOMServerNode.js
index b1f955eef53d7..1347434b6900c 100644
--- a/packages/react-dom/src/server/ReactDOMServerNode.js
+++ b/packages/react-dom/src/server/ReactDOMServerNode.js
@@ -13,11 +13,10 @@ import {
renderToStaticNodeStream,
} from './ReactDOMNodeStreamRenderer';
-// Note: when changing this, also consider https://github.com/facebook/react/issues/11526
-export default {
+export {
renderToString,
renderToStaticMarkup,
renderToNodeStream,
renderToStaticNodeStream,
- version: ReactVersion,
+ ReactVersion as version,
};
diff --git a/packages/react-dom/src/test-utils/ReactTestUtils.js b/packages/react-dom/src/test-utils/ReactTestUtils.js
index 5ac2948c1c36b..9449880c83ed4 100644
--- a/packages/react-dom/src/test-utils/ReactTestUtils.js
+++ b/packages/react-dom/src/test-utils/ReactTestUtils.js
@@ -159,243 +159,233 @@ function validateClassInstance(inst, methodName) {
* utilities will suffice for testing purposes.
* @lends ReactTestUtils
*/
-const ReactTestUtils = {
- renderIntoDocument: function(element) {
- const div = document.createElement('div');
- // None of our tests actually require attaching the container to the
- // DOM, and doing so creates a mess that we rely on test isolation to
- // clean up, so we're going to stop honoring the name of this method
- // (and probably rename it eventually) if no problems arise.
- // document.documentElement.appendChild(div);
- return ReactDOM.render(element, div);
- },
-
- isElement: function(element) {
- return React.isValidElement(element);
- },
-
- isElementOfType: function(inst, convenienceConstructor) {
- return React.isValidElement(inst) && inst.type === convenienceConstructor;
- },
-
- isDOMComponent: function(inst) {
- return !!(inst && inst.nodeType === ELEMENT_NODE && inst.tagName);
- },
-
- isDOMComponentElement: function(inst) {
- return !!(inst && React.isValidElement(inst) && !!inst.tagName);
- },
-
- isCompositeComponent: function(inst) {
- if (ReactTestUtils.isDOMComponent(inst)) {
- // Accessing inst.setState warns; just return false as that'll be what
- // this returns when we have DOM nodes as refs directly
- return false;
- }
- return (
- inst != null &&
- typeof inst.render === 'function' &&
- typeof inst.setState === 'function'
- );
- },
+function renderIntoDocument(element) {
+ const div = document.createElement('div');
+ // None of our tests actually require attaching the container to the
+ // DOM, and doing so creates a mess that we rely on test isolation to
+ // clean up, so we're going to stop honoring the name of this method
+ // (and probably rename it eventually) if no problems arise.
+ // document.documentElement.appendChild(div);
+ return ReactDOM.render(element, div);
+}
- isCompositeComponentWithType: function(inst, type) {
- if (!ReactTestUtils.isCompositeComponent(inst)) {
- return false;
- }
- const internalInstance = getInstance(inst);
- const constructor = internalInstance.type;
- return constructor === type;
- },
-
- findAllInRenderedTree: function(inst, test) {
- validateClassInstance(inst, 'findAllInRenderedTree');
- if (!inst) {
- return [];
- }
- const internalInstance = getInstance(inst);
- return findAllInRenderedFiberTreeInternal(internalInstance, test);
- },
+function isElement(element) {
+ return React.isValidElement(element);
+}
- /**
- * Finds all instance of components in the rendered tree that are DOM
- * components with the class name matching `className`.
- * @return {array} an array of all the matches.
- */
- scryRenderedDOMComponentsWithClass: function(root, classNames) {
- validateClassInstance(root, 'scryRenderedDOMComponentsWithClass');
- return ReactTestUtils.findAllInRenderedTree(root, function(inst) {
- if (ReactTestUtils.isDOMComponent(inst)) {
- let className = inst.className;
- if (typeof className !== 'string') {
- // SVG, probably.
- className = inst.getAttribute('class') || '';
- }
- const classList = className.split(/\s+/);
-
- if (!Array.isArray(classNames)) {
- invariant(
- classNames !== undefined,
- 'TestUtils.scryRenderedDOMComponentsWithClass expects a ' +
- 'className as a second argument.',
- );
- classNames = classNames.split(/\s+/);
- }
- return classNames.every(function(name) {
- return classList.indexOf(name) !== -1;
- });
- }
- return false;
- });
- },
+function isElementOfType(inst, convenienceConstructor) {
+ return React.isValidElement(inst) && inst.type === convenienceConstructor;
+}
- /**
- * Like scryRenderedDOMComponentsWithClass but expects there to be one result,
- * and returns that one result, or throws exception if there is any other
- * number of matches besides one.
- * @return {!ReactDOMComponent} The one match.
- */
- findRenderedDOMComponentWithClass: function(root, className) {
- validateClassInstance(root, 'findRenderedDOMComponentWithClass');
- const all = ReactTestUtils.scryRenderedDOMComponentsWithClass(
- root,
- className,
- );
- if (all.length !== 1) {
- throw new Error(
- 'Did not find exactly one match (found: ' +
- all.length +
- ') ' +
- 'for class:' +
- className,
- );
- }
- return all[0];
- },
+function isDOMComponent(inst) {
+ return !!(inst && inst.nodeType === ELEMENT_NODE && inst.tagName);
+}
- /**
- * Finds all instance of components in the rendered tree that are DOM
- * components with the tag name matching `tagName`.
- * @return {array} an array of all the matches.
- */
- scryRenderedDOMComponentsWithTag: function(root, tagName) {
- validateClassInstance(root, 'scryRenderedDOMComponentsWithTag');
- return ReactTestUtils.findAllInRenderedTree(root, function(inst) {
- return (
- ReactTestUtils.isDOMComponent(inst) &&
- inst.tagName.toUpperCase() === tagName.toUpperCase()
- );
- });
- },
+function isDOMComponentElement(inst) {
+ return !!(inst && React.isValidElement(inst) && !!inst.tagName);
+}
- /**
- * Like scryRenderedDOMComponentsWithTag but expects there to be one result,
- * and returns that one result, or throws exception if there is any other
- * number of matches besides one.
- * @return {!ReactDOMComponent} The one match.
- */
- findRenderedDOMComponentWithTag: function(root, tagName) {
- validateClassInstance(root, 'findRenderedDOMComponentWithTag');
- const all = ReactTestUtils.scryRenderedDOMComponentsWithTag(root, tagName);
- if (all.length !== 1) {
- throw new Error(
- 'Did not find exactly one match (found: ' +
- all.length +
- ') ' +
- 'for tag:' +
- tagName,
- );
- }
- return all[0];
- },
+function isCompositeComponent(inst) {
+ if (isDOMComponent(inst)) {
+ // Accessing inst.setState warns; just return false as that'll be what
+ // this returns when we have DOM nodes as refs directly
+ return false;
+ }
+ return (
+ inst != null &&
+ typeof inst.render === 'function' &&
+ typeof inst.setState === 'function'
+ );
+}
- /**
- * Finds all instances of components with type equal to `componentType`.
- * @return {array} an array of all the matches.
- */
- scryRenderedComponentsWithType: function(root, componentType) {
- validateClassInstance(root, 'scryRenderedComponentsWithType');
- return ReactTestUtils.findAllInRenderedTree(root, function(inst) {
- return ReactTestUtils.isCompositeComponentWithType(inst, componentType);
- });
- },
+function isCompositeComponentWithType(inst, type) {
+ if (!isCompositeComponent(inst)) {
+ return false;
+ }
+ const internalInstance = getInstance(inst);
+ const constructor = internalInstance.type;
+ return constructor === type;
+}
- /**
- * Same as `scryRenderedComponentsWithType` but expects there to be one result
- * and returns that one result, or throws exception if there is any other
- * number of matches besides one.
- * @return {!ReactComponent} The one match.
- */
- findRenderedComponentWithType: function(root, componentType) {
- validateClassInstance(root, 'findRenderedComponentWithType');
- const all = ReactTestUtils.scryRenderedComponentsWithType(
- root,
- componentType,
- );
- if (all.length !== 1) {
- throw new Error(
- 'Did not find exactly one match (found: ' +
- all.length +
- ') ' +
- 'for componentType:' +
- componentType,
- );
- }
- return all[0];
- },
+function findAllInRenderedTree(inst, test) {
+ validateClassInstance(inst, 'findAllInRenderedTree');
+ if (!inst) {
+ return [];
+ }
+ const internalInstance = getInstance(inst);
+ return findAllInRenderedFiberTreeInternal(internalInstance, test);
+}
- /**
- * Pass a mocked component module to this method to augment it with
- * useful methods that allow it to be used as a dummy React component.
- * Instead of rendering as usual, the component will become a simple
- *
containing any provided children.
- *
- * @param {object} module the mock function object exported from a
- * module that defines the component to be mocked
- * @param {?string} mockTagName optional dummy root tag name to return
- * from render method (overrides
- * module.mockTagName if provided)
- * @return {object} the ReactTestUtils object (for chaining)
- */
- mockComponent: function(module, mockTagName) {
- if (__DEV__) {
- if (!hasWarnedAboutDeprecatedMockComponent) {
- hasWarnedAboutDeprecatedMockComponent = true;
- console.warn(
- 'ReactTestUtils.mockComponent() is deprecated. ' +
- 'Use shallow rendering or jest.mock() instead.\n\n' +
- 'See https://fb.me/test-utils-mock-component for more information.',
+/**
+ * Finds all instance of components in the rendered tree that are DOM
+ * components with the class name matching `className`.
+ * @return {array} an array of all the matches.
+ */
+function scryRenderedDOMComponentsWithClass(root, classNames) {
+ validateClassInstance(root, 'scryRenderedDOMComponentsWithClass');
+ return findAllInRenderedTree(root, function(inst) {
+ if (isDOMComponent(inst)) {
+ let className = inst.className;
+ if (typeof className !== 'string') {
+ // SVG, probably.
+ className = inst.getAttribute('class') || '';
+ }
+ const classList = className.split(/\s+/);
+
+ if (!Array.isArray(classNames)) {
+ invariant(
+ classNames !== undefined,
+ 'TestUtils.scryRenderedDOMComponentsWithClass expects a ' +
+ 'className as a second argument.',
);
+ classNames = classNames.split(/\s+/);
}
+ return classNames.every(function(name) {
+ return classList.indexOf(name) !== -1;
+ });
}
+ return false;
+ });
+}
- mockTagName = mockTagName || module.mockTagName || 'div';
+/**
+ * Like scryRenderedDOMComponentsWithClass but expects there to be one result,
+ * and returns that one result, or throws exception if there is any other
+ * number of matches besides one.
+ * @return {!ReactDOMComponent} The one match.
+ */
+function findRenderedDOMComponentWithClass(root, className) {
+ validateClassInstance(root, 'findRenderedDOMComponentWithClass');
+ const all = scryRenderedDOMComponentsWithClass(root, className);
+ if (all.length !== 1) {
+ throw new Error(
+ 'Did not find exactly one match (found: ' +
+ all.length +
+ ') ' +
+ 'for class:' +
+ className,
+ );
+ }
+ return all[0];
+}
- module.prototype.render.mockImplementation(function() {
- return React.createElement(mockTagName, null, this.props.children);
- });
+/**
+ * Finds all instance of components in the rendered tree that are DOM
+ * components with the tag name matching `tagName`.
+ * @return {array} an array of all the matches.
+ */
+function scryRenderedDOMComponentsWithTag(root, tagName) {
+ validateClassInstance(root, 'scryRenderedDOMComponentsWithTag');
+ return findAllInRenderedTree(root, function(inst) {
+ return (
+ isDOMComponent(inst) &&
+ inst.tagName.toUpperCase() === tagName.toUpperCase()
+ );
+ });
+}
- return this;
- },
+/**
+ * Like scryRenderedDOMComponentsWithTag but expects there to be one result,
+ * and returns that one result, or throws exception if there is any other
+ * number of matches besides one.
+ * @return {!ReactDOMComponent} The one match.
+ */
+function findRenderedDOMComponentWithTag(root, tagName) {
+ validateClassInstance(root, 'findRenderedDOMComponentWithTag');
+ const all = scryRenderedDOMComponentsWithTag(root, tagName);
+ if (all.length !== 1) {
+ throw new Error(
+ 'Did not find exactly one match (found: ' +
+ all.length +
+ ') ' +
+ 'for tag:' +
+ tagName,
+ );
+ }
+ return all[0];
+}
- nativeTouchData: function(x, y) {
- return {
- touches: [{pageX: x, pageY: y}],
- };
- },
+/**
+ * Finds all instances of components with type equal to `componentType`.
+ * @return {array} an array of all the matches.
+ */
+function scryRenderedComponentsWithType(root, componentType) {
+ validateClassInstance(root, 'scryRenderedComponentsWithType');
+ return findAllInRenderedTree(root, function(inst) {
+ return isCompositeComponentWithType(inst, componentType);
+ });
+}
- Simulate: null,
- SimulateNative: {},
+/**
+ * Same as `scryRenderedComponentsWithType` but expects there to be one result
+ * and returns that one result, or throws exception if there is any other
+ * number of matches besides one.
+ * @return {!ReactComponent} The one match.
+ */
+function findRenderedComponentWithType(root, componentType) {
+ validateClassInstance(root, 'findRenderedComponentWithType');
+ const all = scryRenderedComponentsWithType(root, componentType);
+ if (all.length !== 1) {
+ throw new Error(
+ 'Did not find exactly one match (found: ' +
+ all.length +
+ ') ' +
+ 'for componentType:' +
+ componentType,
+ );
+ }
+ return all[0];
+}
- act,
-};
+/**
+ * Pass a mocked component module to this method to augment it with
+ * useful methods that allow it to be used as a dummy React component.
+ * Instead of rendering as usual, the component will become a simple
+ *
containing any provided children.
+ *
+ * @param {object} module the mock function object exported from a
+ * module that defines the component to be mocked
+ * @param {?string} mockTagName optional dummy root tag name to return
+ * from render method (overrides
+ * module.mockTagName if provided)
+ * @return {object} the ReactTestUtils object (for chaining)
+ */
+function mockComponent(module, mockTagName) {
+ if (__DEV__) {
+ if (!hasWarnedAboutDeprecatedMockComponent) {
+ hasWarnedAboutDeprecatedMockComponent = true;
+ console.warn(
+ 'ReactTestUtils.mockComponent() is deprecated. ' +
+ 'Use shallow rendering or jest.mock() instead.\n\n' +
+ 'See https://fb.me/test-utils-mock-component for more information.',
+ );
+ }
+ }
+
+ mockTagName = mockTagName || module.mockTagName || 'div';
+
+ module.prototype.render.mockImplementation(function() {
+ return React.createElement(mockTagName, null, this.props.children);
+ });
+
+ return this;
+}
+
+function nativeTouchData(x, y) {
+ return {
+ touches: [{pageX: x, pageY: y}],
+ };
+}
+
+const Simulate = {};
+const SimulateNative = {};
/**
* Exports:
*
- * - `ReactTestUtils.Simulate.click(Element)`
- * - `ReactTestUtils.Simulate.mouseMove(Element)`
- * - `ReactTestUtils.Simulate.change(Element)`
+ * - `Simulate.click(Element)`
+ * - `Simulate.mouseMove(Element)`
+ * - `Simulate.change(Element)`
* - ... (All keys from event plugin `eventTypes` objects)
*/
function makeSimulator(eventType) {
@@ -407,7 +397,7 @@ function makeSimulator(eventType) {
'Note that TestUtils.Simulate will not work if you are using shallow rendering.',
);
invariant(
- !ReactTestUtils.isCompositeComponent(domNode),
+ !isCompositeComponent(domNode),
'TestUtils.Simulate expected a DOM node as the first argument but received ' +
'a component instance. Pass the DOM node you wish to simulate the event on instead.',
);
@@ -450,15 +440,13 @@ function makeSimulator(eventType) {
}
function buildSimulators() {
- ReactTestUtils.Simulate = {};
-
let eventType;
for (eventType in eventNameDispatchConfigs) {
/**
* @param {!Element|ReactDOMComponent} domComponentOrNode
* @param {?object} eventData Fake event data to use in SyntheticEvent.
*/
- ReactTestUtils.Simulate[eventType] = makeSimulator(eventType);
+ Simulate[eventType] = makeSimulator(eventType);
}
}
@@ -467,16 +455,16 @@ buildSimulators();
/**
* Exports:
*
- * - `ReactTestUtils.SimulateNative.click(Element/ReactDOMComponent)`
- * - `ReactTestUtils.SimulateNative.mouseMove(Element/ReactDOMComponent)`
- * - `ReactTestUtils.SimulateNative.mouseIn/ReactDOMComponent)`
- * - `ReactTestUtils.SimulateNative.mouseOut(Element/ReactDOMComponent)`
+ * - `SimulateNative.click(Element/ReactDOMComponent)`
+ * - `SimulateNative.mouseMove(Element/ReactDOMComponent)`
+ * - `SimulateNative.mouseIn/ReactDOMComponent)`
+ * - `SimulateNative.mouseOut(Element/ReactDOMComponent)`
* - ... (All keys from `BrowserEventConstants.topLevelTypes`)
*
* Note: Top level event types are a subset of the entire set of handler types
* (which include a broader set of "synthetic" events). For example, onDragDone
* is a synthetic event. Except when testing an event plugin or React's event
- * handling code specifically, you probably want to use ReactTestUtils.Simulate
+ * handling code specifically, you probably want to use Simulate
* to dispatch synthetic events.
*/
@@ -484,7 +472,7 @@ function makeNativeSimulator(eventType, topLevelType) {
return function(domComponentOrNode, nativeEventData) {
const fakeNativeEvent = new Event(eventType);
Object.assign(fakeNativeEvent, nativeEventData);
- if (ReactTestUtils.isDOMComponent(domComponentOrNode)) {
+ if (isDOMComponent(domComponentOrNode)) {
simulateNativeEventOnDOMComponent(
topLevelType,
domComponentOrNode,
@@ -576,10 +564,27 @@ function makeNativeSimulator(eventType, topLevelType) {
* @param {!Element|ReactDOMComponent} domComponentOrNode
* @param {?Event} nativeEventData Fake native event to use in SyntheticEvent.
*/
- ReactTestUtils.SimulateNative[eventType] = makeNativeSimulator(
- eventType,
- topLevelType,
- );
+ SimulateNative[eventType] = makeNativeSimulator(eventType, topLevelType);
});
-export default ReactTestUtils;
+export {
+ renderIntoDocument,
+ isElement,
+ isElementOfType,
+ isDOMComponent,
+ isDOMComponentElement,
+ isCompositeComponent,
+ isCompositeComponentWithType,
+ findAllInRenderedTree,
+ scryRenderedDOMComponentsWithClass,
+ findRenderedDOMComponentWithClass,
+ scryRenderedDOMComponentsWithTag,
+ findRenderedDOMComponentWithTag,
+ scryRenderedComponentsWithType,
+ findRenderedComponentWithType,
+ mockComponent,
+ nativeTouchData,
+ Simulate,
+ SimulateNative,
+ act,
+};
diff --git a/packages/react-dom/test-utils.js b/packages/react-dom/test-utils.js
index 1d4f69189e026..3eaa6b7b8c5d1 100644
--- a/packages/react-dom/test-utils.js
+++ b/packages/react-dom/test-utils.js
@@ -7,10 +7,4 @@
* @flow
*/
-'use strict';
-
-const ReactTestUtils = require('./src/test-utils/ReactTestUtils');
-
-// TODO: decide on the top-level export form.
-// This is hacky but makes it work with both Rollup and Jest.
-module.exports = ReactTestUtils.default || ReactTestUtils;
+export * from './src/test-utils/ReactTestUtils';
diff --git a/packages/react-dom/unstable-fizz.browser.js b/packages/react-dom/unstable-fizz.browser.js
index 4fb175ec6825e..322d4e364e1ae 100644
--- a/packages/react-dom/unstable-fizz.browser.js
+++ b/packages/react-dom/unstable-fizz.browser.js
@@ -7,10 +7,4 @@
* @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;
+export * from './src/server/ReactDOMFizzServerBrowser';
diff --git a/packages/react-dom/unstable-fizz.js b/packages/react-dom/unstable-fizz.js
index 81d1ccee698d1..835fb25dca4a3 100644
--- a/packages/react-dom/unstable-fizz.js
+++ b/packages/react-dom/unstable-fizz.js
@@ -7,6 +7,4 @@
* @flow
*/
-'use strict';
-
-module.exports = require('./unstable-fizz.node');
+export * from './unstable-fizz.node';
diff --git a/packages/react-dom/unstable-fizz.node.js b/packages/react-dom/unstable-fizz.node.js
index ef943c74eccf5..ae7462ed70713 100644
--- a/packages/react-dom/unstable-fizz.node.js
+++ b/packages/react-dom/unstable-fizz.node.js
@@ -7,10 +7,4 @@
* @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;
+export * from './src/server/ReactDOMFizzServerNode';
diff --git a/packages/react-dom/unstable-native-dependencies.js b/packages/react-dom/unstable-native-dependencies.js
index d44d492b8f198..ec502fb890690 100644
--- a/packages/react-dom/unstable-native-dependencies.js
+++ b/packages/react-dom/unstable-native-dependencies.js
@@ -7,6 +7,4 @@
* @flow
*/
-'use strict';
-
-module.exports = require('./src/unstable-native-dependencies/ReactDOMUnstableNativeDependencies');
+export * from './src/unstable-native-dependencies/ReactDOMUnstableNativeDependencies';
diff --git a/packages/react-server/src/ReactDOMServerFormatConfig.js b/packages/react-server/src/ReactDOMServerFormatConfig.js
index ece3e63890582..fa94102a98c9a 100644
--- a/packages/react-server/src/ReactDOMServerFormatConfig.js
+++ b/packages/react-server/src/ReactDOMServerFormatConfig.js
@@ -9,7 +9,7 @@
import {convertStringToBuffer} from 'react-server/src/ReactServerHostConfig';
-import ReactDOMServer from 'react-dom/server';
+import {renderToStaticMarkup} from 'react-dom/server';
export function formatChunkAsString(type: string, props: Object): string {
let str = '<' + type + '>';
@@ -31,5 +31,5 @@ export function renderHostChildrenToString(
// so we can't actually reference the renderer here. Instead, we
// should replace this method with a reference to Fizz which
// then uses this file to implement the server renderer.
- return ReactDOMServer.renderToStaticMarkup(children);
+ return renderToStaticMarkup(children);
}
diff --git a/packages/react-test-renderer/index.js b/packages/react-test-renderer/index.js
index 8d1c90e8855ac..61da6c01c1d5e 100644
--- a/packages/react-test-renderer/index.js
+++ b/packages/react-test-renderer/index.js
@@ -7,10 +7,4 @@
* @flow
*/
-'use strict';
-
-const ReactTestRenderer = require('./src/ReactTestRenderer');
-
-// TODO: decide on the top-level export form.
-// This is hacky but makes it work with both Rollup and Jest.
-module.exports = ReactTestRenderer.default || ReactTestRenderer;
+export * from './src/ReactTestRenderer';
diff --git a/packages/react-test-renderer/shallow.js b/packages/react-test-renderer/shallow.js
index 05df5d498fd91..fa548b35732db 100644
--- a/packages/react-test-renderer/shallow.js
+++ b/packages/react-test-renderer/shallow.js
@@ -7,10 +7,4 @@
* @flow
*/
-'use strict';
-
-const ReactShallowRenderer = require('./src/ReactShallowRenderer');
-
-// TODO: decide on the top-level export form.
-// This is hacky but makes it work with both Rollup and Jest.
-module.exports = ReactShallowRenderer.default || ReactShallowRenderer;
+export {default} from './src/ReactShallowRenderer';
diff --git a/packages/react-test-renderer/src/ReactShallowRenderer.js b/packages/react-test-renderer/src/ReactShallowRenderer.js
index abdd493704888..20751094fd28a 100644
--- a/packages/react-test-renderer/src/ReactShallowRenderer.js
+++ b/packages/react-test-renderer/src/ReactShallowRenderer.js
@@ -856,4 +856,8 @@ function getMaskedContext(contextTypes, unmaskedContext) {
return context;
}
+// This should probably be a default export and a named export.
+// However, this not how any of other APIs are designed so doesn't line up
+// with our build configs and makes it hard to properly support ES modules
+// and CommonJS.
export default ReactShallowRenderer;
diff --git a/packages/react-test-renderer/src/ReactTestRenderer.js b/packages/react-test-renderer/src/ReactTestRenderer.js
index 0bd57d4702645..18a69c4202111 100644
--- a/packages/react-test-renderer/src/ReactTestRenderer.js
+++ b/packages/react-test-renderer/src/ReactTestRenderer.js
@@ -433,138 +433,129 @@ function propsMatch(props: Object, filter: Object): boolean {
return true;
}
-const ReactTestRendererFiber = {
- _Scheduler: Scheduler,
-
- create(element: React$Element
, options: TestRendererOptions) {
- let createNodeMock = defaultTestOptions.createNodeMock;
- let isConcurrent = false;
- if (typeof options === 'object' && options !== null) {
- if (typeof options.createNodeMock === 'function') {
- createNodeMock = options.createNodeMock;
+function create(element: React$Element, options: TestRendererOptions) {
+ let createNodeMock = defaultTestOptions.createNodeMock;
+ let isConcurrent = false;
+ if (typeof options === 'object' && options !== null) {
+ if (typeof options.createNodeMock === 'function') {
+ createNodeMock = options.createNodeMock;
+ }
+ if (options.unstable_isConcurrent === true) {
+ isConcurrent = true;
+ }
+ }
+ let container = {
+ children: [],
+ createNodeMock,
+ tag: 'CONTAINER',
+ };
+ let root: FiberRoot | null = createContainer(
+ container,
+ isConcurrent ? ConcurrentRoot : LegacyRoot,
+ false,
+ null,
+ );
+ invariant(root != null, 'something went wrong');
+ updateContainer(element, root, null, null);
+
+ const entry = {
+ _Scheduler: Scheduler,
+
+ root: undefined, // makes flow happy
+ // we define a 'getter' for 'root' below using 'Object.defineProperty'
+ toJSON(): Array | ReactTestRendererNode | null {
+ if (root == null || root.current == null || container == null) {
+ return null;
}
- if (options.unstable_isConcurrent === true) {
- isConcurrent = true;
+ if (container.children.length === 0) {
+ return null;
}
- }
- let container = {
- children: [],
- createNodeMock,
- tag: 'CONTAINER',
- };
- let root: FiberRoot | null = createContainer(
- container,
- isConcurrent ? ConcurrentRoot : LegacyRoot,
- false,
- null,
- );
- invariant(root != null, 'something went wrong');
- updateContainer(element, root, null, null);
-
- const entry = {
- _Scheduler: Scheduler,
-
- root: undefined, // makes flow happy
- // we define a 'getter' for 'root' below using 'Object.defineProperty'
- toJSON(): Array | ReactTestRendererNode | null {
- if (root == null || root.current == null || container == null) {
- return null;
- }
- if (container.children.length === 0) {
- return null;
- }
- if (container.children.length === 1) {
- return toJSON(container.children[0]);
- }
- if (
- container.children.length === 2 &&
- container.children[0].isHidden === true &&
- container.children[1].isHidden === false
- ) {
- // Omit timed out children from output entirely, including the fact that we
- // temporarily wrap fallback and timed out children in an array.
- return toJSON(container.children[1]);
- }
- let renderedChildren = null;
- if (container.children && container.children.length) {
- for (let i = 0; i < container.children.length; i++) {
- const renderedChild = toJSON(container.children[i]);
- if (renderedChild !== null) {
- if (renderedChildren === null) {
- renderedChildren = [renderedChild];
- } else {
- renderedChildren.push(renderedChild);
- }
+ if (container.children.length === 1) {
+ return toJSON(container.children[0]);
+ }
+ if (
+ container.children.length === 2 &&
+ container.children[0].isHidden === true &&
+ container.children[1].isHidden === false
+ ) {
+ // Omit timed out children from output entirely, including the fact that we
+ // temporarily wrap fallback and timed out children in an array.
+ return toJSON(container.children[1]);
+ }
+ let renderedChildren = null;
+ if (container.children && container.children.length) {
+ for (let i = 0; i < container.children.length; i++) {
+ const renderedChild = toJSON(container.children[i]);
+ if (renderedChild !== null) {
+ if (renderedChildren === null) {
+ renderedChildren = [renderedChild];
+ } else {
+ renderedChildren.push(renderedChild);
}
}
}
- return renderedChildren;
- },
- toTree() {
- if (root == null || root.current == null) {
- return null;
- }
- return toTree(root.current);
- },
- update(newElement: React$Element) {
- if (root == null || root.current == null) {
- return;
- }
- updateContainer(newElement, root, null, null);
- },
- unmount() {
- if (root == null || root.current == null) {
- return;
+ }
+ return renderedChildren;
+ },
+ toTree() {
+ if (root == null || root.current == null) {
+ return null;
+ }
+ return toTree(root.current);
+ },
+ update(newElement: React$Element) {
+ if (root == null || root.current == null) {
+ return;
+ }
+ updateContainer(newElement, root, null, null);
+ },
+ unmount() {
+ if (root == null || root.current == null) {
+ return;
+ }
+ updateContainer(null, root, null, null);
+ container = null;
+ root = null;
+ },
+ getInstance() {
+ if (root == null || root.current == null) {
+ return null;
+ }
+ return getPublicRootInstance(root);
+ },
+
+ unstable_flushSync(fn: () => T): T {
+ return flushSync(fn);
+ },
+ };
+
+ Object.defineProperty(
+ entry,
+ 'root',
+ ({
+ configurable: true,
+ enumerable: true,
+ get: function() {
+ if (root === null) {
+ throw new Error("Can't access .root on unmounted test renderer");
}
- updateContainer(null, root, null, null);
- container = null;
- root = null;
- },
- getInstance() {
- if (root == null || root.current == null) {
- return null;
+ const children = getChildren(root.current);
+ if (children.length === 0) {
+ throw new Error("Can't access .root on unmounted test renderer");
+ } else if (children.length === 1) {
+ // Normally, we skip the root and just give you the child.
+ return children[0];
+ } else {
+ // However, we give you the root if there's more than one root child.
+ // We could make this the behavior for all cases but it would be a breaking change.
+ return wrapFiber(root.current);
}
- return getPublicRootInstance(root);
- },
-
- unstable_flushSync(fn: () => T): T {
- return flushSync(fn);
},
- };
-
- Object.defineProperty(
- entry,
- 'root',
- ({
- configurable: true,
- enumerable: true,
- get: function() {
- if (root === null) {
- throw new Error("Can't access .root on unmounted test renderer");
- }
- const children = getChildren(root.current);
- if (children.length === 0) {
- throw new Error("Can't access .root on unmounted test renderer");
- } else if (children.length === 1) {
- // Normally, we skip the root and just give you the child.
- return children[0];
- } else {
- // However, we give you the root if there's more than one root child.
- // We could make this the behavior for all cases but it would be a breaking change.
- return wrapFiber(root.current);
- }
- },
- }: Object),
- );
-
- return entry;
- },
+ }: Object),
+ );
- /* eslint-disable-next-line camelcase */
- unstable_batchedUpdates: batchedUpdates,
-
- act,
-};
+ return entry;
+}
const fiberToWrapper = new WeakMap();
function wrapFiber(fiber: Fiber): ReactTestInstance {
@@ -589,4 +580,10 @@ injectIntoDevTools({
rendererPackageName: 'react-test-renderer',
});
-export default ReactTestRendererFiber;
+export {
+ Scheduler as _Scheduler,
+ create,
+ /* eslint-disable-next-line camelcase */
+ batchedUpdates as unstable_batchedUpdates,
+ act,
+};
diff --git a/packages/react-test-renderer/src/__tests__/ReactShallowRenderer-test.js b/packages/react-test-renderer/src/__tests__/ReactShallowRenderer-test.js
index 68c8299cfe963..13aa7682aff2c 100644
--- a/packages/react-test-renderer/src/__tests__/ReactShallowRenderer-test.js
+++ b/packages/react-test-renderer/src/__tests__/ReactShallowRenderer-test.js
@@ -10,19 +10,13 @@
'use strict';
-let createRenderer;
-let PropTypes;
-let React;
+import * as PropTypes from 'prop-types';
+import * as React from 'react';
+import ReactShallowRenderer from 'react-test-renderer/shallow';
-describe('ReactShallowRenderer', () => {
- beforeEach(() => {
- jest.resetModules();
-
- createRenderer = require('react-test-renderer/shallow').createRenderer;
- PropTypes = require('prop-types');
- React = require('react');
- });
+const createRenderer = ReactShallowRenderer.createRenderer;
+describe('ReactShallowRenderer', () => {
it('should call all of the legacy lifecycle hooks', () => {
const logs = [];
const logger = message => () => logs.push(message) || true;
diff --git a/packages/react-test-renderer/src/__tests__/ReactShallowRendererHooks-test.js b/packages/react-test-renderer/src/__tests__/ReactShallowRendererHooks-test.js
index 6b8a962ad5b14..87bbdade2507c 100644
--- a/packages/react-test-renderer/src/__tests__/ReactShallowRendererHooks-test.js
+++ b/packages/react-test-renderer/src/__tests__/ReactShallowRendererHooks-test.js
@@ -10,16 +10,12 @@
'use strict';
-let createRenderer;
-let React;
+import * as React from 'react';
+import ReactShallowRenderer from 'react-test-renderer/shallow';
-describe('ReactShallowRenderer with hooks', () => {
- beforeEach(() => {
- jest.resetModules();
- createRenderer = require('react-test-renderer/shallow').createRenderer;
- React = require('react');
- });
+const createRenderer = ReactShallowRenderer.createRenderer;
+describe('ReactShallowRenderer with hooks', () => {
it('should work with useState', () => {
function SomeComponent({defaultName}) {
const [name] = React.useState(defaultName);
diff --git a/packages/react-test-renderer/src/__tests__/ReactShallowRendererMemo-test.js b/packages/react-test-renderer/src/__tests__/ReactShallowRendererMemo-test.js
index 9ed3bc681593b..5da98d8a7420a 100644
--- a/packages/react-test-renderer/src/__tests__/ReactShallowRendererMemo-test.js
+++ b/packages/react-test-renderer/src/__tests__/ReactShallowRendererMemo-test.js
@@ -10,19 +10,13 @@
'use strict';
-let createRenderer;
-let PropTypes;
-let React;
+import * as PropTypes from 'prop-types';
+import * as React from 'react';
+import ReactShallowRenderer from 'react-test-renderer/shallow';
-describe('ReactShallowRendererMemo', () => {
- beforeEach(() => {
- jest.resetModules();
-
- createRenderer = require('react-test-renderer/shallow').createRenderer;
- PropTypes = require('prop-types');
- React = require('react');
- });
+const createRenderer = ReactShallowRenderer.createRenderer;
+describe('ReactShallowRendererMemo', () => {
it('should call all of the legacy lifecycle hooks', () => {
const logs = [];
const logger = message => () => logs.push(message) || true;