@nx/react-native 16.6.0-beta.3 → 16.6.0-beta.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. package/.eslintrc.json +23 -0
  2. package/migrations.json +78 -0
  3. package/package.json +15 -13
  4. package/plugins/with-nx-metro.d.ts +5 -1
  5. package/plugins/with-nx-metro.js +27 -22
  6. package/src/executors/build-android/build-android.impl.js +18 -32
  7. package/src/executors/build-android/build-android.impl.ts +21 -50
  8. package/src/executors/build-android/schema.d.ts +5 -3
  9. package/src/executors/build-android/schema.json +14 -8
  10. package/src/executors/build-ios/build-ios.impl.d.ts +1 -1
  11. package/src/executors/build-ios/build-ios.impl.js +23 -42
  12. package/src/executors/build-ios/build-ios.impl.ts +26 -64
  13. package/src/executors/build-ios/schema.d.ts +3 -0
  14. package/src/executors/build-ios/schema.json +8 -6
  15. package/src/executors/bundle/bundle.impl.js +19 -17
  16. package/src/executors/bundle/bundle.impl.ts +24 -23
  17. package/src/executors/pod-install/pod-install.impl.js +1 -1
  18. package/src/executors/pod-install/pod-install.impl.ts +1 -1
  19. package/src/executors/pod-install/schema.d.ts +3 -1
  20. package/src/executors/pod-install/schema.json +11 -1
  21. package/src/executors/run-android/run-android.impl.js +47 -26
  22. package/src/executors/run-android/run-android.impl.ts +40 -45
  23. package/src/executors/run-android/schema.d.ts +2 -2
  24. package/src/executors/run-android/schema.json +9 -5
  25. package/src/executors/run-ios/run-ios.impl.js +47 -31
  26. package/src/executors/run-ios/run-ios.impl.ts +42 -56
  27. package/src/executors/run-ios/schema.d.ts +1 -1
  28. package/src/executors/run-ios/schema.json +7 -6
  29. package/src/executors/start/start.impl.d.ts +4 -2
  30. package/src/executors/start/start.impl.js +35 -24
  31. package/src/executors/start/start.impl.ts +42 -35
  32. package/src/executors/storybook/schema.d.ts +1 -1
  33. package/src/generators/application/application.js +1 -3
  34. package/src/generators/application/files/app/Gemfile.template +2 -2
  35. package/src/generators/application/files/app/android/app/build.gradle.template +2 -49
  36. package/src/generators/application/files/app/android/app/src/main/java/com/__lowerCaseName__/MainActivity.java.template +1 -4
  37. package/src/generators/application/files/app/android/app/src/main/res/drawable/rn_edit_text_material.xml +1 -1
  38. package/src/generators/application/files/app/android/build.gradle.template +1 -1
  39. package/src/generators/application/files/app/android/gradle/wrapper/gradle-wrapper.jar +0 -0
  40. package/src/generators/application/files/app/android/gradle/wrapper/gradle-wrapper.properties +2 -1
  41. package/src/generators/application/files/app/android/gradle.properties +1 -1
  42. package/src/generators/application/files/app/android/gradlew.bat +9 -6
  43. package/src/generators/application/files/app/android/gradlew.template +14 -4
  44. package/src/generators/application/files/app/android/settings.gradle.template +1 -2
  45. package/src/generators/application/files/app/ios/Podfile.template +8 -6
  46. package/src/generators/application/files/app/ios/__className__/AppDelegate.mm.template +0 -10
  47. package/src/generators/application/files/app/ios/__className__.xcodeproj/project.pbxproj.template +6 -2
  48. package/src/generators/application/files/app/metro.config.js.template +32 -35
  49. package/src/generators/application/files/app/package.json.template +1 -0
  50. package/src/generators/application/files/app/src/app/App.tsx.template +1 -1
  51. package/src/generators/application/files/app/tsconfig.app.json.template +1 -0
  52. package/src/generators/application/files/app/tsconfig.json.template +1 -7
  53. package/src/generators/application/lib/add-project.js +7 -0
  54. package/src/generators/init/init.js +1 -2
  55. package/src/generators/library/library.js +5 -1
  56. package/src/migrations/update-16-6-0/add-depends-on.d.ts +6 -0
  57. package/src/migrations/update-16-6-0/add-depends-on.js +43 -0
  58. package/src/migrations/update-16-6-0/update-metro-config.d.ts +6 -0
  59. package/src/migrations/update-16-6-0/update-metro-config.js +71 -0
  60. package/src/utils/get-cli-options.js +4 -1
  61. package/src/utils/pod-install-task.d.ts +10 -2
  62. package/src/utils/pod-install-task.js +12 -4
  63. package/src/utils/versions.d.ts +10 -9
  64. package/src/utils/versions.js +11 -10
  65. package/src/generators/application/files/app/.ruby-version +0 -1
  66. /package/src/generators/library/files/lib/{package.json__tmpl__ → package.json.template} +0 -0
  67. /package/src/generators/library/files/lib/src/{index.ts__tmpl__ → index.ts.template} +0 -0
  68. /package/src/generators/library/files/lib/{tsconfig.json__tmpl__ → tsconfig.json.template} +0 -0
  69. /package/src/generators/library/files/lib/{tsconfig.lib.json__tmpl__ → tsconfig.lib.json.template} +0 -0
@@ -1,25 +1,16 @@
1
1
  import { ExecutorContext } from '@nx/devkit';
2
- import { join } from 'path';
2
+ import { resolve as pathResolve } from 'path';
3
3
  import { ChildProcess, fork } from 'child_process';
4
4
  import { platform } from 'os';
5
5
 
6
- import { ensureNodeModulesSymlink } from '../../utils/ensure-node-modules-symlink';
7
- import {
8
- displayNewlyAddedDepsMessage,
9
- syncDeps,
10
- } from '../sync-deps/sync-deps.impl';
11
- import { podInstall } from '../../utils/pod-install-task';
12
6
  import { ReactNativeBuildIosOptions } from './schema';
13
- import { runCliStart } from '../start/start.impl';
14
7
  import { getCliOptions } from '../../utils/get-cli-options';
15
8
 
16
9
  export interface ReactNativeBuildIosOutput {
17
10
  success: boolean;
18
11
  }
19
12
 
20
- let childProcess: ChildProcess;
21
-
22
- export default async function* runIosExecutor(
13
+ export default async function* buildIosExecutor(
23
14
  options: ReactNativeBuildIosOptions,
24
15
  context: ExecutorContext
25
16
  ): AsyncGenerator<ReactNativeBuildIosOutput> {
@@ -28,77 +19,48 @@ export default async function* runIosExecutor(
28
19
  }
29
20
  const projectRoot =
30
21
  context.projectsConfigurations.projects[context.projectName].root;
31
- ensureNodeModulesSymlink(context.root, projectRoot);
32
- if (options.sync) {
33
- displayNewlyAddedDepsMessage(
34
- context.projectName,
35
- await syncDeps(
36
- context.projectName,
37
- projectRoot,
38
- context.root,
39
- context.projectGraph
40
- )
41
- );
42
- }
43
-
44
- if (options.install) {
45
- await podInstall(
46
- join(context.root, projectRoot, 'ios'),
47
- options.buildFolder
48
- );
49
- }
50
-
51
- try {
52
- const tasks = [runCliBuildIOS(context.root, projectRoot, options)];
53
- if (options.packager && options.mode !== 'Release') {
54
- tasks.push(
55
- runCliStart(context.root, projectRoot, {
56
- port: options.port,
57
- resetCache: options.resetCache,
58
- interactive: options.interactive,
59
- })
60
- );
61
- }
62
22
 
63
- await Promise.all(tasks);
64
-
65
- yield { success: true };
66
- } finally {
67
- if (childProcess) {
68
- childProcess.kill();
69
- }
70
- }
23
+ await runCliBuildIOS(context.root, projectRoot, options);
24
+ return { success: true };
71
25
  }
72
26
 
73
27
  function runCliBuildIOS(
74
28
  workspaceRoot: string,
75
29
  projectRoot: string,
76
30
  options: ReactNativeBuildIosOptions
77
- ) {
78
- return new Promise((resolve, reject) => {
79
- /**
80
- * Call the react native cli with option `--no-packager`
81
- * Not passing '--packager' due to cli will launch start command from the project root
82
- */
83
- childProcess = fork(
84
- join(workspaceRoot, './node_modules/react-native/cli.js'),
85
- ['build-ios', ...createBuildIOSOptions(options)],
31
+ ): Promise<ChildProcess> {
32
+ return new Promise<ChildProcess>((resolve, reject) => {
33
+ const childProcess = fork(
34
+ require.resolve('react-native/cli.js'),
35
+ [
36
+ 'build-ios',
37
+ ...createBuildIOSOptions(options),
38
+ ...(process.env.NX_VERBOSE_LOGGING === 'true' ? ['--verbose'] : []),
39
+ ],
86
40
  {
87
- cwd: join(workspaceRoot, projectRoot),
41
+ cwd: pathResolve(workspaceRoot, projectRoot),
88
42
  env: { ...process.env, RCT_METRO_PORT: options.port.toString() },
89
43
  }
90
44
  );
91
45
 
92
- // Ensure the child process is killed when the parent exits
93
- process.on('exit', () => childProcess.kill());
94
- process.on('SIGTERM', () => childProcess.kill());
46
+ /**
47
+ * Ensure the child process is killed when the parent exits
48
+ */
49
+ const processExitListener = (signal?: number | NodeJS.Signals) => () => {
50
+ childProcess.kill(signal);
51
+ process.exit();
52
+ };
53
+ process.once('exit', (signal) => childProcess.kill(signal));
54
+ process.once('SIGTERM', processExitListener);
55
+ process.once('SIGINT', processExitListener);
56
+ process.once('SIGQUIT', processExitListener);
95
57
 
96
58
  childProcess.on('error', (err) => {
97
59
  reject(err);
98
60
  });
99
61
  childProcess.on('exit', (code) => {
100
62
  if (code === 0) {
101
- resolve(code);
63
+ resolve(childProcess);
102
64
  } else {
103
65
  reject(code);
104
66
  }
@@ -16,7 +16,10 @@ export interface ReactNativeBuildIosOptions extends ReactNativeStartOptions {
16
16
  extraParams?: string;
17
17
 
18
18
  // nx options
19
+ // @deprecated, no longer used
19
20
  packager: boolean; // default is true
21
+ // @deprecated, add to pod-install to dependsOn
20
22
  install: boolean; // default is true
23
+ // @deprecated, add to sync-deps to dependsOn
21
24
  sync: boolean; // default is true
22
25
  }
@@ -17,10 +17,6 @@
17
17
  {
18
18
  "name": "Build iOS for a device with udid",
19
19
  "keys": ["udid"]
20
- },
21
- {
22
- "name": "Run `pod install` before building iOS app",
23
- "keys": ["install"]
24
20
  }
25
21
  ],
26
22
  "properties": {
@@ -78,17 +74,22 @@
78
74
  "description": "Explicitly select which scheme and configuration to use before running a build"
79
75
  },
80
76
  "extraParams": {
81
- "type": "string",
77
+ "oneOf": [
78
+ { "type": "array", "items": { "type": "string" } },
79
+ { "type": "string" }
80
+ ],
82
81
  "description": "Custom params that will be passed to xcodebuild command."
83
82
  },
84
83
  "install": {
85
84
  "type": "boolean",
86
85
  "description": "Runs `pod install` for native modules before building iOS app.",
86
+ "x-deprecated": "Add pod-install to dependsOn in project.json for this target instead",
87
87
  "default": true
88
88
  },
89
89
  "sync": {
90
90
  "type": "boolean",
91
91
  "description": "Syncs npm dependencies to `package.json` (for React Native autolink).",
92
+ "x-deprecated": "Add sync-deps to dependsOn in project.json for this target instead",
92
93
  "default": true
93
94
  },
94
95
  "resetCache": {
@@ -99,7 +100,8 @@
99
100
  "packager": {
100
101
  "type": "boolean",
101
102
  "description": "Launch packager while building",
102
- "default": true
103
+ "default": true,
104
+ "x-deprecated": "Run `nx run <project>:start` instead. Will be removed in Nx 17."
103
105
  }
104
106
  },
105
107
  "required": [],
@@ -5,39 +5,41 @@ const fileutils_1 = require("@nx/workspace/src/utilities/fileutils");
5
5
  const devkit_1 = require("@nx/devkit");
6
6
  const path_1 = require("path");
7
7
  const child_process_1 = require("child_process");
8
- const ensure_node_modules_symlink_1 = require("../../utils/ensure-node-modules-symlink");
9
- let childProcess;
10
8
  function bundleExecutor(options, context) {
11
9
  return tslib_1.__asyncGenerator(this, arguments, function* bundleExecutor_1() {
12
10
  const projectRoot = context.projectsConfigurations.projects[context.projectName].root;
13
11
  options.bundleOutput = (0, path_1.join)(context.root, options.bundleOutput);
14
12
  (0, fileutils_1.createDirectory)((0, path_1.dirname)(options.bundleOutput));
15
- (0, ensure_node_modules_symlink_1.ensureNodeModulesSymlink)(context.root, projectRoot);
16
- try {
17
- yield tslib_1.__await(runCliBuild(context.root, projectRoot, options));
18
- yield yield tslib_1.__await({ success: true });
19
- }
20
- finally {
21
- if (childProcess) {
22
- childProcess.kill();
23
- }
24
- }
13
+ yield tslib_1.__await(runCliBuild(context.root, projectRoot, options));
14
+ yield yield tslib_1.__await({ success: true });
25
15
  });
26
16
  }
27
17
  exports.default = bundleExecutor;
28
18
  function runCliBuild(workspaceRoot, projectRoot, options) {
29
19
  return new Promise((resolve, reject) => {
30
20
  const cliOptions = createBundleOptions(options);
31
- childProcess = (0, child_process_1.fork)((0, path_1.join)(workspaceRoot, './node_modules/react-native/cli.js'), ['bundle', ...cliOptions], { cwd: (0, path_1.join)(workspaceRoot, projectRoot), env: process.env });
32
- // Ensure the child process is killed when the parent exits
33
- process.on('exit', () => childProcess.kill());
34
- process.on('SIGTERM', () => childProcess.kill());
21
+ const childProcess = (0, child_process_1.fork)(require.resolve('react-native/cli.js'), ['bundle', ...cliOptions], {
22
+ stdio: 'inherit',
23
+ cwd: (0, path_1.resolve)(workspaceRoot, projectRoot),
24
+ env: process.env,
25
+ });
26
+ /**
27
+ * Ensure the child process is killed when the parent exits
28
+ */
29
+ const processExitListener = (signal) => () => {
30
+ childProcess.kill(signal);
31
+ process.exit();
32
+ };
33
+ process.once('exit', (signal) => childProcess.kill(signal));
34
+ process.once('SIGTERM', processExitListener);
35
+ process.once('SIGINT', processExitListener);
36
+ process.once('SIGQUIT', processExitListener);
35
37
  childProcess.on('error', (err) => {
36
38
  reject(err);
37
39
  });
38
40
  childProcess.on('exit', (code) => {
39
41
  if (code === 0) {
40
- resolve(code);
42
+ resolve(childProcess);
41
43
  }
42
44
  else {
43
45
  reject(code);
@@ -1,18 +1,14 @@
1
1
  import { createDirectory } from '@nx/workspace/src/utilities/fileutils';
2
2
  import { names, ExecutorContext } from '@nx/devkit';
3
- import { dirname, join } from 'path';
3
+ import { dirname, join, resolve as pathResolve } from 'path';
4
4
  import { ChildProcess, fork } from 'child_process';
5
5
 
6
- import { ensureNodeModulesSymlink } from '../../utils/ensure-node-modules-symlink';
7
-
8
6
  import { ReactNativeBundleOptions } from './schema';
9
7
 
10
8
  export interface ReactNativeBundleOutput {
11
9
  success: boolean;
12
10
  }
13
11
 
14
- let childProcess: ChildProcess;
15
-
16
12
  export default async function* bundleExecutor(
17
13
  options: ReactNativeBundleOptions,
18
14
  context: ExecutorContext
@@ -23,41 +19,46 @@ export default async function* bundleExecutor(
23
19
  options.bundleOutput = join(context.root, options.bundleOutput);
24
20
 
25
21
  createDirectory(dirname(options.bundleOutput));
26
- ensureNodeModulesSymlink(context.root, projectRoot);
27
22
 
28
- try {
29
- await runCliBuild(context.root, projectRoot, options);
30
- yield { success: true };
31
- } finally {
32
- if (childProcess) {
33
- childProcess.kill();
34
- }
35
- }
23
+ await runCliBuild(context.root, projectRoot, options);
24
+ yield { success: true };
36
25
  }
37
26
 
38
27
  function runCliBuild(
39
28
  workspaceRoot: string,
40
29
  projectRoot: string,
41
30
  options: ReactNativeBundleOptions
42
- ) {
43
- return new Promise((resolve, reject) => {
31
+ ): Promise<ChildProcess> {
32
+ return new Promise<ChildProcess>((resolve, reject) => {
44
33
  const cliOptions = createBundleOptions(options);
45
- childProcess = fork(
46
- join(workspaceRoot, './node_modules/react-native/cli.js'),
34
+ const childProcess = fork(
35
+ require.resolve('react-native/cli.js'),
47
36
  ['bundle', ...cliOptions],
48
- { cwd: join(workspaceRoot, projectRoot), env: process.env }
37
+ {
38
+ stdio: 'inherit',
39
+ cwd: pathResolve(workspaceRoot, projectRoot),
40
+ env: process.env,
41
+ }
49
42
  );
50
43
 
51
- // Ensure the child process is killed when the parent exits
52
- process.on('exit', () => childProcess.kill());
53
- process.on('SIGTERM', () => childProcess.kill());
44
+ /**
45
+ * Ensure the child process is killed when the parent exits
46
+ */
47
+ const processExitListener = (signal?: number | NodeJS.Signals) => () => {
48
+ childProcess.kill(signal);
49
+ process.exit();
50
+ };
51
+ process.once('exit', (signal) => childProcess.kill(signal));
52
+ process.once('SIGTERM', processExitListener);
53
+ process.once('SIGINT', processExitListener);
54
+ process.once('SIGQUIT', processExitListener);
54
55
 
55
56
  childProcess.on('error', (err) => {
56
57
  reject(err);
57
58
  });
58
59
  childProcess.on('exit', (code) => {
59
60
  if (code === 0) {
60
- resolve(code);
61
+ resolve(childProcess);
61
62
  } else {
62
63
  reject(code);
63
64
  }
@@ -7,7 +7,7 @@ function podInstall(options, context) {
7
7
  return tslib_1.__asyncGenerator(this, arguments, function* podInstall_1() {
8
8
  const projectRoot = context.projectsConfigurations.projects[context.projectName].root;
9
9
  const iosDirectory = (0, path_1.join)(context.root, projectRoot, 'ios');
10
- yield tslib_1.__await((0, pod_install_task_1.runPodInstall)(iosDirectory, true, options.buildFolder)());
10
+ yield tslib_1.__await((0, pod_install_task_1.runPodInstall)(iosDirectory, true, options)());
11
11
  yield yield tslib_1.__await({ success: true });
12
12
  });
13
13
  }
@@ -15,7 +15,7 @@ export default async function* podInstall(
15
15
  const projectRoot =
16
16
  context.projectsConfigurations.projects[context.projectName].root;
17
17
  const iosDirectory = join(context.root, projectRoot, 'ios');
18
- await runPodInstall(iosDirectory, true, options.buildFolder)();
18
+ await runPodInstall(iosDirectory, true, options)();
19
19
 
20
20
  yield { success: true };
21
21
  }
@@ -1,3 +1,5 @@
1
1
  export interface ReactNativePodInstallOptions {
2
- buildFolder: string;
2
+ buildFolder: string; // default is './build'
3
+ repoUpdate: boolean; // default is false
4
+ deployment: boolean; // default is false
3
5
  }
@@ -9,9 +9,19 @@
9
9
  "type": "object",
10
10
  "properties": {
11
11
  "buildFolder": {
12
- "description": "Location for iOS build artifacts. Corresponds to Xcode's \"-derivedDataPath\". Relative to ios directory",
12
+ "description": "Location for iOS build artifacts. Corresponds to Xcode's \"-derivedDataPath\". Relative to ios directory.",
13
13
  "type": "string",
14
14
  "default": "./build"
15
+ },
16
+ "repoUpdate": {
17
+ "description": "Force running `pod repo update` before install.",
18
+ "type": "boolean",
19
+ "default": false
20
+ },
21
+ "deployment": {
22
+ "description": "Disallow any changes to the Podfile or the Podfile.lock during installation.",
23
+ "type": "boolean",
24
+ "default": false
15
25
  }
16
26
  },
17
27
  "required": ["buildFolder"]
@@ -3,37 +3,49 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const tslib_1 = require("tslib");
4
4
  const path_1 = require("path");
5
5
  const child_process_1 = require("child_process");
6
- const ensure_node_modules_symlink_1 = require("../../utils/ensure-node-modules-symlink");
7
- const sync_deps_impl_1 = require("../sync-deps/sync-deps.impl");
8
6
  const start_impl_1 = require("../start/start.impl");
9
7
  const chmod_android_gradle_files_1 = require("../../utils/chmod-android-gradle-files");
10
8
  const get_cli_options_1 = require("../../utils/get-cli-options");
11
9
  let childProcess;
12
10
  function runAndroidExecutor(options, context) {
13
11
  return tslib_1.__asyncGenerator(this, arguments, function* runAndroidExecutor_1() {
12
+ var _a, e_1, _b, _c;
14
13
  const projectRoot = context.projectsConfigurations.projects[context.projectName].root;
15
- (0, ensure_node_modules_symlink_1.ensureNodeModulesSymlink)(context.root, projectRoot);
16
14
  (0, chmod_android_gradle_files_1.chmodAndroidGradlewFiles)((0, path_1.join)(projectRoot, 'android'));
17
- if (options.sync) {
18
- (0, sync_deps_impl_1.displayNewlyAddedDepsMessage)(context.projectName, yield tslib_1.__await((0, sync_deps_impl_1.syncDeps)(context.projectName, projectRoot, context.root, context.projectGraph)));
19
- }
20
- try {
21
- const tasks = [runCliRunAndroid(context.root, projectRoot, options)];
22
- if (options.packager) {
23
- tasks.push((0, start_impl_1.runCliStart)(context.root, projectRoot, {
24
- port: options.port,
25
- resetCache: options.resetCache,
26
- interactive: options.interactive,
27
- }));
15
+ if (options.packager && options.mode !== 'Release') {
16
+ const startResults = (0, start_impl_1.default)({
17
+ port: options.port,
18
+ resetCache: options.resetCache,
19
+ interactive: true,
20
+ }, context);
21
+ try {
22
+ for (var _d = true, startResults_1 = tslib_1.__asyncValues(startResults), startResults_1_1; startResults_1_1 = yield tslib_1.__await(startResults_1.next()), _a = startResults_1_1.done, !_a; _d = true) {
23
+ _c = startResults_1_1.value;
24
+ _d = false;
25
+ const result = _c;
26
+ if (result.success) {
27
+ yield tslib_1.__await(runCliRunAndroid(context.root, projectRoot, options));
28
+ yield yield tslib_1.__await({
29
+ success: true,
30
+ });
31
+ }
32
+ else {
33
+ return yield tslib_1.__await(result);
34
+ }
35
+ }
28
36
  }
29
- yield tslib_1.__await(Promise.all(tasks));
30
- yield yield tslib_1.__await({ success: true });
31
- }
32
- finally {
33
- if (childProcess) {
34
- childProcess.kill();
37
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
38
+ finally {
39
+ try {
40
+ if (!_d && !_a && (_b = startResults_1.return)) yield tslib_1.__await(_b.call(startResults_1));
41
+ }
42
+ finally { if (e_1) throw e_1.error; }
35
43
  }
36
44
  }
45
+ else {
46
+ yield tslib_1.__await(runCliRunAndroid(context.root, projectRoot, options));
47
+ }
48
+ yield yield tslib_1.__await({ success: true });
37
49
  });
38
50
  }
39
51
  exports.default = runAndroidExecutor;
@@ -43,19 +55,28 @@ function runCliRunAndroid(workspaceRoot, projectRoot, options) {
43
55
  * Call the react native cli with option `--no-packager`
44
56
  * Not passing '--packager' due to cli will launch start command from the project root
45
57
  */
46
- childProcess = (0, child_process_1.fork)((0, path_1.join)(workspaceRoot, './node_modules/react-native/cli.js'), ['run-android', ...createRunAndroidOptions(options), '--no-packager'], {
47
- cwd: (0, path_1.join)(workspaceRoot, projectRoot),
58
+ childProcess = (0, child_process_1.fork)(require.resolve('react-native/cli.js'), ['run-android', ...createRunAndroidOptions(options), '--no-packager'], {
59
+ stdio: 'inherit',
60
+ cwd: (0, path_1.resolve)(workspaceRoot, projectRoot),
48
61
  env: Object.assign(Object.assign({}, process.env), { RCT_METRO_PORT: options.port.toString() }),
49
62
  });
50
- // Ensure the child process is killed when the parent exits
51
- process.on('exit', () => childProcess.kill());
52
- process.on('SIGTERM', () => childProcess.kill());
63
+ /**
64
+ * Ensure the child process is killed when the parent exits
65
+ */
66
+ const processExitListener = (signal) => () => {
67
+ childProcess.kill(signal);
68
+ process.exit();
69
+ };
70
+ process.once('exit', (signal) => childProcess.kill(signal));
71
+ process.once('SIGTERM', processExitListener);
72
+ process.once('SIGINT', processExitListener);
73
+ process.once('SIGQUIT', processExitListener);
53
74
  childProcess.on('error', (err) => {
54
75
  reject(err);
55
76
  });
56
77
  childProcess.on('exit', (code) => {
57
78
  if (code === 0) {
58
- resolve(code);
79
+ resolve(childProcess);
59
80
  }
60
81
  else {
61
82
  reject(code);
@@ -1,14 +1,9 @@
1
1
  import { ExecutorContext } from '@nx/devkit';
2
- import { join } from 'path';
2
+ import { join, resolve as pathResolve } from 'path';
3
3
  import { ChildProcess, fork } from 'child_process';
4
4
 
5
- import { ensureNodeModulesSymlink } from '../../utils/ensure-node-modules-symlink';
6
- import {
7
- displayNewlyAddedDepsMessage,
8
- syncDeps,
9
- } from '../sync-deps/sync-deps.impl';
10
5
  import { ReactNativeRunAndroidOptions } from './schema';
11
- import { runCliStart } from '../start/start.impl';
6
+ import startExecutor from '../start/start.impl';
12
7
  import { chmodAndroidGradlewFiles } from '../../utils/chmod-android-gradle-files';
13
8
  import { getCliOptions } from '../../utils/get-cli-options';
14
9
 
@@ -24,72 +19,72 @@ export default async function* runAndroidExecutor(
24
19
  ): AsyncGenerator<ReactNativeRunAndroidOutput> {
25
20
  const projectRoot =
26
21
  context.projectsConfigurations.projects[context.projectName].root;
27
- ensureNodeModulesSymlink(context.root, projectRoot);
28
22
  chmodAndroidGradlewFiles(join(projectRoot, 'android'));
29
23
 
30
- if (options.sync) {
31
- displayNewlyAddedDepsMessage(
32
- context.projectName,
33
- await syncDeps(
34
- context.projectName,
35
- projectRoot,
36
- context.root,
37
- context.projectGraph
38
- )
24
+ if (options.packager && options.mode !== 'Release') {
25
+ const startResults = startExecutor(
26
+ {
27
+ port: options.port,
28
+ resetCache: options.resetCache,
29
+ interactive: true,
30
+ },
31
+ context
39
32
  );
40
- }
41
-
42
- try {
43
- const tasks = [runCliRunAndroid(context.root, projectRoot, options)];
44
- if (options.packager) {
45
- tasks.push(
46
- runCliStart(context.root, projectRoot, {
47
- port: options.port,
48
- resetCache: options.resetCache,
49
- interactive: options.interactive,
50
- })
51
- );
52
- }
53
-
54
- await Promise.all(tasks);
55
-
56
- yield { success: true };
57
- } finally {
58
- if (childProcess) {
59
- childProcess.kill();
33
+ for await (const result of startResults) {
34
+ if (result.success) {
35
+ await runCliRunAndroid(context.root, projectRoot, options);
36
+ yield {
37
+ success: true,
38
+ };
39
+ } else {
40
+ return result;
41
+ }
60
42
  }
43
+ } else {
44
+ await runCliRunAndroid(context.root, projectRoot, options);
61
45
  }
46
+
47
+ yield { success: true };
62
48
  }
63
49
 
64
50
  function runCliRunAndroid(
65
51
  workspaceRoot: string,
66
52
  projectRoot: string,
67
53
  options: ReactNativeRunAndroidOptions
68
- ) {
69
- return new Promise((resolve, reject) => {
54
+ ): Promise<ChildProcess> {
55
+ return new Promise<ChildProcess>((resolve, reject) => {
70
56
  /**
71
57
  * Call the react native cli with option `--no-packager`
72
58
  * Not passing '--packager' due to cli will launch start command from the project root
73
59
  */
74
60
  childProcess = fork(
75
- join(workspaceRoot, './node_modules/react-native/cli.js'),
61
+ require.resolve('react-native/cli.js'),
76
62
  ['run-android', ...createRunAndroidOptions(options), '--no-packager'],
77
63
  {
78
- cwd: join(workspaceRoot, projectRoot),
64
+ stdio: 'inherit',
65
+ cwd: pathResolve(workspaceRoot, projectRoot),
79
66
  env: { ...process.env, RCT_METRO_PORT: options.port.toString() },
80
67
  }
81
68
  );
82
69
 
83
- // Ensure the child process is killed when the parent exits
84
- process.on('exit', () => childProcess.kill());
85
- process.on('SIGTERM', () => childProcess.kill());
70
+ /**
71
+ * Ensure the child process is killed when the parent exits
72
+ */
73
+ const processExitListener = (signal?: number | NodeJS.Signals) => () => {
74
+ childProcess.kill(signal);
75
+ process.exit();
76
+ };
77
+ process.once('exit', (signal) => childProcess.kill(signal));
78
+ process.once('SIGTERM', processExitListener);
79
+ process.once('SIGINT', processExitListener);
80
+ process.once('SIGQUIT', processExitListener);
86
81
 
87
82
  childProcess.on('error', (err) => {
88
83
  reject(err);
89
84
  });
90
85
  childProcess.on('exit', (code) => {
91
86
  if (code === 0) {
92
- resolve(code);
87
+ resolve(childProcess);
93
88
  } else {
94
89
  reject(code);
95
90
  }
@@ -5,11 +5,11 @@ import { ReactNativeStartOptions } from '../start/schema';
5
5
  export interface ReactNativeRunAndroidOptions
6
6
  extends ReactNativeBuildAndroidOptions {
7
7
  /**
8
- * @deprecated use mode instead
8
+ * @deprecated TODO(v17) use mode instead
9
9
  */
10
10
  variant: string;
11
11
  /**
12
- * @deprecated no longer supported in react native cli
12
+ * @deprecated TODO(v17) no longer supported in react native cli
13
13
  * https://github.com/react-native-community/cli/commit/7c003f2b1d9d80ec5c167614ba533a004272c685
14
14
  */
15
15
  jetifier: boolean;
@@ -77,10 +77,10 @@
77
77
  "default": 8081
78
78
  },
79
79
  "tasks": {
80
- "type": "array",
81
- "items": {
82
- "type": "string"
83
- },
80
+ "oneOf": [
81
+ { "type": "array", "items": { "type": "string" } },
82
+ { "type": "string" }
83
+ ],
84
84
  "description": "Run custom Gradle tasks. By default it's \"assembleDebug\". Will override passed mode and variant arguments.",
85
85
  "examples": [
86
86
  "assembleDebug",
@@ -97,7 +97,10 @@
97
97
  "default": false
98
98
  },
99
99
  "extraParams": {
100
- "type": "string",
100
+ "oneOf": [
101
+ { "type": "array", "items": { "type": "string" } },
102
+ { "type": "string" }
103
+ ],
101
104
  "description": "Custom params passed to gradle build command"
102
105
  },
103
106
  "interactive": {
@@ -107,6 +110,7 @@
107
110
  "sync": {
108
111
  "type": "boolean",
109
112
  "description": "Syncs npm dependencies to `package.json` (for React Native autolink).",
113
+ "x-deprecated": "Add sync-deps to dependsOn for this target in project.json instead",
110
114
  "default": true
111
115
  },
112
116
  "resetCache": {