It turns out that flow cannot type `this` with a function constructor + prototype overrides. Turning it to a class makes flow happy and has minimal impact on the output.
In open source, we already use the loose version of the class transform and internally we have one that's outputting even less code if you have `@preventMunge` in the header.
See discussion in https://www.facebook.com/groups/2003630259862046/permalink/2098480820376989/
(cherry picked from commit a70acb37d9)
We used to copy and paste the same big blob many times in order for it to work with keyOf which is no longer a constraint. This pull request takes a list of all the events as string and generate those data structures at runtime.
It reduces the size of React by 1k post gzip and flow is able to extract the structure out of it :)
(cherry picked from commit 1229a238c4)
This is the last callsite of keyMirror! It removes 0.5k gzipped :)
The only trick with this one is that ReactTestUtils actually iterates over the list of all the events. Instead of duplicating the logic, I used the $Enum feature of flow that lets us statically extract out the type from the dynamic value. Inside of react-dom we're no longer requiring the file directly so it doesn't bloat the file size, and we still get to have static typing, best of both worlds!
(cherry picked from commit 2f9a9dc4c5)
This one is interesting because we have transaction objects being passed around everywhere in the codebase but there's actually no Transaction class. It's a "mixin" that comes to life by being Object.assigned to the prototype of a real "class" (before class was cool!). Therefore, we can't just say `var Transaction = require('Transaction'); (transaction: Transaction) => { }` because it would be the object that contains a mixin and not an instance of a transaction.
The trick I use is to export `TransactionType` and alias it to `Transaction` in the file as it doesn't actually require transaction. In case they do, we'll figure it out, but in the few files I looked at, it doesn't seem to be the case.
For the perform function, it actually typechecks pretty well!
(cherry picked from commit a3e576e1bb)
This one was really interesting to type as it's doing a lot of unusual JavaScript. Fortunately flow is now pretty kick ass and I've been able to mostly type it. The only missing piece is that it won't check the constructor arguments.
If you are a fb employee, you can follow the discussion here: https://www.facebook.com/groups/flowtype/permalink/1132359430146004/
(cherry picked from commit 19b8eadb24)
Incrementally type ReactInstance by adding the types of attach/detachRef.
I moved isValidOwner as a function inside of the file since it's never used externally.
(cherry picked from commit fa9869b5a0)
This one involves a bit more work as I added "phantom" flow types to a bunch of places where the type is a ReactPropTypeLocations even though those files are not `@flow` yet.
A good side effect is that `ReactPropTypeLocationNames` keys are now correctly typed, this means that they cannot go out of sync without breaking flow :)
(cherry picked from commit 84084153ed)
Flow doesn't really support the concept of variables that are non-null but only inside of a `__DEV__` block. There's an internal post about it ( https://www.facebook.com/groups/flowtype/permalink/1132437726804841/ ) and the conclusion is that we should force it to be non-null and trust the developer to put the proper DEV checks in place.
(cherry picked from commit 0d927844fb)
We need to export FlushHistory type and I submitted a PR on flow to fix the type of console.table which is too restrictive.
I'm already starting to see the benefits of flow, I can look at random variables in the code and flow knows what shape the objects are! It's really useful to try and understand what's going on :)
(cherry picked from commit 2fb5eae372)
It turns out that we don't need it, flow is smart enough to realize that the function is declared in the two branches :)
(cherry picked from commit b977cf13c4)
In Type ReactComponentTreeHook #7504, I merged even though travis didn't report green (travis for all the fb repos has been backlogged like crazy since this morning) by manually doing `npm test` and `npm run flow` but I didn't ensure that lint was all green.
@millermedeiros pinged me about it so here's a quick fix
(cherry picked from commit 66e77f696a)
For this one, I wanted to type a non-trivial piece of the codebase and ran into the fact that we do not have types for ReactElement nor ReactInstance, so I had to create them.
I'll add comments inline
(cherry picked from commit ea494a2c10)
* Show React events in the timeline when ReactPerf is active
This currently only seems to work on Chrome.
* Address Chrome issue
(cherry picked from commit 0a248ee7b9)
I already had to aliasify to have better control over the requires
so we might as well do it everywhere for consistency.
This probably makes it easier to rebase the rollup work too
because aliases seems to be how you solve this in that world.
(cherry picked from commit c8f7215b20)
This is needed for flat builds. It also lets us get rid of a bunch
of special cases in the build scripts.
It also allow us to just copy the source files into React Native
instead of having to build first to resolve the special cases.
(cherry picked from commit 1c5a639c37)
This builds a `react-dom-fiber.js` bundle which exposes ReactDOMFiber.
This allows early experiments with the new Fiber reconciler.
I also expose it in the npm package through `react-dom/fiber`.
(cherry picked from commit f7e0db9a18)
This copies modules into three separate packages instead of
putting it all in React.
The overlap in shared and between renderers gets duplicated.
This allows the isomorphic package to stay minimal. It can also
be used as a direct dependency without much risk.
This also allow us to ship versions to each renderer independently
and we can ship renderers without updating the main react package
dependency.
(cherry picked from commit 0f004efce2)
We currently write all our tests against the DOM implementation.
I need a way to run the Fiber tests against it. But I don't want
to take on any package dependencies on Fiber modules yet.
There's a problem with jest right now where you can't globally
mock modules that already exist. So I have to add a global call
to jest.mock.
Luckily we already have a way to test the useCreateElement paths
using a feature flag. I won't activate this flag in travis until
it passes, but the idea is to run all three variants in travis.
I'm not sure that invoking rAF and rIC synchronously is the best
way to test this since it doesn't capture the backwards
compatibility aspect. I.e. the fact that people might be relying
on the synchronous nature in real apps too. It's a start.
Ideally, jest would have these built-in.
(cherry picked from commit c06a68a10b)
* Cut out isomorphic dependencies from the renderers
These files reaches into isomorphic files.
The ReactElement functions are exposed on the React object anyway
so I can just use those instead.
I also found some files that are not shared that should be in
renderers shared.
* Found a few more shared dependencies
renderSubtreeIntoContainer is only used by the DOM renderer.
It's not an addon.
ReactClass isn't needed as a dependency since injection doesn't
happen anymore.
* Use a shim file to load addons' dependencies on DOM
By replacing this intermediate file we can do the lazy loading
without needing any lazy requires. This set up works with ES
modules.
We could also replace the globalShim thing with aliased files
instead for consistency.
* Bundle DOM renderers into their individual UMD bundles
Instead of exposing the entire DOM renderer on the react.js
package, I only expose CurrentOwner and ComponentTreeDevtool which
are currently the only two modules that share __state__ with the
renderers.
Then I package each renderer in its own package. That could allow
us to drop more server dependencies from the client package. It
will also allow us to ship fiber as a separate renderer.
Unminified DEV after before
react.js 123kb 696kb
react-with-addons.js 227kb 774kb
react-dom.js 668kb 1kb
react-dom-server.js 638kb 1kb
Minified PROD after before
react.min.js 24kb 154kb
react-with-addons.min.js 37kb 166kb
react-dom.min.js 149kb 1kb
react-dom-server.min.js 144kb 1kb
The total size for react.min.js + react-dom.min.js is +19kb larger
because of the overlap between them right now. I'd like to see
what an optimizing compiler can do to this. Some of that is fbjs
stuff. There shouldn't need to be that much overlap so that's
something we can hunt. We should keep isomorphic absolutely
minimal so there's no reason for other React clones not to use it.
There will be less overlap with Fiber.
However, another strategy that we could do is package the
isomorphic package into each renderer bundle and conditionally
initialize it if it hasn't already been initialized. That way
you only pay an overlap tax when there are two renderers on the
page but not without it. It's also easier to just pull in one
package. The downside is the versioning stuff that the separate
npm package would solve. That applies to CDNs as well.
ReactWithAddons is a bit weird because it is packaged into the
isomorphic package but has a bunch of DOM dependencies. So we have
to load them lazily since the DOM package gets initialized after.
(cherry picked from commit 8ef00dbb7d)
* PropTypes: distinguish nullable from optional object field
This gives a more precise message (no type semantics change) to the case of passing a field in an object, but whose value is `null`:
Before:
```js
propTypes: {
foo: React.PropTypes.number.isRequired
}
```
Would scream "Required prop `foo` was not specified in `MyComp`".
Now it'll be "Required prop `foo` was specified in `MyComp`, but its value is `null`.".
Works as expected in nested objects.
This fixes the issue of a component transitively passing a `null`, specifying the correct field to the child but have the child tell it that it didn't provide the prop.
Optional field and nullable are two different things anyway.
* Add missing test case.
* Reword messages.
(cherry picked from commit 0292d34047)