From 604d3e96364175974fcb2d12fc7fa02b1c50d2e6 Mon Sep 17 00:00:00 2001 From: Matan Borenkraout Date: Sun, 5 Jul 2020 20:15:38 +0300 Subject: [PATCH] fix: React next fails on build (#726) (#732) * fix: Fix build on react@next * Working on ^16.9 and lower than 16.8 * Solution works in 16.8 also * Fixes from code review * Import only the function we need --- package.json | 3 ++- src/flush-microtasks.js | 32 +++++++++++++++++++++++++++++++- 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 802a2e34..ea03d463 100644 --- a/package.json +++ b/package.json @@ -44,7 +44,8 @@ "license": "MIT", "dependencies": { "@babel/runtime": "^7.10.3", - "@testing-library/dom": "^7.17.1" + "@testing-library/dom": "^7.17.1", + "semver": "^7.3.2" }, "devDependencies": { "@reach/router": "^1.3.3", diff --git a/src/flush-microtasks.js b/src/flush-microtasks.js index 2638da04..99b56ea5 100644 --- a/src/flush-microtasks.js +++ b/src/flush-microtasks.js @@ -1,3 +1,6 @@ +import React from 'react' +import satisfies from 'semver/functions/satisfies' + /* istanbul ignore file */ // the part of this file that we need tested is definitely being run // and the part that is not cannot easily have useful tests written @@ -15,8 +18,15 @@ function getIsUsingFakeTimers() { ) } +const globalObj = typeof window === 'undefined' ? global : window +let Scheduler = globalObj.Scheduler +const isModernScheduleCallbackSupported = satisfies(React.version, '>16.8.6', { + includePrerelease: true, +}) + 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. @@ -25,6 +35,8 @@ try { // assuming we're in node, let's try to get node's // version of setImmediate, bypassing fake timers if any. enqueueTask = nodeRequire.call(module, 'timers').setImmediate + // import React's scheduler so we'll be able to schedule our tasks later on. + Scheduler = nodeRequire.call(module, 'scheduler') } catch (_err) { // we're in a browser // we can't use regular timers because they may still be faked @@ -49,6 +61,20 @@ try { } } +function scheduleCallback(cb) { + const NormalPriority = Scheduler + ? Scheduler.NormalPriority || Scheduler.unstable_NormalPriority + : null + + const scheduleFn = Scheduler + ? Scheduler.scheduleCallback || Scheduler.unstable_scheduleCallback + : callback => callback() + + return isModernScheduleCallbackSupported + ? scheduleFn(NormalPriority, cb) + : scheduleFn(cb) +} + export default function flushMicroTasks() { return { then(resolve) { @@ -59,7 +85,11 @@ export default function flushMicroTasks() { jest.advanceTimersByTime(0) resolve() } else { - enqueueTask(resolve) + scheduleCallback(() => { + enqueueTask(() => { + resolve() + }) + }) } }, }