Skip to content

Commit

Permalink
feat(react-native): upgrade react-native to 0.72.0
Browse files Browse the repository at this point in the history
  • Loading branch information
xiongemi committed Jun 26, 2023
1 parent 836cd34 commit 3526968
Show file tree
Hide file tree
Showing 36 changed files with 895 additions and 495 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,7 @@
"presets": [
{ "name": "Build iOS for a simulator", "keys": ["simulator"] },
{ "name": "Build iOS for a device", "keys": ["device"] },
{ "name": "Build iOS for a device with udid", "keys": ["udid"] },
{
"name": "Run `pod install` before building iOS app",
"keys": ["install"]
}
{ "name": "Build iOS for a device with udid", "keys": ["udid"] }
],
"properties": {
"simulator": {
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,8 @@
"magic-string": "~0.26.2",
"markdown-factory": "^0.0.6",
"memfs": "^3.0.1",
"metro-resolver": "^0.74.1",
"metro-config": "^0.76.5",
"metro-resolver": "^0.76.5",
"mini-css-extract-plugin": "~2.4.7",
"minimatch": "3.0.5",
"next-sitemap": "^3.1.10",
Expand Down Expand Up @@ -349,4 +350,3 @@
]
}
}

1 change: 0 additions & 1 deletion packages/expo/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@
"chalk": "^4.1.0",
"enhanced-resolve": "^5.8.3",
"fs-extra": "^11.1.0",
"metro-resolver": "^0.74.1",
"node-fetch": "^2.6.7",
"tar-fs": "^2.1.1",
"tsconfig-paths": "^4.1.2",
Expand Down
4 changes: 0 additions & 4 deletions packages/react-native/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@
"fs-extra": "^11.1.0",
"glob": "7.1.4",
"ignore": "^5.0.4",
"metro-resolver": "^0.74.1",
"minimatch": "3.0.5",
"node-fetch": "^2.6.7",
"tsconfig-paths": "^4.1.2",
Expand All @@ -42,9 +41,6 @@
"@nx/react": "file:../react",
"@nx/workspace": "file:../workspace"
},
"peerDependencies": {
"react-native": ">= 0.71.0"
},
"builders": "./executors.json",
"ng-update": {
"requirements": {},
Expand Down
33 changes: 19 additions & 14 deletions packages/react-native/plugins/with-nx-metro.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import { workspaceLayout, workspaceRoot } from '@nx/devkit';
import { MetroConfig, mergeConfig } from 'metro-config';
const { getDefaultConfig } = require('metro-config'); // use require for typing issues of getDefaultConfig
import { join } from 'path';
import { existsSync } from 'fs-extra';

Expand All @@ -11,32 +13,35 @@ interface WithNxOptions {
watchFolders?: string[];
}

export function withNxMetro(config: any, opts: WithNxOptions = {}) {
export async function withNxMetro(
userConfig: MetroConfig,
opts: WithNxOptions = {}
) {
const defaultConfig = await getDefaultConfig(
opts.projectRoot || workspaceRoot
);
const extensions = ['', 'ts', 'tsx', 'js', 'jsx', 'json'];
if (opts.debug) process.env.NX_REACT_NATIVE_DEBUG = 'true';
if (opts.extensions) extensions.push(...opts.extensions);

config.projectRoot = opts.projectRoot || workspaceRoot;

// Add support for paths specified by tsconfig
config.resolver = {
...config.resolver,
resolveRequest: getResolveRequest(extensions),
};

let watchFolders = config.watchFolders || [];
watchFolders = watchFolders.concat([
let watchFolders = [
join(workspaceRoot, 'node_modules'),
join(workspaceRoot, workspaceLayout().libsDir),
join(workspaceRoot, 'packages'),
join(workspaceRoot, '.storybook'),
]);
];
if (opts.watchFolders?.length) {
watchFolders = watchFolders.concat(opts.watchFolders);
}

watchFolders = watchFolders.filter((folder) => existsSync(folder));
config.watchFolders = watchFolders;

return config;
const nxConfig: MetroConfig = {
resolver: {
resolveRequest: getResolveRequest(extensions),
},
watchFolders,
};

return mergeConfig(defaultConfig, userConfig, nxConfig);
}
Original file line number Diff line number Diff line change
@@ -1,93 +1,74 @@
import { ExecutorContext, names } from '@nx/devkit';
import { join } from 'path';
import { ensureNodeModulesSymlink } from '../../utils/ensure-node-modules-symlink';
import { ExecutorContext, runExecutor } from '@nx/devkit';
import { join, resolve as pathResolve } from 'path';
import { ChildProcess, fork } from 'child_process';
import { ReactNativeBuildAndroidOptions } from './schema';
import { chmodAndroidGradlewFiles } from '../../utils/chmod-android-gradle-files';
import { runCliStart } from '../start/start.impl';
import {
displayNewlyAddedDepsMessage,
syncDeps,
} from '../sync-deps/sync-deps.impl';
import startExecutor, { runCliStart } from '../start/start.impl';
import { getCliOptions } from '../../utils/get-cli-options';

export interface ReactNativeBuildOutput {
success: boolean;
}

let childProcess: ChildProcess;

export default async function* buildAndroidExecutor(
options: ReactNativeBuildAndroidOptions,
context: ExecutorContext
): AsyncGenerator<ReactNativeBuildOutput> {
const projectRoot =
context.projectsConfigurations.projects[context.projectName].root;
ensureNodeModulesSymlink(context.root, projectRoot);
if (options.sync) {
displayNewlyAddedDepsMessage(
context.projectName,
await syncDeps(
context.projectName,
projectRoot,
context.root,
context.projectGraph
)
);
}

chmodAndroidGradlewFiles(join(projectRoot, 'android'));

try {
const tasks = [runCliBuild(context.root, projectRoot, options)];
if (options.packager && options.mode !== 'release') {
tasks.push(
runCliStart(context.root, projectRoot, {
port: options.port,
resetCache: options.resetCache,
interactive: options.interactive,
})
);
}

await Promise.all(tasks);
yield { success: true };
} finally {
if (childProcess) {
childProcess.kill();
runCliBuild(context.root, projectRoot, options);
if (options.packager && options.mode !== 'release') {
const startResults = startExecutor(options, context);
for await (const result of startResults) {
if (!result.success) {
return result;
}
yield {
success: true,
};
}
}
yield { success: true };
}

function runCliBuild(
workspaceRoot: string,
projectRoot: string,
options: ReactNativeBuildAndroidOptions
) {
return new Promise((resolve, reject) => {
return new Promise<ChildProcess>((res, reject) => {
/**
* Call the react native cli with option `--no-packager`
* Not passing '--packager' due to cli will launch start command from the project root
*/
childProcess = fork(
join(workspaceRoot, './node_modules/react-native/cli.js'),
const childProcess = fork(
require.resolve('react-native/cli.js'),
['build-android', ...createBuildAndroidOptions(options), '--no-packager'],
{
cwd: join(workspaceRoot, projectRoot),
stdio: 'inherit',
cwd: pathResolve(workspaceRoot, projectRoot),
env: { ...process.env, RCT_METRO_PORT: options.port.toString() },
}
);

// Ensure the child process is killed when the parent exits
process.on('exit', () => childProcess.kill());
process.on('SIGTERM', () => childProcess.kill());
/**
* Ensure the child process is killed when the parent exits
*/
const processExitListener = (signal?: number | NodeJS.Signals) => () =>
childProcess.kill(signal);
process.on('exit', processExitListener);
process.on('SIGTERM', processExitListener);
process.on('SIGINT', processExitListener);
process.on('SIGQUIT', processExitListener);

childProcess.on('error', (err) => {
reject(err);
});
childProcess.on('exit', (code) => {
if (code === 0) {
resolve(code);
res(childProcess);
} else {
reject(code);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,9 @@ export interface ReactNativeBuildAndroidOptions
// react native options
mode: string; // default is debug
activeArchOnly: boolean; // default is false
port: number; // default is 8081
tasks?: Array<string>;
extraParams?: Array<string>;
interactive?: boolean;
interactive: boolean;

// nx options
packager: boolean; // default is true
Expand Down
82 changes: 27 additions & 55 deletions packages/react-native/src/executors/build-ios/build-ios.impl.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,8 @@
import { ExecutorContext } from '@nx/devkit';
import { join } from 'path';
import { resolve } from 'path';
import { ChildProcess, fork } from 'child_process';
import { platform } from 'os';

import { ensureNodeModulesSymlink } from '../../utils/ensure-node-modules-symlink';
import {
displayNewlyAddedDepsMessage,
syncDeps,
} from '../sync-deps/sync-deps.impl';
import { podInstall } from '../../utils/pod-install-task';
import { ReactNativeBuildIosOptions } from './schema';
import { runCliStart } from '../start/start.impl';
import { getCliOptions } from '../../utils/get-cli-options';
Expand All @@ -17,9 +11,7 @@ export interface ReactNativeBuildIosOutput {
success: boolean;
}

let childProcess: ChildProcess;

export default async function* runIosExecutor(
export default async function* buildIosExecutor(
options: ReactNativeBuildIosOptions,
context: ExecutorContext
): AsyncGenerator<ReactNativeBuildIosOutput> {
Expand All @@ -28,77 +20,57 @@ export default async function* runIosExecutor(
}
const projectRoot =
context.projectsConfigurations.projects[context.projectName].root;
ensureNodeModulesSymlink(context.root, projectRoot);
if (options.sync) {
displayNewlyAddedDepsMessage(
context.projectName,
await syncDeps(
context.projectName,
projectRoot,
context.root,
context.projectGraph
)
);
}

if (options.install) {
await podInstall(
join(context.root, projectRoot, 'ios'),
options.buildFolder
const tasks = [runCliBuildIOS(context.root, projectRoot, options)];
if (options.packager && options.mode !== 'Release') {
tasks.push(
runCliStart(context.root, projectRoot, {
port: options.port,
resetCache: options.resetCache,
interactive: options.interactive,
})
);
}

try {
const tasks = [runCliBuildIOS(context.root, projectRoot, options)];
if (options.packager && options.mode !== 'Release') {
tasks.push(
runCliStart(context.root, projectRoot, {
port: options.port,
resetCache: options.resetCache,
interactive: options.interactive,
})
);
}

await Promise.all(tasks);
await Promise.all(tasks);

yield { success: true };
} finally {
if (childProcess) {
childProcess.kill();
}
}
yield { success: true };
}

function runCliBuildIOS(
workspaceRoot: string,
projectRoot: string,
options: ReactNativeBuildIosOptions
) {
return new Promise((resolve, reject) => {
): Promise<ChildProcess> {
return new Promise<ChildProcess>((res, reject) => {
/**
* Call the react native cli with option `--no-packager`
* Not passing '--packager' due to cli will launch start command from the project root
*/
childProcess = fork(
join(workspaceRoot, './node_modules/react-native/cli.js'),
const childProcess = fork(
require.resolve('react-native/cli.js'),
['build-ios', ...createBuildIOSOptions(options)],
{
cwd: join(workspaceRoot, projectRoot),
cwd: resolve(workspaceRoot, projectRoot),
env: { ...process.env, RCT_METRO_PORT: options.port.toString() },
}
);

// Ensure the child process is killed when the parent exits
process.on('exit', () => childProcess.kill());
process.on('SIGTERM', () => childProcess.kill());

/**
* Ensure the child process is killed when the parent exits
*/
const processExitListener = (signal?: number | NodeJS.Signals) => () =>
childProcess.kill(signal);
process.on('exit', processExitListener);
process.on('SIGTERM', processExitListener);
process.on('SIGINT', processExitListener);
process.on('SIGQUIT', processExitListener);
childProcess.on('error', (err) => {
reject(err);
});
childProcess.on('exit', (code) => {
if (code === 0) {
resolve(code);
res(childProcess);
} else {
reject(code);
}
Expand Down
2 changes: 2 additions & 0 deletions packages/react-native/src/executors/build-ios/schema.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ export interface ReactNativeBuildIosOptions extends ReactNativeStartOptions {

// nx options
packager: boolean; // default is true
// @deprecated, add to pod-install to dependOn
install: boolean; // default is true
// @deprecated, add to sync-deps to dependOn
sync: boolean; // default is true
}
4 changes: 0 additions & 4 deletions packages/react-native/src/executors/build-ios/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,6 @@
{
"name": "Build iOS for a device with udid",
"keys": ["udid"]
},
{
"name": "Run `pod install` before building iOS app",
"keys": ["install"]
}
],
"properties": {
Expand Down
Loading

0 comments on commit 3526968

Please sign in to comment.