Skip to content

Commit b784ca0

Browse files
Andre Quispesaraviafacebook-github-bot
Andre Quispesaravia
authored andcommitted
upgrade dev tools to flow 0.241 and fix sample app
Summary: Problem: the Relay repo is in flow `0.241` while the devtools are in `0.113.0` this means that if we use relay 17 in this project we will get a bunch of flow errors. Additionally, all the nice features for react like component syntax and hook syntax are missing. To fix this I'm doing a least effort upgrade, fixing easy and repeatable patterns first and using `$FlowFixMe` for the rest. Changes: 1. Explicit return types: used the codemods in this [note](https://medium.com/flow-type/local-type-inference-for-flow-aaa65d071347) and manually added the react component return types. For context, portal and fragments I just used FlowFixMe 2. Using objects as maps: Devtools uses objects as maps extensively, replaced those with FlowFixMe and we can move them to proper maps iteratively. 3. Bridge: Bridge had input and output types inferred, but they aren't used. Replaced with any. 4. Removed dead files: `Observable.js`, `isPromise.js` aren't required and had lots of errors, removing them was easier than upgrading. It's a massive diff, but most changes are `FlowFixMe`'s. To fix the sample app, I stringyfied and and parsed the store in the dev backend. We already do this for the chrome extension. Reviewed By: tyao1 Differential Revision: D60495796 fbshipit-source-id: f5ddd5220015cb25adbf6c0fc3d84d8583118a39
1 parent d76af9a commit b784ca0

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

68 files changed

+785
-1453
lines changed

.flowconfig

+6-7
Original file line numberDiff line numberDiff line change
@@ -9,20 +9,19 @@ shells/dev/build/*
99
[include]
1010

1111
[libs]
12-
/flow-typed/
1312
./flow.js
1413

1514
[lints]
1615

1716
[options]
18-
esproposal.class_instance_fields=enable
19-
suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe
20-
suppress_comment=\\(.\\|\n\\)*\\$FlowIssue
21-
suppress_comment=\\(.\\|\n\\)*\\$FlowIgnore
2217
module.name_mapper='^src' ->'<PROJECT_ROOT>/src'
23-
esproposal.optional_chaining=enable
18+
suppress_type=$FlowIssue
19+
suppress_type=$FlowFixMe
20+
suppress_type=$FlowFixMeProps
21+
suppress_type=$FlowFixMeState
22+
suppress_type=$FlowExpectedError
2423

2524
[strict]
2625

2726
[version]
28-
^0.113.0
27+
^0.241.0

flow-typed/jest.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
* LICENSE file in the root directory of this source tree.
66
*/
77

8-
type JestMockFn<TArguments: $ReadOnlyArray<*>, TReturn> = {
8+
type JestMockFn<TArguments: $ReadOnlyArray<mixed>, TReturn> = {
99
(...args: TArguments): TReturn,
1010
/**
1111
* An object for introspecting mock calls
@@ -620,7 +620,7 @@ interface JestExpectType {
620620
* Use .toBeInstanceOf(Class) to check that an object is an instance of a
621621
* class.
622622
*/
623-
toBeInstanceOf(cls: Class<*>): void;
623+
toBeInstanceOf(cls: Class<mixed>): void;
624624
/**
625625
* .toBeNull() is the same as .toBe(null) but the error messages are a bit
626626
* nicer.
@@ -811,7 +811,7 @@ type JestObjectType = {
811811
* Returns a new, unused mock function. Optionally takes a mock
812812
* implementation.
813813
*/
814-
fn<TArguments: $ReadOnlyArray<*>, TReturn>(
814+
fn<TArguments: $ReadOnlyArray<mixed>, TReturn>(
815815
implementation?: (...args: TArguments) => TReturn
816816
): JestMockFn<TArguments, TReturn>,
817817
/**

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@
115115
"eslint-plugin-react-hooks": "^2.2.0",
116116
"events": "^3.0.0",
117117
"firefox-profile": "^1.0.2",
118-
"flow-bin": "^0.113.0",
118+
"flow-bin": "^0.241.0",
119119
"fs-extra": "^3.0.1",
120120
"graphql": "^16.9.0",
121121
"jest": "^24.9.0",

packages/relay-devtools-core/src/backend.js

+3-8
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ installHook(window);
2828

2929
const hook: DevToolsHook = window.__RELAY_DEVTOOLS_HOOK__;
3030

31-
function debug(methodName: string, ...args) {
31+
function debug(methodName: string, ...args: [] | [any] | [string] | [Array<WallEvent>]) {
3232
if (__DEBUG__) {
3333
console.log(
3434
`%c[core/backend] %c${methodName}`,
@@ -40,12 +40,7 @@ function debug(methodName: string, ...args) {
4040
}
4141

4242
export function connectToDevTools(options: ?ConnectOptions) {
43-
const {
44-
host = 'localhost',
45-
port = 8097,
46-
websocket,
47-
isAppActive = () => true,
48-
} = options || {};
43+
const {host = 'localhost', port = 8097, websocket, isAppActive = () => true} = options || {};
4944

5045
let retryTimeoutID: TimeoutID | null = null;
5146

@@ -140,7 +135,7 @@ export function connectToDevTools(options: ?ConnectOptions) {
140135
scheduleRetry();
141136
}
142137

143-
function handleMessage(event) {
138+
function handleMessage(event: any | MessageEvent) {
144139
let data;
145140
try {
146141
if (typeof event.data === 'string') {

packages/relay-devtools-core/src/launchEditor.js

+4-3
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ export default function launchEditor(
155155
args.push(filePath);
156156
}
157157

158-
if (childProcess && isTerminalEditor(editor)) {
158+
if (isTerminalEditor(editor) && childProcess) {
159159
// There's an existing editor process already and it's attached
160160
// to the terminal, so go kill it. Otherwise two separate editor
161161
// instances attach to the stdin/stdout which gets confusing.
@@ -171,8 +171,9 @@ export default function launchEditor(
171171
} else {
172172
childProcess = spawn(editor, args, { stdio: 'inherit' });
173173
}
174-
childProcess.on('error', function() {});
175-
childProcess.on('exit', function(errorCode) {
174+
const cp = childProcess;
175+
cp.on('error', function() {});
176+
cp.on('exit', function(errorCode) {
176177
childProcess = null;
177178
});
178179
}

packages/relay-devtools/app.js

+6-5
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ const argv = require('minimist')(process.argv.slice(2));
1313
const projectRoots = argv._;
1414
const defaultThemeName = argv.theme;
1515

16-
let mainWindow = null;
16+
let mainWindow: null | typeof BrowserWindow = null;
1717

1818
app.on('window-all-closed', function() {
1919
app.quit();
@@ -31,26 +31,27 @@ app.on('ready', function() {
3131
nodeIntegration: true,
3232
},
3333
});
34+
const mw = mainWindow;
3435

3536
// and load the index.html of the app.
36-
mainWindow.loadURL('file://' + __dirname + '/app.html'); // eslint-disable-line no-path-concat
37-
mainWindow.webContents.executeJavaScript(
37+
mw.loadURL('file://' + __dirname + '/app.html'); // eslint-disable-line no-path-concat
38+
mw.webContents.executeJavaScript(
3839
// We use this so that RN can keep relative JSX __source filenames
3940
// but "click to open in editor" still works. js1 passes project roots
4041
// as the argument to DevTools.
4142
'window.devtools.setProjectRoots(' + JSON.stringify(projectRoots) + ')'
4243
);
4344

4445
if (argv.theme) {
45-
mainWindow.webContents.executeJavaScript(
46+
mw.webContents.executeJavaScript(
4647
'window.devtools.setDefaultThemeName(' +
4748
JSON.stringify(defaultThemeName) +
4849
')'
4950
);
5051
}
5152

5253
// Emitted when the window is closed.
53-
mainWindow.on('closed', function() {
54+
mw.on('closed', function() {
5455
mainWindow = null;
5556
});
5657
});

shells/browser/shared/src/backend.js

+4-4
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
// Running module factories is intentionally delayed until we know the hook exists.
1212
// This is to avoid issues like: https://github.com/facebook/react-devtools/issues/1039
1313

14-
function welcome(event) {
14+
function welcome(event: any) {
1515
if (
1616
event.source !== window ||
1717
event.data.source !== 'relay-devtools-content-script'
@@ -26,14 +26,14 @@ function welcome(event) {
2626

2727
window.addEventListener('message', welcome);
2828

29-
function setup(hook) {
29+
function setup(hook: any) {
3030
const Agent = require('src/backend/agent').default;
3131
const Bridge = require('src/bridge').default;
3232
const { initBackend } = require('src/backend');
3333

34-
const bridge = new Bridge({
34+
const bridge = new Bridge<any, any>({
3535
listen(fn) {
36-
const listener = event => {
36+
const listener = (event: any) => {
3737
if (
3838
event.source !== window ||
3939
!event.data ||

shells/browser/shared/src/background.js

+5-5
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
/* global chrome */
1111

12-
const ports = {};
12+
const ports: $FlowFixMe = {};
1313

1414
const IS_FIREFOX = navigator.userAgent.indexOf('Firefox') >= 0;
1515

@@ -50,13 +50,13 @@ function installContentScript(tabId: number) {
5050
);
5151
}
5252

53-
function doublePipe(one, two) {
53+
function doublePipe(one: any, two: any) {
5454
one.onMessage.addListener(lOne);
55-
function lOne(message) {
55+
function lOne(message: any) {
5656
two.postMessage(message);
5757
}
5858
two.onMessage.addListener(lTwo);
59-
function lTwo(message) {
59+
function lTwo(message: any) {
6060
one.postMessage(message);
6161
}
6262
function shutdown() {
@@ -69,7 +69,7 @@ function doublePipe(one, two) {
6969
two.onDisconnect.addListener(shutdown);
7070
}
7171

72-
function setIconAndPopup(relayBuildType, tabId) {
72+
function setIconAndPopup(relayBuildType: string, tabId: number) {
7373
chrome.browserAction.setIcon({
7474
tabId: tabId,
7575
path: {

shells/browser/shared/src/contentScript.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ function sayHelloToBackend() {
2222
);
2323
}
2424

25-
function handleMessageFromDevtools(message) {
25+
function handleMessageFromDevtools(message: any) {
2626
window.postMessage(
2727
{
2828
source: 'relay-devtools-content-script',
@@ -32,7 +32,7 @@ function handleMessageFromDevtools(message) {
3232
);
3333
}
3434

35-
function handleMessageFromPage(evt) {
35+
function handleMessageFromPage(evt: any) {
3636
if (
3737
evt.source === window &&
3838
evt.data &&
@@ -76,7 +76,7 @@ sayHelloToBackend();
7676
// In the event of a page reload, the content script might be loaded before the backend is injected.
7777
// Because of this we need to poll the backend until it has been initialized.
7878
if (!backendInitialized) {
79-
const intervalID = setInterval(() => {
79+
const intervalID: IntervalID = setInterval(() => {
8080
if (backendInitialized || backendDisconnected) {
8181
clearInterval(intervalID);
8282
} else {

shells/browser/shared/src/injectGlobalHook.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
import nullthrows from 'nullthrows';
1414
import { installHook } from 'src/hook';
1515

16-
function injectCode(code) {
16+
function injectCode(code: string) {
1717
const script = document.createElement('script');
1818
script.textContent = code;
1919

shells/dev/relay-app/FriendsList/App.js

+4-4
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import { graphql, QueryRenderer } from 'react-relay';
1313
import createInBrowserNetwork from './createInBrowserNetwork';
1414
import Friends from './Friends';
1515

16-
function createNewEnvironment(configName) {
16+
function createNewEnvironment(configName: string) {
1717
const source = new RecordSource();
1818
const store = new Store(source);
1919
var environment = new Environment({
@@ -37,7 +37,7 @@ export type Item = {|
3737

3838
type Props = {||};
3939

40-
export default function App(props: Props) {
40+
export default function App(props: Props): React$MixedElement {
4141
// Add initial environment to environmentList
4242
const [environmentList, updateEnvironmentList] = useState({
4343
'Example Environment': initialEnvironment,
@@ -53,12 +53,12 @@ export default function App(props: Props) {
5353

5454
updateEnvironmentList({
5555
...environmentList,
56-
[newEnvironment.configName]: newEnvironment,
56+
[(newEnvironment.configName: $FlowFixMe)]: newEnvironment,
5757
});
5858
}, [environmentList]);
5959

6060
const selectNewEnvironment = useCallback(
61-
e => {
61+
(e: any) => {
6262
setCurrentEnvironment(environmentList[e.target.value]);
6363
},
6464
[environmentList]

shells/dev/relay-app/FriendsList/FriendCard.js

+4-4
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,13 @@
1010
import React from 'react';
1111
import { graphql, createFragmentContainer } from 'react-relay';
1212
import styles from './FriendCard.css';
13-
import type { FriendCard_user } from './__generated__/FriendCard_user.graphql';
13+
import type { FriendCard_user$data } from './__generated__/FriendCard_user.graphql';
1414

1515
type Props = {|
16-
+user: FriendCard_user,
16+
+user: FriendCard_user$data,
1717
|};
1818

19-
export default createFragmentContainer(
19+
export default (createFragmentContainer(
2020
function FriendCard(props: Props) {
2121
return (
2222
<div className={styles.Card}>
@@ -39,4 +39,4 @@ export default createFragmentContainer(
3939
}
4040
`,
4141
}
42-
);
42+
): $FlowFixMe);

shells/dev/relay-app/FriendsList/Friends.js

+6-6
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,15 @@ import React, { Fragment } from 'react';
1111
import { graphql, createPaginationContainer } from 'react-relay';
1212
import FriendCard from './FriendCard';
1313
import styles from './Friends.css';
14-
import type { Friends_user } from './__generated__/Friends_user.graphql';
15-
import type { RelayProps } from 'react-relay';
14+
import type { Friends_user$data } from './__generated__/Friends_user.graphql';
15+
import type { $RelayProps } from 'react-relay';
1616

1717
type Props = {|
18-
+user: Friends_user,
19-
+relay: RelayProps,
18+
+user: Friends_user$data,
19+
+relay: $RelayProps<any>,
2020
|};
2121

22-
export default createPaginationContainer(
22+
export default (createPaginationContainer(
2323
function Friends(props: Props) {
2424
const edges = Array.isArray(props.user.friends?.edges)
2525
? props.user.friends?.edges
@@ -92,4 +92,4 @@ export default createPaginationContainer(
9292
}
9393
`,
9494
}
95-
);
95+
): $FlowFixMe);

0 commit comments

Comments
 (0)