Skip to content
This repository was archived by the owner on Jan 18, 2024. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/dev-server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@
"@expo/bunyan": "4.0.0",
"@expo/metro-config": "0.3.13",
"@expo/osascript": "2.0.32",
"@react-native-community/cli-server-api": "^5.0.1",
"body-parser": "1.19.0",
"chalk": "^4.0.0",
"connect": "^3.7.0",
Expand All @@ -52,6 +51,7 @@
},
"devDependencies": {
"@types/connect": "^3.4.33",
"@react-native-community/cli-server-api": "^7.0.3",
"metro-inspector-proxy": "^0.64.0"
},
"publishConfig": {
Expand Down
42 changes: 33 additions & 9 deletions packages/dev-server/src/MetroDevServer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,15 @@ export async function runMetroDevServerAsync(

const metroConfig = await ExpoMetroConfig.loadAsync(projectRoot, { reporter, ...options });

const { middleware, attachToServer } = createDevServerMiddleware({
const {
middleware,
attachToServer,

// RN +68 -- Expo SDK +45
messageSocketEndpoint,
eventsSocketEndpoint,
websocketEndpoints,
} = createDevServerMiddleware(projectRoot, {
port: metroConfig.server.port,
watchFolders: metroConfig.watchFolders,
logger: options.logger,
Expand All @@ -100,16 +108,32 @@ export async function runMetroDevServerAsync(
return middleware.use(metroMiddleware);
};

const server = await Metro.runServer(metroConfig, { hmrEnabled: true });
const server = await Metro.runServer(metroConfig, {
hmrEnabled: true,
websocketEndpoints,
});

const { messageSocket, eventsSocket } = attachToServer(server);
reporter.reportEvent = eventsSocket.reportEvent;
if (attachToServer) {
// Expo SDK 44 and lower
const { messageSocket, eventsSocket } = attachToServer(server);
reporter.reportEvent = eventsSocket.reportEvent;

return {
server,
middleware,
messageSocket,
};
return {
server,
middleware,
messageSocket,
};
} else {
// RN +68 -- Expo SDK +45
reporter.reportEvent = eventsSocketEndpoint.reportEvent;

return {
server,
middleware,
messageSocket: messageSocketEndpoint,
// debuggerProxyEndpoint,
};
}
}

let nextBuildID = 0;
Expand Down
6 changes: 6 additions & 0 deletions packages/dev-server/src/metro/importMetroFromProject.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,12 @@ export function importMetroServerFromProject(projectRoot: string): typeof Metro.
return importFromProject(projectRoot, 'metro/src/Server');
}

export function importCliServerApiFromProject(
projectRoot: string
): typeof import('@react-native-community/cli-server-api') {
return importFromProject(projectRoot, '@react-native-community/cli-server-api');
}

export function importInspectorProxyServerFromProject(
projectRoot: string
): { InspectorProxy: any } {
Expand Down
61 changes: 40 additions & 21 deletions packages/dev-server/src/middleware/devServerMiddleware.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,15 @@
import type Log from '@expo/bunyan';
import {
createDevServerMiddleware as createReactNativeDevServerMiddleware,
securityHeadersMiddleware,
} from '@react-native-community/cli-server-api';
import Log from '@expo/bunyan';
import bodyParser from 'body-parser';
import type { Server as ConnectServer } from 'connect';
import { Server as ConnectServer } from 'connect';

import { importCliServerApiFromProject } from '../metro/importMetroFromProject';
import { prependMiddleware, replaceMiddlewareWith } from '../middlwareMutations';
import clientLogsMiddleware from './clientLogsMiddleware';
import createJsInspectorMiddleware from './createJsInspectorMiddleware';
import { remoteDevtoolsCorsMiddleware } from './remoteDevtoolsCorsMiddleware';
import { remoteDevtoolsSecurityHeadersMiddleware } from './remoteDevtoolsSecurityHeadersMiddleware';
import { suppressRemoteDebuggingErrorMiddleware } from './suppressErrorMiddleware';

export type AttachToServerFunction = ReturnType<
typeof createReactNativeDevServerMiddleware
>['attachToServer'];

/**
* Extends the default `createDevServerMiddleware` and adds some Expo CLI-specific dev middleware
* with exception for the manifest middleware which is currently in `xdl`.
Expand All @@ -33,16 +26,32 @@ export type AttachToServerFunction = ReturnType<
*
* @returns
*/
export function createDevServerMiddleware({
watchFolders,
port,
logger,
}: {
watchFolders: readonly string[];
port: number;
logger: Log;
}): { middleware: ConnectServer; attachToServer: AttachToServerFunction; logger: Log } {
const { middleware, attachToServer } = createReactNativeDevServerMiddleware({
export function createDevServerMiddleware(
projectRoot: string,
{
watchFolders,
port,
logger,
}: {
watchFolders: readonly string[];
port: number;
logger: Log;
}
) {
const { createDevServerMiddleware, securityHeadersMiddleware } = importCliServerApiFromProject(
projectRoot
);
const {
middleware,
// @ts-expect-error: Old API
attachToServer,

// New
debuggerProxyEndpoint,
messageSocketEndpoint,
eventsSocketEndpoint,
websocketEndpoints,
} = createDevServerMiddleware({
port,
watchFolders,
});
Expand All @@ -61,5 +70,15 @@ export function createDevServerMiddleware({
middleware.use('/logs', clientLogsMiddleware(logger));
middleware.use('/inspector', createJsInspectorMiddleware());

return { middleware, attachToServer, logger };
return {
logger,
middleware,
// Old
attachToServer,
// New
debuggerProxyEndpoint,
messageSocketEndpoint,
eventsSocketEndpoint,
websocketEndpoints,
};
}
2 changes: 1 addition & 1 deletion packages/expo-cli/src/commands/start/parseStartOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ export function parseStartOptions(
}

// The SDK 41 client has web socket support.
if (Versions.gteSdkVersion(exp, '41.0.0')) {
if (!Versions.lteSdkVersion(exp, '40.0.0')) {
Copy link
Member

Choose a reason for hiding this comment

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

personally i think the original version of this read more clearly 🤷

Copy link
Contributor Author

Choose a reason for hiding this comment

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

But if you ran this in a project without Expo it would default to false whereas the feature is now old enough to default to being true.

Copy link
Member

Choose a reason for hiding this comment

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

i see. that's an unexpected nuance here.

startOpts.isRemoteReloadingEnabled = true;
if (!startOpts.webOnly || Webpack.isTargetingNative()) {
startOpts.isWebSocketsEnabled = true;
Expand Down
50 changes: 30 additions & 20 deletions packages/xdl/src/Webpack.ts
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ function createNativeDevServerMiddleware(
if (!isTargetingNative()) {
return null;
}
const nativeMiddleware = createDevServerMiddleware({
const nativeMiddleware = createDevServerMiddleware(projectRoot, {
logger: ProjectUtils.getLogger(projectRoot),
port,
watchFolders: [projectRoot],
Expand Down Expand Up @@ -179,30 +179,40 @@ function attachNativeDevServerMiddlewareToDevServer(
{
server,
middleware,
attachToServer,
logger,
// Expo SDK 44 and lower
attachToServer,
// React Native +68 -- Expo SDK 45 and higher
messageSocketEndpoint,
eventsSocketEndpoint,
}: { server: http.Server } & ReturnType<typeof createNativeDevServerMiddleware>
) {
// Hook up the React Native WebSockets to the Webpack dev server.
const { messageSocket, debuggerProxy, eventsSocket } = attachToServer(server);
if (attachToServer) {
// Hook up the React Native WebSockets to the Webpack dev server.
const { messageSocket, eventsSocket } = attachToServer(server);

customMessageSocketBroadcaster = messageSocket.broadcast;
customMessageSocketBroadcaster = messageSocket.broadcast;

const logReporter = new LogReporter(logger);
logReporter.reportEvent = eventsSocket.reportEvent;
const logReporter = new LogReporter(logger);
logReporter.reportEvent = eventsSocket.reportEvent;

const { inspectorProxy } = attachInspectorProxy(projectRoot, {
middleware,
server,
});
attachInspectorProxy(projectRoot, {
middleware,
server,
});
} else {
// React Native +68
const logReporter = new LogReporter(logger);

return {
messageSocket,
eventsSocket,
debuggerProxy,
logReporter,
inspectorProxy,
};
logReporter.reportEvent = eventsSocketEndpoint.reportEvent;

customMessageSocketBroadcaster = messageSocketEndpoint.broadcast;

attachInspectorProxy(projectRoot, {
middleware,
server,
});
}
}

export async function startAsync(
Expand Down Expand Up @@ -494,7 +504,7 @@ async function getAvailablePortAsync(options: {
throw new Error(`Port ${defaultPort} not available.`);
}
return port;
} catch (error) {
} catch (error: any) {
throw new XDLError('NO_PORT_FOUND', error.message);
}
}
Expand Down Expand Up @@ -677,7 +687,7 @@ async function openProjectAsync(
}
openBrowserAsync(url);
return { success: true, url };
} catch (e) {
} catch (e: any) {
Logger.global.error(`Couldn't start project on web: ${e.message}`);
return { success: false, error: e };
}
Expand Down
1 change: 1 addition & 0 deletions ts-declarations/metro/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@ declare module 'metro' {
secure?: boolean;
secureCert?: string;
secureKey?: string;
websocketEndpoints?: object;
};

type BuildGraphOptions = {
Expand Down
44 changes: 40 additions & 4 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2866,6 +2866,13 @@
dependencies:
serve-static "^1.13.1"

"@react-native-community/cli-debugger-ui@^7.0.3":
version "7.0.3"
resolved "https://registry.yarnpkg.com/@react-native-community/cli-debugger-ui/-/cli-debugger-ui-7.0.3.tgz#3eeeacc5a43513cbcae56e5e965d77726361bcb4"
integrity sha512-G4SA6jFI0j22o+j+kYP8/7sxzbCDqSp2QiHA/X5E0lsGEd2o9qN2zbIjiFr8b8k+VVAYSUONhoC0+uKuINvmkA==
dependencies:
serve-static "^1.13.1"

"@react-native-community/cli-hermes@^5.0.1":
version "5.0.1"
resolved "https://registry.yarnpkg.com/@react-native-community/cli-hermes/-/cli-hermes-5.0.1.tgz#039d064bf2dcd5043beb7dcd6cdf5f5cdd51e7fc"
Expand Down Expand Up @@ -2921,6 +2928,21 @@
serve-static "^1.13.1"
ws "^1.1.0"

"@react-native-community/cli-server-api@^7.0.3":
version "7.0.3"
resolved "https://registry.yarnpkg.com/@react-native-community/cli-server-api/-/cli-server-api-7.0.3.tgz#ba9695a2fdfef22750d141153efd94baf641129b"
integrity sha512-JDrLsrkBgNxbG2u3fouoVGL9tKrXUrTsaNwr+oCV+3XyMwbVe42r/OaQ681/iW/7mHXjuVkDnMcp7BMg7e2yJg==
dependencies:
"@react-native-community/cli-debugger-ui" "^7.0.3"
"@react-native-community/cli-tools" "^6.2.0"
compression "^1.7.1"
connect "^3.6.5"
errorhandler "^1.5.0"
nocache "^2.1.0"
pretty-format "^26.6.2"
serve-static "^1.13.1"
ws "^7.5.1"

"@react-native-community/cli-tools@^5.0.1":
version "5.0.1"
resolved "https://registry.yarnpkg.com/@react-native-community/cli-tools/-/cli-tools-5.0.1.tgz#9ee564dbe20448becd6bce9fbea1b59aa5797919"
Expand All @@ -2933,6 +2955,20 @@
open "^6.2.0"
shell-quote "1.6.1"

"@react-native-community/cli-tools@^6.2.0":
version "6.2.0"
resolved "https://registry.yarnpkg.com/@react-native-community/cli-tools/-/cli-tools-6.2.0.tgz#8f4adc2d83ab96e5654348533c8fa602742c4fce"
integrity sha512-08ssz4GMEnRxC/1FgTTN/Ud7mExQi5xMphItPjfHiTxpZPhrFn+IMx6mya0ncFEhhxQ207wYlJMRLPRRdBZ8oA==
dependencies:
appdirsjs "^1.2.4"
chalk "^4.1.2"
lodash "^4.17.15"
mime "^2.4.1"
node-fetch "^2.6.0"
open "^6.2.0"
semver "^6.3.0"
shell-quote "1.6.1"

"@react-native-community/cli-types@^5.0.1":
version "5.0.1"
resolved "https://registry.yarnpkg.com/@react-native-community/cli-types/-/cli-types-5.0.1.tgz#8c5db4011988b0836d27a5efe230cb34890915dc"
Expand Down Expand Up @@ -18571,10 +18607,10 @@ ws@^6.1.4, ws@^6.2.1:
dependencies:
async-limiter "~1.0.0"

ws@^7, ws@^7.2.3:
version "7.5.2"
resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.2.tgz#09cc8fea3bec1bc5ed44ef51b42f945be36900f6"
integrity sha512-lkF7AWRicoB9mAgjeKbGqVUekLnSNO4VjKVnuPHpQeOxZOErX6BPXwJk70nFslRCEEA8EVW7ZjKwXaP9N+1sKQ==
ws@^7, ws@^7.2.3, ws@^7.5.1:
version "7.5.7"
resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.7.tgz#9e0ac77ee50af70d58326ecff7e85eb3fa375e67"
integrity sha512-KMvVuFzpKBuiIXW3E4u3mySRO2/mCHSyZDJQM5NQ9Q9KHWHWh0NHgfbRMLLrceUK5qAL4ytALJbpRMjixFZh8A==

xcode@^2.0.0:
version "2.1.0"
Expand Down