From 7686bfc2c9086567d721fe762fbe5bd8cbb836f7 Mon Sep 17 00:00:00 2001 From: Flarnie Marchan Date: Wed, 23 May 2018 14:00:06 -0700 Subject: [PATCH 1/6] Use local references to global things inside 'scheduler' **what is the change?:** See title **why make this change?:** We want to avoid initially calling one version of an API and then later accessing a polyfilled version. **test plan:** Run existing tests. --- packages/react-scheduler/src/ReactScheduler.js | 12 ++++++++++-- packages/shared/requestAnimationFrameForReact.js | 9 +++++++-- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/packages/react-scheduler/src/ReactScheduler.js b/packages/react-scheduler/src/ReactScheduler.js index a17fa51128798..1a79bb17a2aa4 100644 --- a/packages/react-scheduler/src/ReactScheduler.js +++ b/packages/react-scheduler/src/ReactScheduler.js @@ -44,17 +44,25 @@ export type CallbackIdType = CallbackConfigType; import requestAnimationFrameForReact from 'shared/requestAnimationFrameForReact'; import ExecutionEnvironment from 'fbjs/lib/ExecutionEnvironment'; +// We capture a local reference to any global, in case it gets polyfilled after +// this module is initially evaluated. +// We want to be using a consistent implementation. +const localDate = Date; +const localSetTimeout = setTimeout; +const localClearTimeout = clearTimeout; + const hasNativePerformanceNow = typeof performance === 'object' && typeof performance.now === 'function'; let now; if (hasNativePerformanceNow) { + const localPerformance = performance; now = function() { - return performance.now(); + return localPerformance.now(); }; } else { now = function() { - return Date.now(); + return localDate.now(); }; } diff --git a/packages/shared/requestAnimationFrameForReact.js b/packages/shared/requestAnimationFrameForReact.js index aa59610322deb..fd2d19c6b7b34 100644 --- a/packages/shared/requestAnimationFrameForReact.js +++ b/packages/shared/requestAnimationFrameForReact.js @@ -12,10 +12,15 @@ import ExecutionEnvironment from 'fbjs/lib/ExecutionEnvironment'; import warning from 'fbjs/lib/warning'; +// We capture a local reference to any global, in case it gets polyfilled after +// this module is initially evaluated. +// We want to be using a consistent implementation. +const localRequestAnimationFrame = requestAnimationFrame; + if (__DEV__) { if ( ExecutionEnvironment.canUseDOM && - typeof requestAnimationFrame !== 'function' + typeof localRequestAnimationFrame !== 'function' ) { warning( false, @@ -25,4 +30,4 @@ if (__DEV__) { } } -export default requestAnimationFrame; +export default localRequestAnimationFrame; From a96de36706d60bbe9bfda032a49c9071988f4f34 Mon Sep 17 00:00:00 2001 From: Flarnie Marchan Date: Wed, 23 May 2018 15:32:41 -0700 Subject: [PATCH 2/6] Shim ReactScheduler for www **what is the change?:** In 'www' we want to reference the separate build of ReactScheduler, which allows treating it as a separate module internally. **why make this change?:** We need to require the ReactScheduler before our rAF polyfill activates, in order to customize which custom behaviors we want. This is also a step towards being able to experiment with using it outside of React. **test plan:** Ran tests, ran the build, and ran `test-build`. --- packages/react-art/src/ReactARTHostConfig.js | 2 +- packages/react-dom/src/client/ReactDOMHostConfig.js | 2 +- packages/shared/ReactScheduler.js | 13 +++++++++++++ packages/shared/forks/ReactScheduler.www.js | 11 +++++++++++ scripts/rollup/forks.js | 11 +++++++++++ 5 files changed, 37 insertions(+), 2 deletions(-) create mode 100644 packages/shared/ReactScheduler.js create mode 100644 packages/shared/forks/ReactScheduler.www.js diff --git a/packages/react-art/src/ReactARTHostConfig.js b/packages/react-art/src/ReactARTHostConfig.js index eae266eb490f6..689303c086787 100644 --- a/packages/react-art/src/ReactARTHostConfig.js +++ b/packages/react-art/src/ReactARTHostConfig.js @@ -5,7 +5,7 @@ * LICENSE file in the root directory of this source tree. */ -import * as ReactScheduler from 'react-scheduler'; +import * as ReactScheduler from 'shared/ReactScheduler'; import Transform from 'art/core/transform'; import Mode from 'art/modes/current'; import invariant from 'fbjs/lib/invariant'; diff --git a/packages/react-dom/src/client/ReactDOMHostConfig.js b/packages/react-dom/src/client/ReactDOMHostConfig.js index 9d06c8f268025..c19a2c7425ce9 100644 --- a/packages/react-dom/src/client/ReactDOMHostConfig.js +++ b/packages/react-dom/src/client/ReactDOMHostConfig.js @@ -7,7 +7,7 @@ * @flow */ -import * as ReactScheduler from 'react-scheduler'; +import * as ReactScheduler from 'shared/ReactScheduler'; import * as ReactDOMComponentTree from './ReactDOMComponentTree'; import * as ReactDOMFiberComponent from './ReactDOMFiberComponent'; diff --git a/packages/shared/ReactScheduler.js b/packages/shared/ReactScheduler.js new file mode 100644 index 0000000000000..c8c75c5feb78a --- /dev/null +++ b/packages/shared/ReactScheduler.js @@ -0,0 +1,13 @@ +/** + * Copyright (c) 2013-present, Facebook, Inc. + * + * 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'; +import {now, scheduleWork, cancelScheduledWork} from 'react-scheduler/src/ReactScheduler'; + +export {now, scheduleWork, cancelScheduledWork}; diff --git a/packages/shared/forks/ReactScheduler.www.js b/packages/shared/forks/ReactScheduler.www.js new file mode 100644 index 0000000000000..4f76345a1c20f --- /dev/null +++ b/packages/shared/forks/ReactScheduler.www.js @@ -0,0 +1,11 @@ +/** + * Copyright (c) 2013-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +'use strict'; +const {now, scheduleWork, cancelScheduledWork} = require('customSchedule'); + +export {now, scheduleWork, cancelScheduledWork}; diff --git a/scripts/rollup/forks.js b/scripts/rollup/forks.js index b2d526946e87f..d6fcdb4d18d9b 100644 --- a/scripts/rollup/forks.js +++ b/scripts/rollup/forks.js @@ -79,6 +79,7 @@ const forks = Object.freeze({ }, // This logic is forked on www to use the 'acrossTransitions' version. + // This will be removed soon, see internal task T29442940 'shared/requestAnimationFrameForReact': (bundleType, entry) => { switch (bundleType) { case FB_WWW_DEV: @@ -89,6 +90,16 @@ const forks = Object.freeze({ } }, + 'shared/ReactScheduler': (bundleType, entry) => { + switch (bundleType) { + case FB_WWW_DEV: + case FB_WWW_PROD: + return 'shared/forks/ReactScheduler.www.js'; + default: + return null; + } + }, + // This logic is forked on www to blacklist warnings. 'shared/lowPriorityWarning': (bundleType, entry) => { switch (bundleType) { From 01c7385a3b9a703e6ebd4728cee0038dee854bdb Mon Sep 17 00:00:00 2001 From: Flarnie Marchan Date: Thu, 24 May 2018 08:09:13 -0700 Subject: [PATCH 3/6] Generate a bundle for fb-www **what is the change?:** See title **why make this change?:** Splitting out the 'schedule' module allows us to load it before polyfills kick in for rAF and other APIs. And long term we want to split this into a separate module anyway, this is a step towards that. **test plan:** I'll run the sync next week and verify that this all works. :) --- scripts/rollup/bundles.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/scripts/rollup/bundles.js b/scripts/rollup/bundles.js index 504055088586e..da2c1fc1ce7fb 100644 --- a/scripts/rollup/bundles.js +++ b/scripts/rollup/bundles.js @@ -371,7 +371,14 @@ const bundles = [ /******* React Scheduler (experimental) *******/ { label: 'react-scheduler', - bundleTypes: [NODE_DEV, NODE_PROD, UMD_DEV, UMD_PROD], + bundleTypes: [ + UMD_DEV, + UMD_PROD, + NODE_DEV, + NODE_PROD, + FB_WWW_DEV, + FB_WWW_PROD, + ], moduleType: ISOMORPHIC, entry: 'react-scheduler', global: 'ReactScheduler', From adef20612bfc88575ff8d7758989c74d636afc15 Mon Sep 17 00:00:00 2001 From: Flarnie Marchan Date: Sat, 26 May 2018 16:14:19 -0700 Subject: [PATCH 4/6] ran prettier --- packages/shared/ReactScheduler.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/shared/ReactScheduler.js b/packages/shared/ReactScheduler.js index c8c75c5feb78a..c65d28ecfaf7c 100644 --- a/packages/shared/ReactScheduler.js +++ b/packages/shared/ReactScheduler.js @@ -8,6 +8,10 @@ */ 'use strict'; -import {now, scheduleWork, cancelScheduledWork} from 'react-scheduler/src/ReactScheduler'; +import { + now, + scheduleWork, + cancelScheduledWork, +} from 'react-scheduler/src/ReactScheduler'; export {now, scheduleWork, cancelScheduledWork}; From 9c7b64d990703140080ce0145e3e8c735dd48a07 Mon Sep 17 00:00:00 2001 From: Flarnie Marchan Date: Sat, 26 May 2018 16:21:20 -0700 Subject: [PATCH 5/6] fix rebase issues --- packages/react-scheduler/src/ReactScheduler.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/react-scheduler/src/ReactScheduler.js b/packages/react-scheduler/src/ReactScheduler.js index 1a79bb17a2aa4..06c6338070c3f 100644 --- a/packages/react-scheduler/src/ReactScheduler.js +++ b/packages/react-scheduler/src/ReactScheduler.js @@ -86,7 +86,7 @@ if (!ExecutionEnvironment.canUseDOM) { next: null, prev: null, }; - const timeoutId = setTimeout(() => { + const timeoutId = localSetTimeout(() => { callback({ timeRemaining() { return Infinity; @@ -101,7 +101,7 @@ if (!ExecutionEnvironment.canUseDOM) { const callback = callbackId.scheduledCallback; const timeoutId = timeoutIds.get(callback); timeoutIds.delete(callbackId); - clearTimeout(timeoutId); + localClearTimeout(timeoutId); }; } else { let headOfPendingCallbacksLinkedList: CallbackConfigType | null = null; From 1320890e40fb9e56a04185262152db4c9b9adaab Mon Sep 17 00:00:00 2001 From: Flarnie Marchan Date: Tue, 29 May 2018 13:17:00 -0700 Subject: [PATCH 6/6] Change names of variables used for holding globals --- packages/react-scheduler/src/ReactScheduler.js | 18 +++++++++--------- .../shared/requestAnimationFrameForReact.js | 6 +++--- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/packages/react-scheduler/src/ReactScheduler.js b/packages/react-scheduler/src/ReactScheduler.js index 06c6338070c3f..f3dd11886b475 100644 --- a/packages/react-scheduler/src/ReactScheduler.js +++ b/packages/react-scheduler/src/ReactScheduler.js @@ -47,22 +47,22 @@ import ExecutionEnvironment from 'fbjs/lib/ExecutionEnvironment'; // We capture a local reference to any global, in case it gets polyfilled after // this module is initially evaluated. // We want to be using a consistent implementation. -const localDate = Date; -const localSetTimeout = setTimeout; -const localClearTimeout = clearTimeout; +const Date = global.Date; +const setTimeout = global.setTimeout; +const clearTimeout = global.clearTimeout; const hasNativePerformanceNow = typeof performance === 'object' && typeof performance.now === 'function'; let now; if (hasNativePerformanceNow) { - const localPerformance = performance; + const Performance = performance; now = function() { - return localPerformance.now(); + return Performance.now(); }; } else { now = function() { - return localDate.now(); + return Date.now(); }; } @@ -86,7 +86,7 @@ if (!ExecutionEnvironment.canUseDOM) { next: null, prev: null, }; - const timeoutId = localSetTimeout(() => { + const timeoutId = setTimeout(() => { callback({ timeRemaining() { return Infinity; @@ -101,7 +101,7 @@ if (!ExecutionEnvironment.canUseDOM) { const callback = callbackId.scheduledCallback; const timeoutId = timeoutIds.get(callback); timeoutIds.delete(callbackId); - localClearTimeout(timeoutId); + clearTimeout(timeoutId); }; } else { let headOfPendingCallbacksLinkedList: CallbackConfigType | null = null; @@ -232,7 +232,7 @@ if (!ExecutionEnvironment.canUseDOM) { }; // Assumes that we have addEventListener in this environment. Might need // something better for old IE. - window.addEventListener('message', idleTick, false); + global.addEventListener('message', idleTick, false); const animationTick = function(rafTime) { isAnimationFrameScheduled = false; diff --git a/packages/shared/requestAnimationFrameForReact.js b/packages/shared/requestAnimationFrameForReact.js index fd2d19c6b7b34..7d568862da1ab 100644 --- a/packages/shared/requestAnimationFrameForReact.js +++ b/packages/shared/requestAnimationFrameForReact.js @@ -15,12 +15,12 @@ import warning from 'fbjs/lib/warning'; // We capture a local reference to any global, in case it gets polyfilled after // this module is initially evaluated. // We want to be using a consistent implementation. -const localRequestAnimationFrame = requestAnimationFrame; +const requestAnimationFrame = global.requestAnimationFrame; if (__DEV__) { if ( ExecutionEnvironment.canUseDOM && - typeof localRequestAnimationFrame !== 'function' + typeof requestAnimationFrame !== 'function' ) { warning( false, @@ -30,4 +30,4 @@ if (__DEV__) { } } -export default localRequestAnimationFrame; +export default requestAnimationFrame;