mirror of
https://github.com/hanzoai/react.git
synced 2026-09-24 17:02:27 +00:00
make testing builds for React/ReactDOM (#17915)
This PR introduces adds `react/testing` and `react-dom/testing`. - changes infra to generate these builds - exports act on ReactDOM in these testing builds - uses the new test builds in fixtures/dom In the next PR - - I'll use the new builds for all our own tests - I'll replace usages of TestUtils.act with ReactDOM.act.
This commit is contained in:
@@ -8,18 +8,23 @@
|
||||
*/
|
||||
|
||||
let React;
|
||||
let TestUtils;
|
||||
let ReactDOM;
|
||||
let TestRenderer;
|
||||
|
||||
global.__DEV__ = process.env.NODE_ENV !== 'production';
|
||||
|
||||
jest.mock('react-dom', () =>
|
||||
require.requireActual('react-dom/cjs/react-dom-testing.development.js')
|
||||
);
|
||||
// we'll replace the above with react/testing and react-dom/testing right before the next minor
|
||||
|
||||
expect.extend(require('../toWarnDev'));
|
||||
|
||||
describe('unmocked scheduler', () => {
|
||||
beforeEach(() => {
|
||||
jest.resetModules();
|
||||
React = require('react');
|
||||
TestUtils = require('react-dom/test-utils');
|
||||
ReactDOM = require('react-dom');
|
||||
TestRenderer = require('react-test-renderer');
|
||||
});
|
||||
|
||||
@@ -33,7 +38,7 @@ describe('unmocked scheduler', () => {
|
||||
}
|
||||
// in legacy mode, this tests whether an act only flushes its own effects
|
||||
TestRenderer.act(() => {
|
||||
TestUtils.act(() => {
|
||||
ReactDOM.act(() => {
|
||||
TestRenderer.create(<Effecty />);
|
||||
});
|
||||
expect(log).toEqual([]);
|
||||
@@ -42,7 +47,7 @@ describe('unmocked scheduler', () => {
|
||||
|
||||
log = [];
|
||||
// for doublechecking, we flip it inside out, and assert on the outermost
|
||||
TestUtils.act(() => {
|
||||
ReactDOM.act(() => {
|
||||
TestRenderer.act(() => {
|
||||
TestRenderer.create(<Effecty />);
|
||||
});
|
||||
@@ -59,7 +64,7 @@ describe('mocked scheduler', () => {
|
||||
require.requireActual('scheduler/unstable_mock')
|
||||
);
|
||||
React = require('react');
|
||||
TestUtils = require('react-dom/test-utils');
|
||||
ReactDOM = require('react-dom');
|
||||
TestRenderer = require('react-test-renderer');
|
||||
});
|
||||
|
||||
@@ -77,7 +82,7 @@ describe('mocked scheduler', () => {
|
||||
}
|
||||
// with a mocked scheduler, this tests whether it flushes all work only on the outermost act
|
||||
TestRenderer.act(() => {
|
||||
TestUtils.act(() => {
|
||||
ReactDOM.act(() => {
|
||||
TestRenderer.create(<Effecty />);
|
||||
});
|
||||
expect(log).toEqual([]);
|
||||
@@ -86,7 +91,7 @@ describe('mocked scheduler', () => {
|
||||
|
||||
log = [];
|
||||
// for doublechecking, we flip it inside out, and assert on the outermost
|
||||
TestUtils.act(() => {
|
||||
ReactDOM.act(() => {
|
||||
TestRenderer.act(() => {
|
||||
TestRenderer.create(<Effecty />);
|
||||
});
|
||||
|
||||
@@ -12,13 +12,17 @@ let ReactDOM;
|
||||
let ReactART;
|
||||
let ARTSVGMode;
|
||||
let ARTCurrentMode;
|
||||
let TestUtils;
|
||||
let TestRenderer;
|
||||
let ARTTest;
|
||||
|
||||
global.__DEV__ = process.env.NODE_ENV !== 'production';
|
||||
global.__EXPERIMENTAL__ = process.env.RELEASE_CHANNEL === 'experimental';
|
||||
|
||||
jest.mock('react-dom', () =>
|
||||
require.requireActual('react-dom/cjs/react-dom-testing.development.js')
|
||||
);
|
||||
// we'll replace the above with react/testing and react-dom/testing right before the next minor
|
||||
|
||||
expect.extend(require('../toWarnDev'));
|
||||
|
||||
function App(props) {
|
||||
@@ -32,7 +36,6 @@ beforeEach(() => {
|
||||
ReactART = require('react-art');
|
||||
ARTSVGMode = require('art/modes/svg');
|
||||
ARTCurrentMode = require('art/modes/current');
|
||||
TestUtils = require('react-dom/test-utils');
|
||||
TestRenderer = require('react-test-renderer');
|
||||
|
||||
ARTCurrentMode.setCurrent(ARTSVGMode);
|
||||
@@ -70,8 +73,8 @@ beforeEach(() => {
|
||||
});
|
||||
|
||||
it("doesn't warn when you use the right act + renderer: dom", () => {
|
||||
TestUtils.act(() => {
|
||||
TestUtils.renderIntoDocument(<App />);
|
||||
ReactDOM.act(() => {
|
||||
ReactDOM.render(<App />, document.createElement('div'));
|
||||
});
|
||||
});
|
||||
|
||||
@@ -86,7 +89,7 @@ it('resets correctly across renderers', () => {
|
||||
React.useEffect(() => {}, []);
|
||||
return null;
|
||||
}
|
||||
TestUtils.act(() => {
|
||||
ReactDOM.act(() => {
|
||||
TestRenderer.act(() => {});
|
||||
expect(() => {
|
||||
TestRenderer.create(<Effecty />);
|
||||
@@ -99,7 +102,7 @@ it('resets correctly across renderers', () => {
|
||||
it('warns when using the wrong act version - test + dom: render', () => {
|
||||
expect(() => {
|
||||
TestRenderer.act(() => {
|
||||
TestUtils.renderIntoDocument(<App />);
|
||||
ReactDOM.render(<App />, document.createElement('div'));
|
||||
});
|
||||
}).toWarnDev(["It looks like you're using the wrong act()"], {
|
||||
withoutStack: true,
|
||||
@@ -113,7 +116,7 @@ it('warns when using the wrong act version - test + dom: updates', () => {
|
||||
setCtr = _setCtr;
|
||||
return ctr;
|
||||
}
|
||||
TestUtils.renderIntoDocument(<Counter />);
|
||||
ReactDOM.render(<Counter />, document.createElement('div'));
|
||||
expect(() => {
|
||||
TestRenderer.act(() => {
|
||||
setCtr(1);
|
||||
@@ -123,7 +126,7 @@ it('warns when using the wrong act version - test + dom: updates', () => {
|
||||
|
||||
it('warns when using the wrong act version - dom + test: .create()', () => {
|
||||
expect(() => {
|
||||
TestUtils.act(() => {
|
||||
ReactDOM.act(() => {
|
||||
TestRenderer.create(<App />);
|
||||
});
|
||||
}).toWarnDev(["It looks like you're using the wrong act()"], {
|
||||
@@ -134,7 +137,7 @@ it('warns when using the wrong act version - dom + test: .create()', () => {
|
||||
it('warns when using the wrong act version - dom + test: .update()', () => {
|
||||
const root = TestRenderer.create(<App key="one" />);
|
||||
expect(() => {
|
||||
TestUtils.act(() => {
|
||||
ReactDOM.act(() => {
|
||||
root.update(<App key="two" />);
|
||||
});
|
||||
}).toWarnDev(["It looks like you're using the wrong act()"], {
|
||||
@@ -151,15 +154,15 @@ it('warns when using the wrong act version - dom + test: updates', () => {
|
||||
}
|
||||
TestRenderer.create(<Counter />);
|
||||
expect(() => {
|
||||
TestUtils.act(() => {
|
||||
ReactDOM.act(() => {
|
||||
setCtr(1);
|
||||
});
|
||||
}).toWarnDev(["It looks like you're using the wrong act()"]);
|
||||
});
|
||||
|
||||
it('does not warn when nesting react-act inside react-dom', () => {
|
||||
TestUtils.act(() => {
|
||||
TestUtils.renderIntoDocument(<ARTTest />);
|
||||
ReactDOM.act(() => {
|
||||
ReactDOM.render(<ARTTest />, document.createElement('div'));
|
||||
});
|
||||
});
|
||||
|
||||
@@ -171,7 +174,7 @@ it('does not warn when nesting react-act inside react-test-renderer', () => {
|
||||
|
||||
it("doesn't warn if you use nested acts from different renderers", () => {
|
||||
TestRenderer.act(() => {
|
||||
TestUtils.act(() => {
|
||||
ReactDOM.act(() => {
|
||||
TestRenderer.create(<App />);
|
||||
});
|
||||
});
|
||||
|
||||
Vendored
+38
@@ -0,0 +1,38 @@
|
||||
'use strict';
|
||||
|
||||
function checkDCE() {
|
||||
/* global __REACT_DEVTOOLS_GLOBAL_HOOK__ */
|
||||
if (
|
||||
typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ === 'undefined' ||
|
||||
typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE !== 'function'
|
||||
) {
|
||||
return;
|
||||
}
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
// This branch is unreachable because this function is only called
|
||||
// in production, but the condition is true only in development.
|
||||
// Therefore if the branch is still here, dead code elimination wasn't
|
||||
// properly applied.
|
||||
// Don't change the message. React DevTools relies on it. Also make sure
|
||||
// this message doesn't occur elsewhere in this function, or it will cause
|
||||
// a false positive.
|
||||
throw new Error('^_^');
|
||||
}
|
||||
try {
|
||||
// Verify that the code above has been dead code eliminated (DCE'd).
|
||||
__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(checkDCE);
|
||||
} catch (err) {
|
||||
// DevTools shouldn't crash React, no matter what.
|
||||
// We should still report in case we break this code.
|
||||
console.error(err);
|
||||
}
|
||||
}
|
||||
|
||||
if (process.env.NODE_ENV === 'production') {
|
||||
// DCE check should happen before ReactDOM bundle executes so that
|
||||
// DevTools can report bad minification during injection.
|
||||
checkDCE();
|
||||
module.exports = require('./cjs/react-dom-testing.production.min.js');
|
||||
} else {
|
||||
module.exports = require('./cjs/react-dom-testing.development.js');
|
||||
}
|
||||
@@ -722,6 +722,7 @@ function runActTests(label, render, unmount, rerender) {
|
||||
|
||||
describe('suspense', () => {
|
||||
if (__DEV__ && __EXPERIMENTAL__) {
|
||||
// todo - remove __DEV__ check once we start using testing builds
|
||||
it('triggers fallbacks if available', async () => {
|
||||
let resolved = false;
|
||||
let resolve;
|
||||
|
||||
+6
@@ -35,6 +35,7 @@ import {
|
||||
attemptUserBlockingHydration,
|
||||
attemptContinuousHydration,
|
||||
attemptHydrationAtCurrentPriority,
|
||||
act,
|
||||
} from 'react-reconciler/inline.dom';
|
||||
import {createPortal as createPortalImpl} from 'shared/ReactPortal';
|
||||
import {canUseDOM} from 'shared/ExecutionEnvironment';
|
||||
@@ -58,6 +59,7 @@ import {
|
||||
disableUnstableCreatePortal,
|
||||
disableUnstableRenderSubtreeIntoContainer,
|
||||
warnUnstableRenderSubtreeIntoContainer,
|
||||
isTestEnvironment,
|
||||
} from 'shared/ReactFeatureFlags';
|
||||
|
||||
import {
|
||||
@@ -251,4 +253,8 @@ if (__DEV__) {
|
||||
}
|
||||
}
|
||||
|
||||
if (isTestEnvironment) {
|
||||
ReactDOM.act = act;
|
||||
}
|
||||
|
||||
export default ReactDOM;
|
||||
|
||||
Vendored
+16
@@ -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 ReactDOM = require('./src/client/ReactDOM');
|
||||
|
||||
// TODO: decide on the top-level export form.
|
||||
// This is hacky but makes it work with both Rollup and Jest.
|
||||
module.exports = ReactDOM.default || ReactDOM;
|
||||
+1
-197
@@ -14,7 +14,6 @@
|
||||
* environment.
|
||||
*/
|
||||
|
||||
import type {Thenable} from 'react-reconciler/src/ReactFiberWorkLoop';
|
||||
import type {Fiber} from 'react-reconciler/src/ReactFiber';
|
||||
import type {UpdateQueue} from 'react-reconciler/src/ReactUpdateQueue';
|
||||
import type {ReactNodeList} from 'shared/ReactTypes';
|
||||
@@ -23,8 +22,6 @@ import type {RootTag} from 'shared/ReactRootTags';
|
||||
import * as Scheduler from 'scheduler/unstable_mock';
|
||||
import {createPortal} from 'shared/ReactPortal';
|
||||
import {REACT_FRAGMENT_TYPE, REACT_ELEMENT_TYPE} from 'shared/ReactSymbols';
|
||||
import enqueueTask from 'shared/enqueueTask';
|
||||
import ReactSharedInternals from 'shared/ReactSharedInternals';
|
||||
import {ConcurrentRoot, BlockingRoot, LegacyRoot} from 'shared/ReactRootTags';
|
||||
|
||||
type Container = {
|
||||
@@ -60,8 +57,6 @@ type TextInstance = {|
|
||||
|};
|
||||
type HostContext = Object;
|
||||
|
||||
const {IsSomeRendererActing} = ReactSharedInternals;
|
||||
|
||||
const NO_CONTEXT = {};
|
||||
const UPPERCASE_CONTEXT = {};
|
||||
const UPDATE_SIGNAL = {};
|
||||
@@ -597,197 +592,6 @@ function createReactNoop(reconciler: Function, useMutation: boolean) {
|
||||
const roots = new Map();
|
||||
const DEFAULT_ROOT_ID = '<default>';
|
||||
|
||||
const {
|
||||
flushPassiveEffects,
|
||||
batchedUpdates,
|
||||
IsThisRendererActing,
|
||||
} = NoopRenderer;
|
||||
|
||||
// this act() implementation should be exactly the same in
|
||||
// ReactTestUtilsAct.js, ReactTestRendererAct.js, createReactNoop.js
|
||||
|
||||
const isSchedulerMocked =
|
||||
typeof Scheduler.unstable_flushAllWithoutAsserting === 'function';
|
||||
const flushWork =
|
||||
Scheduler.unstable_flushAllWithoutAsserting ||
|
||||
function() {
|
||||
let didFlushWork = false;
|
||||
while (flushPassiveEffects()) {
|
||||
didFlushWork = true;
|
||||
}
|
||||
|
||||
return didFlushWork;
|
||||
};
|
||||
|
||||
function flushWorkAndMicroTasks(onDone: (err: ?Error) => void) {
|
||||
try {
|
||||
flushWork();
|
||||
enqueueTask(() => {
|
||||
if (flushWork()) {
|
||||
flushWorkAndMicroTasks(onDone);
|
||||
} else {
|
||||
onDone();
|
||||
}
|
||||
});
|
||||
} catch (err) {
|
||||
onDone(err);
|
||||
}
|
||||
}
|
||||
|
||||
// we track the 'depth' of the act() calls with this counter,
|
||||
// so we can tell if any async act() calls try to run in parallel.
|
||||
|
||||
let actingUpdatesScopeDepth = 0;
|
||||
let didWarnAboutUsingActInProd = false;
|
||||
|
||||
function act(callback: () => Thenable) {
|
||||
if (!__DEV__) {
|
||||
if (didWarnAboutUsingActInProd === false) {
|
||||
didWarnAboutUsingActInProd = true;
|
||||
// eslint-disable-next-line react-internal/no-production-logging
|
||||
console.error(
|
||||
'act(...) is not supported in production builds of React, and might not behave as expected.',
|
||||
);
|
||||
}
|
||||
}
|
||||
let previousActingUpdatesScopeDepth = actingUpdatesScopeDepth;
|
||||
let previousIsSomeRendererActing;
|
||||
let previousIsThisRendererActing;
|
||||
actingUpdatesScopeDepth++;
|
||||
|
||||
previousIsSomeRendererActing = IsSomeRendererActing.current;
|
||||
previousIsThisRendererActing = IsThisRendererActing.current;
|
||||
IsSomeRendererActing.current = true;
|
||||
IsThisRendererActing.current = true;
|
||||
|
||||
function onDone() {
|
||||
actingUpdatesScopeDepth--;
|
||||
IsSomeRendererActing.current = previousIsSomeRendererActing;
|
||||
IsThisRendererActing.current = previousIsThisRendererActing;
|
||||
if (__DEV__) {
|
||||
if (actingUpdatesScopeDepth > previousActingUpdatesScopeDepth) {
|
||||
// if it's _less than_ previousActingUpdatesScopeDepth, then we can assume the 'other' one has warned
|
||||
console.error(
|
||||
'You seem to have overlapping act() calls, this is not supported. ' +
|
||||
'Be sure to await previous act() calls before making a new one. ',
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let result;
|
||||
try {
|
||||
result = batchedUpdates(callback);
|
||||
} catch (error) {
|
||||
// on sync errors, we still want to 'cleanup' and decrement actingUpdatesScopeDepth
|
||||
onDone();
|
||||
throw error;
|
||||
}
|
||||
|
||||
if (
|
||||
result !== null &&
|
||||
typeof result === 'object' &&
|
||||
typeof result.then === 'function'
|
||||
) {
|
||||
// setup a boolean that gets set to true only
|
||||
// once this act() call is await-ed
|
||||
let called = false;
|
||||
if (__DEV__) {
|
||||
if (typeof Promise !== 'undefined') {
|
||||
//eslint-disable-next-line no-undef
|
||||
Promise.resolve()
|
||||
.then(() => {})
|
||||
.then(() => {
|
||||
if (called === false) {
|
||||
console.error(
|
||||
'You called act(async () => ...) without await. ' +
|
||||
'This could lead to unexpected testing behaviour, interleaving multiple act ' +
|
||||
'calls and mixing their scopes. You should - await act(async () => ...);',
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// in the async case, the returned thenable runs the callback, flushes
|
||||
// effects and microtasks in a loop until flushPassiveEffects() === false,
|
||||
// and cleans up
|
||||
return {
|
||||
then(resolve: () => void, reject: (?Error) => void) {
|
||||
called = true;
|
||||
result.then(
|
||||
() => {
|
||||
if (
|
||||
actingUpdatesScopeDepth > 1 ||
|
||||
(isSchedulerMocked === true &&
|
||||
previousIsSomeRendererActing === true)
|
||||
) {
|
||||
onDone();
|
||||
resolve();
|
||||
return;
|
||||
}
|
||||
// we're about to exit the act() scope,
|
||||
// now's the time to flush tasks/effects
|
||||
flushWorkAndMicroTasks((err: ?Error) => {
|
||||
onDone();
|
||||
if (err) {
|
||||
reject(err);
|
||||
} else {
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
},
|
||||
err => {
|
||||
onDone();
|
||||
reject(err);
|
||||
},
|
||||
);
|
||||
},
|
||||
};
|
||||
} else {
|
||||
if (__DEV__) {
|
||||
if (result !== undefined) {
|
||||
console.error(
|
||||
'The callback passed to act(...) function ' +
|
||||
'must return undefined, or a Promise. You returned %s',
|
||||
result,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// flush effects until none remain, and cleanup
|
||||
try {
|
||||
if (
|
||||
actingUpdatesScopeDepth === 1 &&
|
||||
(isSchedulerMocked === false ||
|
||||
previousIsSomeRendererActing === false)
|
||||
) {
|
||||
// we're about to exit the act() scope,
|
||||
// now's the time to flush effects
|
||||
flushWork();
|
||||
}
|
||||
onDone();
|
||||
} catch (err) {
|
||||
onDone();
|
||||
throw err;
|
||||
}
|
||||
|
||||
// in the sync case, the returned thenable only warns *if* await-ed
|
||||
return {
|
||||
then(resolve: () => void) {
|
||||
if (__DEV__) {
|
||||
console.error(
|
||||
'Do not await the result of calling act(...) with sync logic, it is not a Promise.',
|
||||
);
|
||||
}
|
||||
resolve();
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// end act() implementation
|
||||
|
||||
function childToJSX(child, text) {
|
||||
if (text !== null) {
|
||||
return text;
|
||||
@@ -1106,7 +910,7 @@ function createReactNoop(reconciler: Function, useMutation: boolean) {
|
||||
|
||||
flushPassiveEffects: NoopRenderer.flushPassiveEffects,
|
||||
|
||||
act,
|
||||
act: NoopRenderer.act,
|
||||
|
||||
// Logs the current state of the tree.
|
||||
dumpTree(rootID: string = DEFAULT_ROOT_ID) {
|
||||
|
||||
@@ -87,6 +87,11 @@ import {
|
||||
findHostInstancesForRefresh,
|
||||
} from './ReactFiberHotReloading';
|
||||
|
||||
// used by isTestEnvironment builds
|
||||
import enqueueTask from 'shared/enqueueTask';
|
||||
import * as Scheduler from 'scheduler';
|
||||
// end isTestEnvironment imports
|
||||
|
||||
type OpaqueRoot = FiberRoot;
|
||||
|
||||
// 0 is PROD, 1 is DEV.
|
||||
@@ -535,3 +540,185 @@ export function injectIntoDevTools(devToolsConfig: DevToolsConfig): boolean {
|
||||
getCurrentFiber: __DEV__ ? () => ReactCurrentFiberCurrent : null,
|
||||
});
|
||||
}
|
||||
|
||||
const {IsSomeRendererActing} = ReactSharedInternals;
|
||||
const isSchedulerMocked =
|
||||
typeof Scheduler.unstable_flushAllWithoutAsserting === 'function';
|
||||
const flushWork =
|
||||
Scheduler.unstable_flushAllWithoutAsserting ||
|
||||
function() {
|
||||
let didFlushWork = false;
|
||||
while (flushPassiveEffects()) {
|
||||
didFlushWork = true;
|
||||
}
|
||||
|
||||
return didFlushWork;
|
||||
};
|
||||
|
||||
function flushWorkAndMicroTasks(onDone: (err: ?Error) => void) {
|
||||
try {
|
||||
flushWork();
|
||||
enqueueTask(() => {
|
||||
if (flushWork()) {
|
||||
flushWorkAndMicroTasks(onDone);
|
||||
} else {
|
||||
onDone();
|
||||
}
|
||||
});
|
||||
} catch (err) {
|
||||
onDone(err);
|
||||
}
|
||||
}
|
||||
|
||||
// we track the 'depth' of the act() calls with this counter,
|
||||
// so we can tell if any async act() calls try to run in parallel.
|
||||
|
||||
let actingUpdatesScopeDepth = 0;
|
||||
let didWarnAboutUsingActInProd = false;
|
||||
|
||||
// eslint-disable-next-line no-inner-declarations
|
||||
export function act(callback: () => Thenable) {
|
||||
if (!__DEV__) {
|
||||
if (didWarnAboutUsingActInProd === false) {
|
||||
didWarnAboutUsingActInProd = true;
|
||||
// eslint-disable-next-line react-internal/no-production-logging
|
||||
console.error(
|
||||
'act(...) is not supported in production builds of React, and might not behave as expected.',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
let previousActingUpdatesScopeDepth = actingUpdatesScopeDepth;
|
||||
let previousIsSomeRendererActing;
|
||||
let previousIsThisRendererActing;
|
||||
actingUpdatesScopeDepth++;
|
||||
|
||||
previousIsSomeRendererActing = IsSomeRendererActing.current;
|
||||
previousIsThisRendererActing = IsThisRendererActing.current;
|
||||
IsSomeRendererActing.current = true;
|
||||
IsThisRendererActing.current = true;
|
||||
|
||||
function onDone() {
|
||||
actingUpdatesScopeDepth--;
|
||||
IsSomeRendererActing.current = previousIsSomeRendererActing;
|
||||
IsThisRendererActing.current = previousIsThisRendererActing;
|
||||
if (__DEV__) {
|
||||
if (actingUpdatesScopeDepth > previousActingUpdatesScopeDepth) {
|
||||
// if it's _less than_ previousActingUpdatesScopeDepth, then we can assume the 'other' one has warned
|
||||
console.error(
|
||||
'You seem to have overlapping act() calls, this is not supported. ' +
|
||||
'Be sure to await previous act() calls before making a new one. ',
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let result;
|
||||
try {
|
||||
result = batchedUpdates(callback);
|
||||
} catch (error) {
|
||||
// on sync errors, we still want to 'cleanup' and decrement actingUpdatesScopeDepth
|
||||
onDone();
|
||||
throw error;
|
||||
}
|
||||
|
||||
if (
|
||||
result !== null &&
|
||||
typeof result === 'object' &&
|
||||
typeof result.then === 'function'
|
||||
) {
|
||||
// setup a boolean that gets set to true only
|
||||
// once this act() call is await-ed
|
||||
let called = false;
|
||||
if (__DEV__) {
|
||||
if (typeof Promise !== 'undefined') {
|
||||
//eslint-disable-next-line no-undef
|
||||
Promise.resolve()
|
||||
.then(() => {})
|
||||
.then(() => {
|
||||
if (called === false) {
|
||||
console.error(
|
||||
'You called act(async () => ...) without await. ' +
|
||||
'This could lead to unexpected testing behaviour, interleaving multiple act ' +
|
||||
'calls and mixing their scopes. You should - await act(async () => ...);',
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// in the async case, the returned thenable runs the callback, flushes
|
||||
// effects and microtasks in a loop until flushPassiveEffects() === false,
|
||||
// and cleans up
|
||||
return {
|
||||
then(resolve: () => void, reject: (?Error) => void) {
|
||||
called = true;
|
||||
result.then(
|
||||
() => {
|
||||
if (
|
||||
actingUpdatesScopeDepth > 1 ||
|
||||
(isSchedulerMocked === true &&
|
||||
previousIsSomeRendererActing === true)
|
||||
) {
|
||||
onDone();
|
||||
resolve();
|
||||
return;
|
||||
}
|
||||
// we're about to exit the act() scope,
|
||||
// now's the time to flush tasks/effects
|
||||
flushWorkAndMicroTasks((err: ?Error) => {
|
||||
onDone();
|
||||
if (err) {
|
||||
reject(err);
|
||||
} else {
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
},
|
||||
err => {
|
||||
onDone();
|
||||
reject(err);
|
||||
},
|
||||
);
|
||||
},
|
||||
};
|
||||
} else {
|
||||
if (__DEV__) {
|
||||
if (result !== undefined) {
|
||||
console.error(
|
||||
'The callback passed to act(...) function ' +
|
||||
'must return undefined, or a Promise. You returned %s',
|
||||
result,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// flush effects until none remain, and cleanup
|
||||
try {
|
||||
if (
|
||||
actingUpdatesScopeDepth === 1 &&
|
||||
(isSchedulerMocked === false || previousIsSomeRendererActing === false)
|
||||
) {
|
||||
// we're about to exit the act() scope,
|
||||
// now's the time to flush effects
|
||||
flushWork();
|
||||
}
|
||||
onDone();
|
||||
} catch (err) {
|
||||
onDone();
|
||||
throw err;
|
||||
}
|
||||
|
||||
// in the sync case, the returned thenable only warns *if* await-ed
|
||||
return {
|
||||
then(resolve: () => void) {
|
||||
if (__DEV__) {
|
||||
console.error(
|
||||
'Do not await the result of calling act(...) with sync logic, it is not a Promise.',
|
||||
);
|
||||
}
|
||||
resolve();
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -19,6 +19,7 @@ import {
|
||||
flushSync,
|
||||
injectIntoDevTools,
|
||||
batchedUpdates,
|
||||
act,
|
||||
} from 'react-reconciler/inline.test';
|
||||
import {findCurrentFiberUsingSlowPath} from 'react-reconciler/reflection';
|
||||
import {
|
||||
@@ -42,7 +43,6 @@ import {
|
||||
} from 'shared/ReactWorkTags';
|
||||
import invariant from 'shared/invariant';
|
||||
import ReactVersion from 'shared/ReactVersion';
|
||||
import act from './ReactTestRendererAct';
|
||||
|
||||
import {getPublicInstance} from './ReactTestHostConfig';
|
||||
import {ConcurrentRoot, LegacyRoot} from 'shared/ReactRootTags';
|
||||
|
||||
@@ -1,204 +0,0 @@
|
||||
/**
|
||||
* 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 {Thenable} from 'react-reconciler/src/ReactFiberWorkLoop';
|
||||
|
||||
import {
|
||||
batchedUpdates,
|
||||
flushPassiveEffects,
|
||||
IsThisRendererActing,
|
||||
} from 'react-reconciler/inline.test';
|
||||
import ReactSharedInternals from 'shared/ReactSharedInternals';
|
||||
import enqueueTask from 'shared/enqueueTask';
|
||||
import * as Scheduler from 'scheduler';
|
||||
|
||||
const {IsSomeRendererActing} = ReactSharedInternals;
|
||||
|
||||
// this implementation should be exactly the same in
|
||||
// ReactTestUtilsAct.js, ReactTestRendererAct.js, createReactNoop.js
|
||||
|
||||
const isSchedulerMocked =
|
||||
typeof Scheduler.unstable_flushAllWithoutAsserting === 'function';
|
||||
const flushWork =
|
||||
Scheduler.unstable_flushAllWithoutAsserting ||
|
||||
function() {
|
||||
let didFlushWork = false;
|
||||
while (flushPassiveEffects()) {
|
||||
didFlushWork = true;
|
||||
}
|
||||
|
||||
return didFlushWork;
|
||||
};
|
||||
|
||||
function flushWorkAndMicroTasks(onDone: (err: ?Error) => void) {
|
||||
try {
|
||||
flushWork();
|
||||
enqueueTask(() => {
|
||||
if (flushWork()) {
|
||||
flushWorkAndMicroTasks(onDone);
|
||||
} else {
|
||||
onDone();
|
||||
}
|
||||
});
|
||||
} catch (err) {
|
||||
onDone(err);
|
||||
}
|
||||
}
|
||||
|
||||
// we track the 'depth' of the act() calls with this counter,
|
||||
// so we can tell if any async act() calls try to run in parallel.
|
||||
|
||||
let actingUpdatesScopeDepth = 0;
|
||||
let didWarnAboutUsingActInProd = false;
|
||||
|
||||
function act(callback: () => Thenable) {
|
||||
if (!__DEV__) {
|
||||
if (didWarnAboutUsingActInProd === false) {
|
||||
didWarnAboutUsingActInProd = true;
|
||||
// eslint-disable-next-line react-internal/no-production-logging
|
||||
console.error(
|
||||
'act(...) is not supported in production builds of React, and might not behave as expected.',
|
||||
);
|
||||
}
|
||||
}
|
||||
let previousActingUpdatesScopeDepth = actingUpdatesScopeDepth;
|
||||
let previousIsSomeRendererActing;
|
||||
let previousIsThisRendererActing;
|
||||
actingUpdatesScopeDepth++;
|
||||
|
||||
previousIsSomeRendererActing = IsSomeRendererActing.current;
|
||||
previousIsThisRendererActing = IsThisRendererActing.current;
|
||||
IsSomeRendererActing.current = true;
|
||||
IsThisRendererActing.current = true;
|
||||
|
||||
function onDone() {
|
||||
actingUpdatesScopeDepth--;
|
||||
IsSomeRendererActing.current = previousIsSomeRendererActing;
|
||||
IsThisRendererActing.current = previousIsThisRendererActing;
|
||||
if (__DEV__) {
|
||||
if (actingUpdatesScopeDepth > previousActingUpdatesScopeDepth) {
|
||||
// if it's _less than_ previousActingUpdatesScopeDepth, then we can assume the 'other' one has warned
|
||||
console.error(
|
||||
'You seem to have overlapping act() calls, this is not supported. ' +
|
||||
'Be sure to await previous act() calls before making a new one. ',
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let result;
|
||||
try {
|
||||
result = batchedUpdates(callback);
|
||||
} catch (error) {
|
||||
// on sync errors, we still want to 'cleanup' and decrement actingUpdatesScopeDepth
|
||||
onDone();
|
||||
throw error;
|
||||
}
|
||||
|
||||
if (
|
||||
result !== null &&
|
||||
typeof result === 'object' &&
|
||||
typeof result.then === 'function'
|
||||
) {
|
||||
// setup a boolean that gets set to true only
|
||||
// once this act() call is await-ed
|
||||
let called = false;
|
||||
if (__DEV__) {
|
||||
if (typeof Promise !== 'undefined') {
|
||||
//eslint-disable-next-line no-undef
|
||||
Promise.resolve()
|
||||
.then(() => {})
|
||||
.then(() => {
|
||||
if (called === false) {
|
||||
console.error(
|
||||
'You called act(async () => ...) without await. ' +
|
||||
'This could lead to unexpected testing behaviour, interleaving multiple act ' +
|
||||
'calls and mixing their scopes. You should - await act(async () => ...);',
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// in the async case, the returned thenable runs the callback, flushes
|
||||
// effects and microtasks in a loop until flushPassiveEffects() === false,
|
||||
// and cleans up
|
||||
return {
|
||||
then(resolve: () => void, reject: (?Error) => void) {
|
||||
called = true;
|
||||
result.then(
|
||||
() => {
|
||||
if (
|
||||
actingUpdatesScopeDepth > 1 ||
|
||||
(isSchedulerMocked === true &&
|
||||
previousIsSomeRendererActing === true)
|
||||
) {
|
||||
onDone();
|
||||
resolve();
|
||||
return;
|
||||
}
|
||||
// we're about to exit the act() scope,
|
||||
// now's the time to flush tasks/effects
|
||||
flushWorkAndMicroTasks((err: ?Error) => {
|
||||
onDone();
|
||||
if (err) {
|
||||
reject(err);
|
||||
} else {
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
},
|
||||
err => {
|
||||
onDone();
|
||||
reject(err);
|
||||
},
|
||||
);
|
||||
},
|
||||
};
|
||||
} else {
|
||||
if (__DEV__) {
|
||||
if (result !== undefined) {
|
||||
console.error(
|
||||
'The callback passed to act(...) function ' +
|
||||
'must return undefined, or a Promise. You returned %s',
|
||||
result,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// flush effects until none remain, and cleanup
|
||||
try {
|
||||
if (
|
||||
actingUpdatesScopeDepth === 1 &&
|
||||
(isSchedulerMocked === false || previousIsSomeRendererActing === false)
|
||||
) {
|
||||
// we're about to exit the act() scope,
|
||||
// now's the time to flush effects
|
||||
flushWork();
|
||||
}
|
||||
onDone();
|
||||
} catch (err) {
|
||||
onDone();
|
||||
throw err;
|
||||
}
|
||||
|
||||
// in the sync case, the returned thenable only warns *if* await-ed
|
||||
return {
|
||||
then(resolve: () => void) {
|
||||
if (__DEV__) {
|
||||
console.error(
|
||||
'Do not await the result of calling act(...) with sync logic, it is not a Promise.',
|
||||
);
|
||||
}
|
||||
resolve();
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export default act;
|
||||
@@ -0,0 +1,7 @@
|
||||
'use strict';
|
||||
|
||||
if (process.env.NODE_ENV === 'production') {
|
||||
module.exports = require('./cjs/react-testing.production.min.js');
|
||||
} else {
|
||||
module.exports = require('./cjs/react-testing.development.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 React = require('./src/React');
|
||||
|
||||
// TODO: decide on the top-level export form.
|
||||
// This is hacky but makes it work with both Rollup and Jest.
|
||||
module.exports = React.default || React;
|
||||
@@ -122,3 +122,5 @@ export const warnUnstableRenderSubtreeIntoContainer = false;
|
||||
|
||||
// Disables ReactDOM.unstable_createPortal
|
||||
export const disableUnstableCreatePortal = false;
|
||||
|
||||
export const isTestEnvironment = false;
|
||||
|
||||
@@ -8,37 +8,41 @@
|
||||
*/
|
||||
|
||||
let didWarnAboutMessageChannel = false;
|
||||
let enqueueTask;
|
||||
try {
|
||||
// read require off the module object to get around the bundlers.
|
||||
// we don't want them to detect a require and bundle a Node polyfill.
|
||||
let requireString = ('require' + Math.random()).slice(0, 7);
|
||||
let nodeRequire = module && module[requireString];
|
||||
// assuming we're in node, let's try to get node's
|
||||
// version of setImmediate, bypassing fake timers if any.
|
||||
enqueueTask = nodeRequire('timers').setImmediate;
|
||||
} catch (_err) {
|
||||
// we're in a browser
|
||||
// we can't use regular timers because they may still be faked
|
||||
// so we try MessageChannel+postMessage instead
|
||||
enqueueTask = function(callback: () => void) {
|
||||
if (__DEV__) {
|
||||
if (didWarnAboutMessageChannel === false) {
|
||||
didWarnAboutMessageChannel = true;
|
||||
if (typeof MessageChannel === 'undefined') {
|
||||
console.error(
|
||||
'This browser does not have a MessageChannel implementation, ' +
|
||||
'so enqueuing tasks via await act(async () => ...) will fail. ' +
|
||||
'Please file an issue at https://github.com/facebook/react/issues ' +
|
||||
'if you encounter this warning.',
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
const channel = new MessageChannel();
|
||||
channel.port1.onmessage = callback;
|
||||
channel.port2.postMessage(undefined);
|
||||
};
|
||||
}
|
||||
let enqueueTaskImpl = null;
|
||||
|
||||
export default enqueueTask;
|
||||
export default function enqueueTask(task: () => void) {
|
||||
if (enqueueTaskImpl === null) {
|
||||
try {
|
||||
// read require off the module object to get around the bundlers.
|
||||
// we don't want them to detect a require and bundle a Node polyfill.
|
||||
let requireString = ('require' + Math.random()).slice(0, 7);
|
||||
let nodeRequire = module && module[requireString];
|
||||
// assuming we're in node, let's try to get node's
|
||||
// version of setImmediate, bypassing fake timers if any.
|
||||
enqueueTaskImpl = nodeRequire('timers').setImmediate;
|
||||
} catch (_err) {
|
||||
// we're in a browser
|
||||
// we can't use regular timers because they may still be faked
|
||||
// so we try MessageChannel+postMessage instead
|
||||
enqueueTaskImpl = function(callback: () => void) {
|
||||
if (__DEV__) {
|
||||
if (didWarnAboutMessageChannel === false) {
|
||||
didWarnAboutMessageChannel = true;
|
||||
if (typeof MessageChannel === 'undefined') {
|
||||
console.error(
|
||||
'This browser does not have a MessageChannel implementation, ' +
|
||||
'so enqueuing tasks via await act(async () => ...) will fail. ' +
|
||||
'Please file an issue at https://github.com/facebook/react/issues ' +
|
||||
'if you encounter this warning.',
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
const channel = new MessageChannel();
|
||||
channel.port1.onmessage = callback;
|
||||
channel.port2.postMessage(undefined);
|
||||
};
|
||||
}
|
||||
}
|
||||
return enqueueTaskImpl(task);
|
||||
}
|
||||
|
||||
@@ -51,6 +51,7 @@ export const disableUnstableRenderSubtreeIntoContainer = false;
|
||||
export const warnUnstableRenderSubtreeIntoContainer = false;
|
||||
export const disableUnstableCreatePortal = false;
|
||||
export const deferPassiveEffectCleanupDuringUnmount = false;
|
||||
export const isTestEnvironment = false;
|
||||
|
||||
// Only used in www builds.
|
||||
export function addUserTimingListener() {
|
||||
|
||||
@@ -46,6 +46,7 @@ export const disableUnstableRenderSubtreeIntoContainer = false;
|
||||
export const warnUnstableRenderSubtreeIntoContainer = false;
|
||||
export const disableUnstableCreatePortal = false;
|
||||
export const deferPassiveEffectCleanupDuringUnmount = false;
|
||||
export const isTestEnvironment = false;
|
||||
|
||||
// Only used in www builds.
|
||||
export function addUserTimingListener() {
|
||||
|
||||
@@ -46,6 +46,7 @@ export const disableUnstableRenderSubtreeIntoContainer = false;
|
||||
export const warnUnstableRenderSubtreeIntoContainer = false;
|
||||
export const disableUnstableCreatePortal = false;
|
||||
export const deferPassiveEffectCleanupDuringUnmount = false;
|
||||
export const isTestEnvironment = false;
|
||||
|
||||
// Only used in www builds.
|
||||
export function addUserTimingListener() {
|
||||
|
||||
@@ -46,6 +46,7 @@ export const disableUnstableRenderSubtreeIntoContainer = false;
|
||||
export const warnUnstableRenderSubtreeIntoContainer = false;
|
||||
export const disableUnstableCreatePortal = false;
|
||||
export const deferPassiveEffectCleanupDuringUnmount = false;
|
||||
export const isTestEnvironment = true; // this should probably *never* change
|
||||
|
||||
// Only used in www builds.
|
||||
export function addUserTimingListener() {
|
||||
|
||||
@@ -44,6 +44,7 @@ export const disableUnstableRenderSubtreeIntoContainer = false;
|
||||
export const warnUnstableRenderSubtreeIntoContainer = false;
|
||||
export const disableUnstableCreatePortal = false;
|
||||
export const deferPassiveEffectCleanupDuringUnmount = false;
|
||||
export const isTestEnvironment = true; // this should probably *never* change
|
||||
|
||||
// Only used in www builds.
|
||||
export function addUserTimingListener() {
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
/**
|
||||
* 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';
|
||||
|
||||
import typeof * as FeatureFlagsType from 'shared/ReactFeatureFlags';
|
||||
import typeof * as PersistentFeatureFlagsType from './ReactFeatureFlags.persistent';
|
||||
|
||||
export const debugRenderPhaseSideEffectsForStrictMode = false;
|
||||
export const enableUserTimingAPI = __DEV__;
|
||||
export const warnAboutDeprecatedLifecycles = true;
|
||||
export const replayFailedUnitOfWorkWithInvokeGuardedCallback = false;
|
||||
export const enableProfilerTimer = __PROFILE__;
|
||||
export const enableSchedulerTracing = __PROFILE__;
|
||||
export const enableSuspenseServerRenderer = false;
|
||||
export const enableSelectiveHydration = false;
|
||||
export const enableChunksAPI = false;
|
||||
export const disableJavaScriptURLs = false;
|
||||
export const disableInputAttributeSyncing = false;
|
||||
export const exposeConcurrentModeAPIs = __EXPERIMENTAL__;
|
||||
export const warnAboutShorthandPropertyCollision = false;
|
||||
export const enableSchedulerDebugging = false;
|
||||
export const enableDeprecatedFlareAPI = false;
|
||||
export const enableFundamentalAPI = false;
|
||||
export const enableScopeAPI = false;
|
||||
export const enableJSXTransformAPI = false;
|
||||
export const warnAboutUnmockedScheduler = false;
|
||||
export const flushSuspenseFallbacksInTests = true;
|
||||
export const enableSuspenseCallback = false;
|
||||
export const warnAboutDefaultPropsOnFunctionComponents = false;
|
||||
export const warnAboutStringRefs = false;
|
||||
export const disableLegacyContext = false;
|
||||
export const disableSchedulerTimeoutBasedOnReactExpirationTime = false;
|
||||
export const enableTrainModelFix = true;
|
||||
export const enableTrustedTypesIntegration = false;
|
||||
export const enableNativeTargetAsInstance = false;
|
||||
export const disableCreateFactory = false;
|
||||
export const disableTextareaChildren = false;
|
||||
export const disableUnstableRenderSubtreeIntoContainer = false;
|
||||
export const warnUnstableRenderSubtreeIntoContainer = false;
|
||||
export const disableUnstableCreatePortal = false;
|
||||
export const deferPassiveEffectCleanupDuringUnmount = false;
|
||||
export const isTestEnvironment = true;
|
||||
|
||||
// Only used in www builds.
|
||||
export function addUserTimingListener() {
|
||||
invariant(false, 'Not implemented.');
|
||||
}
|
||||
|
||||
// Flow magic to verify the exports of this file match the original version.
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
type Check<_X, Y: _X, X: Y = _X> = null;
|
||||
// eslint-disable-next-line no-unused-expressions
|
||||
(null: Check<PersistentFeatureFlagsType, FeatureFlagsType>);
|
||||
@@ -102,6 +102,8 @@ export const warnUnstableRenderSubtreeIntoContainer = false;
|
||||
|
||||
export const disableUnstableCreatePortal = false;
|
||||
|
||||
export const isTestEnvironment = false;
|
||||
|
||||
// Flow magic to verify the exports of this file match the original version.
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
type Check<_X, Y: _X, X: Y = _X> = null;
|
||||
|
||||
@@ -104,6 +104,31 @@ const bundles = [
|
||||
externals: ['react', 'react-dom'],
|
||||
},
|
||||
|
||||
/******* React DOM - Testing *******/
|
||||
{
|
||||
moduleType: RENDERER,
|
||||
bundleTypes: [
|
||||
UMD_DEV,
|
||||
UMD_PROD,
|
||||
UMD_PROFILING,
|
||||
NODE_DEV,
|
||||
NODE_PROD,
|
||||
NODE_PROFILING,
|
||||
],
|
||||
entry: 'react-dom/testing',
|
||||
global: 'ReactDOM',
|
||||
externals: ['react'],
|
||||
},
|
||||
|
||||
/******* React DOM - www - Testing *******/
|
||||
{
|
||||
moduleType: RENDERER,
|
||||
bundleTypes: [FB_WWW_DEV, FB_WWW_PROD, FB_WWW_PROFILING],
|
||||
entry: 'react-dom/testing',
|
||||
global: 'ReactDOMTesting',
|
||||
externals: ['react'],
|
||||
},
|
||||
|
||||
/* React DOM internals required for react-native-web (e.g., to shim native events from react-dom) */
|
||||
{
|
||||
bundleTypes: [
|
||||
@@ -517,7 +542,7 @@ const bundles = [
|
||||
externals: [],
|
||||
},
|
||||
|
||||
/******* ESLint Plugin for Hooks (proposal) *******/
|
||||
/******* ESLint Plugin for Hooks *******/
|
||||
{
|
||||
// TODO: it's awkward to create a bundle for this but if we don't, the package
|
||||
// won't get copied. We also can't create just DEV bundle because it contains a
|
||||
|
||||
+21
-17
@@ -1,23 +1,23 @@
|
||||
'use strict';
|
||||
|
||||
const bundleTypes = require('./bundles').bundleTypes;
|
||||
const moduleTypes = require('./bundles').moduleTypes;
|
||||
const {bundleTypes, moduleTypes} = require('./bundles');
|
||||
const inlinedHostConfigs = require('../shared/inlinedHostConfigs');
|
||||
|
||||
const UMD_DEV = bundleTypes.UMD_DEV;
|
||||
const UMD_PROD = bundleTypes.UMD_PROD;
|
||||
const UMD_PROFILING = bundleTypes.UMD_PROFILING;
|
||||
const FB_WWW_DEV = bundleTypes.FB_WWW_DEV;
|
||||
const FB_WWW_PROD = bundleTypes.FB_WWW_PROD;
|
||||
const FB_WWW_PROFILING = bundleTypes.FB_WWW_PROFILING;
|
||||
const RN_OSS_DEV = bundleTypes.RN_OSS_DEV;
|
||||
const RN_OSS_PROD = bundleTypes.RN_OSS_PROD;
|
||||
const RN_OSS_PROFILING = bundleTypes.RN_OSS_PROFILING;
|
||||
const RN_FB_DEV = bundleTypes.RN_FB_DEV;
|
||||
const RN_FB_PROD = bundleTypes.RN_FB_PROD;
|
||||
const RN_FB_PROFILING = bundleTypes.RN_FB_PROFILING;
|
||||
const RENDERER = moduleTypes.RENDERER;
|
||||
const RECONCILER = moduleTypes.RECONCILER;
|
||||
const {
|
||||
UMD_DEV,
|
||||
UMD_PROD,
|
||||
UMD_PROFILING,
|
||||
FB_WWW_DEV,
|
||||
FB_WWW_PROD,
|
||||
FB_WWW_PROFILING,
|
||||
RN_OSS_DEV,
|
||||
RN_OSS_PROD,
|
||||
RN_OSS_PROFILING,
|
||||
RN_FB_DEV,
|
||||
RN_FB_PROD,
|
||||
RN_FB_PROFILING,
|
||||
} = bundleTypes;
|
||||
const {RENDERER, RECONCILER} = moduleTypes;
|
||||
|
||||
// If you need to replace a file with another file for a specific environment,
|
||||
// add it to this list with the logic for choosing the right replacement.
|
||||
@@ -46,7 +46,7 @@ const forks = Object.freeze({
|
||||
// Without this fork, importing `shared/ReactSharedInternals` inside
|
||||
// the `react` package itself would not work due to a cyclical dependency.
|
||||
'shared/ReactSharedInternals': (bundleType, entry, dependencies) => {
|
||||
if (entry === 'react') {
|
||||
if (entry === 'react' || entry === 'react/testing') {
|
||||
return 'react/src/ReactSharedInternals';
|
||||
}
|
||||
if (dependencies.indexOf('react') === -1) {
|
||||
@@ -106,6 +106,10 @@ const forks = Object.freeze({
|
||||
return 'shared/forks/ReactFeatureFlags.test-renderer.www.js';
|
||||
}
|
||||
return 'shared/forks/ReactFeatureFlags.test-renderer.js';
|
||||
case 'react-dom/testing':
|
||||
return 'shared/forks/ReactFeatureFlags.testing.js';
|
||||
case 'react/testing':
|
||||
return 'shared/forks/ReactFeatureFlags.testing.js';
|
||||
default:
|
||||
switch (bundleType) {
|
||||
case FB_WWW_DEV:
|
||||
|
||||
@@ -1,11 +1,7 @@
|
||||
'use strict';
|
||||
|
||||
const forks = require('./forks');
|
||||
const bundleTypes = require('./bundles').bundleTypes;
|
||||
|
||||
const UMD_DEV = bundleTypes.UMD_DEV;
|
||||
const UMD_PROD = bundleTypes.UMD_PROD;
|
||||
const UMD_PROFILING = bundleTypes.UMD_PROFILING;
|
||||
const {UMD_DEV, UMD_PROD, UMD_PROFILING} = require('./bundles').bundleTypes;
|
||||
|
||||
// For any external that is used in a DEV-only condition, explicitly
|
||||
// specify whether it has side effects during import or not. This lets
|
||||
|
||||
+19
-17
@@ -1,25 +1,27 @@
|
||||
'use strict';
|
||||
|
||||
const Bundles = require('./bundles');
|
||||
const {bundleTypes, moduleTypes} = require('./bundles');
|
||||
const reactVersion = require('../../package.json').version;
|
||||
|
||||
const UMD_DEV = Bundles.bundleTypes.UMD_DEV;
|
||||
const UMD_PROD = Bundles.bundleTypes.UMD_PROD;
|
||||
const UMD_PROFILING = Bundles.bundleTypes.UMD_PROFILING;
|
||||
const NODE_DEV = Bundles.bundleTypes.NODE_DEV;
|
||||
const NODE_PROD = Bundles.bundleTypes.NODE_PROD;
|
||||
const NODE_PROFILING = Bundles.bundleTypes.NODE_PROFILING;
|
||||
const FB_WWW_DEV = Bundles.bundleTypes.FB_WWW_DEV;
|
||||
const FB_WWW_PROD = Bundles.bundleTypes.FB_WWW_PROD;
|
||||
const FB_WWW_PROFILING = Bundles.bundleTypes.FB_WWW_PROFILING;
|
||||
const RN_OSS_DEV = Bundles.bundleTypes.RN_OSS_DEV;
|
||||
const RN_OSS_PROD = Bundles.bundleTypes.RN_OSS_PROD;
|
||||
const RN_OSS_PROFILING = Bundles.bundleTypes.RN_OSS_PROFILING;
|
||||
const RN_FB_DEV = Bundles.bundleTypes.RN_FB_DEV;
|
||||
const RN_FB_PROD = Bundles.bundleTypes.RN_FB_PROD;
|
||||
const RN_FB_PROFILING = Bundles.bundleTypes.RN_FB_PROFILING;
|
||||
const {
|
||||
UMD_DEV,
|
||||
UMD_PROD,
|
||||
UMD_PROFILING,
|
||||
NODE_DEV,
|
||||
NODE_PROD,
|
||||
NODE_PROFILING,
|
||||
FB_WWW_DEV,
|
||||
FB_WWW_PROD,
|
||||
FB_WWW_PROFILING,
|
||||
RN_OSS_DEV,
|
||||
RN_OSS_PROD,
|
||||
RN_OSS_PROFILING,
|
||||
RN_FB_DEV,
|
||||
RN_FB_PROD,
|
||||
RN_FB_PROFILING,
|
||||
} = bundleTypes;
|
||||
|
||||
const RECONCILER = Bundles.moduleTypes.RECONCILER;
|
||||
const {RECONCILER} = moduleTypes;
|
||||
|
||||
const license = ` * Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
|
||||
@@ -11,6 +11,7 @@ module.exports = [
|
||||
shortName: 'dom',
|
||||
entryPoints: [
|
||||
'react-dom',
|
||||
'react-dom/testing',
|
||||
'react-dom/unstable-fizz.node',
|
||||
'react-flight-dom-webpack/server.node',
|
||||
'react-flight-dom-webpack',
|
||||
|
||||
Reference in New Issue
Block a user