Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[RFC] Mock react scheduler module #12684

Closed
wants to merge 6 commits into from

Conversation

flarnie
Copy link
Contributor

@flarnie flarnie commented Apr 25, 2018

This isn't 100% ready but leaving in case @gaearon has time to leave some tips on how this looks so far. I'm still working towards grokking our build system.

This is built on top of another PR, so ignore changes to ReactScheduler itself, which come from #12682

flarnie added 6 commits April 24, 2018 12:39
**what is the change?:**
We want to support calling ReactScheduler multiple times with different
callbacks, even if the initial callback hasn't been called yet.

There are two possible ways ReactScheduler can handle multiple
callbacks, and in one case we know that callbackA depends on callbackB
having been called already. For example;
callbackA -> updates SelectionState in a textArea
callbackB -> processes the deletion of the text currently selected.

We want to ensure that callbackA happens before callbackB. For now we
will flush callbackB as soon as callbackA is added.

In the next commit we'll split this into two methods, which support two
different behaviors here. We will support the usual behavior, which
would defer both callbackA and callbackB.

One issue with this is that we now create a new object to pass to the
callback for every use of the scheduler, while before we reused the same
object and mutated the 'didExpire' before passing it to each new
callback. With multiple callbacks, I think this leads to a risk of
mutating the object which is being used by multiple callbacks.

**why make this change?:**
We want to use this scheduling helper to coordinate between React and
non-React scripts.

**test plan:**
Added and ran a unit test.
**what is the change?:**
- Rewires React renderer tests to mock out the react-scheduler

**why make this change?:**
Once we properly treat this module as external, then we can mock it out
and also still run tests against the production bundle.

It makes sense to mock this module out, since it's depending heavily on
browser timing APIs which are mocked in the jest test environment
anyway. We will have separate unit tests covering 'react-scheduler'
itself.

**test plan:**
Run existing tests.

**issue:**
Internal task T28128480
**what is the change?:**
see title

**why make this change?:**
The ReactScheduler is a separate module from other React modules, and we
intend to mock it out in tests. For that mocking to work in tests which
run against the bundles, we have to treat ReactScheduler as external.

It also just makes sense.

**test plan:**
Run tests with bundles; yarn test-build
**what is the change?:**
NOTE: The last piece to fix is the 'brunch' build.
---
Unbreak the 'packaging' fixture to work with the new configuration of
'react-scheduler' as external.

**why make this change?:**
To allow continued use of this fixture, and also testing how things will
work with this new configuration.

**test plan:**
Ran the build for this fixture and manually inspected
@pull-bot
Copy link

ReactDOM: size: -1.0%, gzip: -1.3%

Details of bundled changes.

Comparing: 9c77ffb...b17cad8

react-dom

File Filesize Diff Gzip Diff Prev Size Current Size Prev Gzip Current Gzip ENV
react-dom.development.js -0.9% -1.2% 611.19 KB 605.39 KB 141.28 KB 139.55 KB UMD_DEV
react-dom.production.min.js -1.0% -1.3% 100.3 KB 99.34 KB 31.85 KB 31.44 KB UMD_PROD
react-dom.development.js -1.0% -1.3% 595.56 KB 589.74 KB 137.14 KB 135.4 KB NODE_DEV
react-dom.production.min.js -1.0% -1.3% 98.74 KB 97.73 KB 31.05 KB 30.65 KB NODE_PROD
ReactDOM-dev.js -1.0% -1.2% 619.99 KB 614.1 KB 139.85 KB 138.1 KB FB_WWW_DEV
ReactDOM-prod.js -0.9% -1.3% 283.99 KB 281.3 KB 51.93 KB 51.26 KB FB_WWW_PROD

react-art

File Filesize Diff Gzip Diff Prev Size Current Size Prev Gzip Current Gzip ENV
react-art.development.js -1.6% -2.4% 414.1 KB 407.57 KB 90.15 KB 88.01 KB UMD_DEV
react-art.production.min.js -1.1% -1.3% 90.62 KB 89.66 KB 27.51 KB 27.15 KB UMD_PROD
react-art.development.js -1.7% -2.5% 339.94 KB 334.22 KB 71.51 KB 69.71 KB NODE_DEV
react-art.production.min.js -1.8% -2.6% 55.14 KB 54.17 KB 16.76 KB 16.33 KB NODE_PROD
ReactART-dev.js -1.7% -2.5% 348.2 KB 342.41 KB 71.06 KB 69.26 KB FB_WWW_DEV
ReactART-prod.js -1.5% -2.2% 166.73 KB 164.18 KB 27.41 KB 26.8 KB FB_WWW_PROD

react-scheduler

File Filesize Diff Gzip Diff Prev Size Current Size Prev Gzip Current Gzip ENV
react-scheduler.development.js +7.0% +6.2% 10.2 KB 10.92 KB 3.6 KB 3.82 KB UMD_DEV
react-scheduler.production.min.js 🔺+3.0% 🔺+2.2% 1.58 KB 1.63 KB 860 B 879 B UMD_PROD
react-scheduler.development.js +7.1% +6.2% 10.01 KB 10.73 KB 3.55 KB 3.77 KB NODE_DEV
react-scheduler.production.min.js 🔺+3.2% 🔺+2.2% 1.66 KB 1.71 KB 871 B 890 B NODE_PROD

Generated by 🚫 dangerJS

@gaearon
Copy link
Collaborator

gaearon commented Apr 25, 2018

Fixtures shouldn’t ever need a new <script> tag. Because we only want to use a package for CJS builds. UMD builds should keep working the way they are.

@@ -24,6 +24,7 @@ const importSideEffects = Object.freeze({
const knownGlobals = Object.freeze({
react: 'React',
'react-dom': 'ReactDOM',
'react-scheduler': 'ReactScheduler',
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don’t think we want this. We don’t want it to be used in UMD builds if I understand it right.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead we want to add react-scheduler to dependencies of react-dom.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does dependencies mean in this context? Things that get inlined into the flat bundle, or things that are left as a require statement (or global reference, for UMD builds)?

The point of the scheduler package is to coordinate React work with non-React work (e.g. Booloader, Webpack, non-React product code) using a centralized scheduler. We want the scheduler to be packaged separately from React and React DOM, not inlined into the flat bundle, so everything can share the same instance.

Since this is a breaking change for UMD bundles, the plan for 16.x is to include the scheduler in the UMD bundle but use the global scheduler if it's available. In 17+, we stop bundling and always use the global scheduler instance.

For CommonJS bundles, it's not a breaking change, so we can externalize it immediately without waiting for 17.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AFAIK putting it in dependencies should do exactly what you described (for 16).

CJS gets a require, UMD continues bundling (if you remove it from knownGlobals).

@@ -1,5 +1,6 @@
<html>
<body>
<script src="../../../build/dist/react-scheduler.development.js"></script>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changes adding script tags should not be needed.

@flarnie
Copy link
Contributor Author

flarnie commented Apr 26, 2018

Thanks - the comments are helpful, will open a separate PR which adds react-scheduler to the dependencies of react-dom.

@flarnie flarnie closed this Apr 26, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants