Fiber ReactDOM shouldn't throw on import in Node environment if it's unused (#9389)
* Fixes #9102 by fake polyfilling rAF (and rIC) * Ensure we restore globals even if test fails + minor nits * Remove periods
Manas committed
Apr 27, 2017 at 17:43 UTC
182642b2ea9073cf036dc9da37d3dadb4b7482be
3 files changed
+78
-1
scripts/fiber/tests-passing.txt
+4
@@ -1642,6 +1642,10 @@ src/renderers/native/__tests__/ReactNativeMount-test.js
1642
* returns the correct instance and calls it in the callback
1643
* renders and reorders children
1644
1645
+src/renderers/shared/__tests__/ReactDOMFrameScheduling-test.js
1646
+* throws when requestAnimationFrame is not polyfilled in the browser
1647
+* can import findDOMNode in Node environment
1648
+
1649
src/renderers/shared/__tests__/ReactDebugTool-test.js
1650
* should add and remove hooks
1651
* warns once when an error is thrown in hook
src/renderers/shared/ReactDOMFrameScheduling.js
+19
-1
@@ -23,11 +23,29 @@
23
import type {Deadline} from 'ReactFiberReconciler';
24
25
var invariant = require('fbjs/lib/invariant');
26
+var ExecutionEnvironment = require('fbjs/lib/ExecutionEnvironment');
27
28
// TODO: There's no way to cancel these, because Fiber doesn't atm.
29
let rAF: (callback: (time: number) => void) => number;
30
let rIC: (callback: (deadline: Deadline) => void) => number;
30
-if (typeof requestAnimationFrame !== 'function') {
31
+
32
+if (!ExecutionEnvironment.canUseDOM) {
33
+ rAF = function(frameCallback: (time: number) => void): number {
34
+ setTimeout(frameCallback, 16);
35
+ return 0;
36
+ };
37
+
38
+ rIC = function(frameCallback: (deadline: Deadline) => void): number {
39
+ setTimeout(() => {
40
+ frameCallback({
41
+ timeRemaining() {
42
+ return Infinity;
43
+ },
44
+ });
45
+ });
46
+ return 0;
47
+ };
48
+} else if (typeof requestAnimationFrame !== 'function') {
49
invariant(
50
false,
51
'React depends on requestAnimationFrame. Make sure that you load a ' +
src/renderers/shared/__tests__/ReactDOMFrameScheduling-test.js
new
+55
@@ -0,0 +1,55 @@
1
+/**
2
+ * Copyright 2016-present, Facebook, Inc.
3
+ * All rights reserved.
4
+ *
5
+ * This source code is licensed under the BSD-style license found in the
6
+ * LICENSE file in the root directory of this source tree. An additional grant
7
+ * of patent rights can be found in the PATENTS file in the same directory.
8
+ *
9
+ * @emails react-core
10
+ */
11
+
12
+'use strict';
13
+
14
+const ReactDOMFeatureFlags = require('ReactDOMFeatureFlags');
15
+const describeFiber = ReactDOMFeatureFlags.useFiber ? describe : xdescribe;
16
+
17
+describeFiber('ReactDOMFrameScheduling', () => {
18
+ it('throws when requestAnimationFrame is not polyfilled in the browser', () => {
19
+ const previousRAF = global.requestAnimationFrame;
20
+ try {
21
+ global.requestAnimationFrame = undefined;
22
+ jest.resetModules();
23
+ expect(() => {
24
+ require('ReactDOM');
25
+ }).toThrow(
26
+ 'React depends on requestAnimationFrame. Make sure that you load a ' +
27
+ 'polyfill in older browsers.',
28
+ );
29
+ } finally {
30
+ global.requestAnimationFrame = previousRAF;
31
+ }
32
+ });
33
+
34
+ // We're just testing importing, not using it.
35
+ // It is important because even isomorphic components may import it.
36
+ it('can import findDOMNode in Node environment', () => {
37
+ const previousRAF = global.requestAnimationFrame;
38
+ const previousRIC = global.requestIdleCallback;
39
+ const prevWindow = global.window;
40
+ try {
41
+ global.requestAnimationFrame = undefined;
42
+ global.requestIdleCallback = undefined;
43
+ // Simulate the Node environment:
44
+ delete global.window;
45
+ jest.resetModules();
46
+ expect(() => {
47
+ require('ReactDOM');
48
+ }).not.toThrow();
49
+ } finally {
50
+ global.requestAnimationFrame = previousRAF;
51
+ global.requestIdleCallback = previousRIC;
52
+ global.window = prevWindow;
53
+ }
54
+ });
55
+});