diff --git a/e2e/expo/src/expo-legacy.test.ts b/e2e/expo/src/expo-legacy.test.ts index 22bb7167a7b7b..01ccc09b94756 100644 --- a/e2e/expo/src/expo-legacy.test.ts +++ b/e2e/expo/src/expo-legacy.test.ts @@ -146,12 +146,26 @@ describe('@nx/expo (legacy)', () => { it('should install', async () => { // run install command - const installResults = await runCLIAsync( + let installResults = await runCLIAsync( `install ${appName} --no-interactive` ); expect(installResults.combinedOutput).toContain( 'Successfully ran target install' ); + + installResults = await runCLIAsync( + `install ${appName} --packages=@react-native-async-storage/async-storage,react-native-image-picker --no-interactive` + ); + expect(installResults.combinedOutput).toContain( + 'Successfully ran target install' + ); + const packageJson = readJson(join('apps', appName, 'package.json')); + expect(packageJson).toMatchObject({ + dependencies: { + '@react-native-async-storage/async-storage': '*', + 'react-native-image-picker': '*', + }, + }); }); it('should start', async () => { diff --git a/e2e/expo/src/expo.test.ts b/e2e/expo/src/expo.test.ts index 388f5fec1660a..e46ed9ccfc109 100644 --- a/e2e/expo/src/expo.test.ts +++ b/e2e/expo/src/expo.test.ts @@ -112,6 +112,30 @@ describe('@nx/expo', () => { ); }); + it('should install', async () => { + // run install command + let installResults = await runCLIAsync( + `install ${appName} --no-interactive` + ); + expect(installResults.combinedOutput).toContain( + 'Successfully ran target install' + ); + + installResults = await runCLIAsync( + `install ${appName} --packages=@react-native-async-storage/async-storage,react-native-image-picker --no-interactive` + ); + expect(installResults.combinedOutput).toContain( + 'Successfully ran target install' + ); + const packageJson = readJson(join(appName, 'package.json')); + expect(packageJson).toMatchObject({ + dependencies: { + '@react-native-async-storage/async-storage': '*', + 'react-native-image-picker': '*', + }, + }); + }); + it('should run e2e for cypress', async () => { if (runE2ETests()) { const results = runCLI(`e2e ${appName}-e2e`); diff --git a/packages/expo/plugins/plugin.ts b/packages/expo/plugins/plugin.ts index 95939d5c1e71c..70bd15590d8d4 100644 --- a/packages/expo/plugins/plugin.ts +++ b/packages/expo/plugins/plugin.ts @@ -124,8 +124,7 @@ function buildExpoTargets( outputs: [getOutputs(projectRoot, 'dist')], }, [options.installTargetName]: { - command: `expo install`, - options: { cwd: workspaceRoot }, // install at workspace root + executor: '@nx/expo:install', }, [options.prebuildTargetName]: { executor: `@nx/expo:prebuild`, diff --git a/packages/expo/src/executors/install/install.impl.ts b/packages/expo/src/executors/install/install.impl.ts index b78c51bad8629..c180711b7705e 100644 --- a/packages/expo/src/executors/install/install.impl.ts +++ b/packages/expo/src/executors/install/install.impl.ts @@ -1,7 +1,13 @@ import { ExecutorContext, names } from '@nx/devkit'; +import { readJsonFile } from 'nx/src/utils/fileutils'; import { ChildProcess, fork } from 'child_process'; import { ExpoInstallOptions } from './schema'; +import { join } from 'path'; +import { + displayNewlyAddedDepsMessage, + syncDeps, +} from '../sync-deps/sync-deps.impl'; export interface ExpoInstallOutput { success: boolean; @@ -13,12 +19,8 @@ export default async function* installExecutor( options: ExpoInstallOptions, context: ExecutorContext ): AsyncGenerator { - const projectRoot = - context.projectsConfigurations.projects[context.projectName].root; - try { - await installAsync(context.root, options); - + await installAndUpdatePackageJson(context, options); yield { success: true, }; @@ -29,6 +31,40 @@ export default async function* installExecutor( } } +export async function installAndUpdatePackageJson( + context: ExecutorContext, + options: ExpoInstallOptions +) { + await installAsync(context.root, options); + + const projectRoot = + context.projectsConfigurations.projects[context.projectName].root; + const workspacePackageJsonPath = join(context.root, 'package.json'); + const projectPackageJsonPath = join( + context.root, + projectRoot, + 'package.json' + ); + + const workspacePackageJson = readJsonFile(workspacePackageJsonPath); + const projectPackageJson = readJsonFile(projectPackageJsonPath); + const packages = + typeof options.packages === 'string' + ? options.packages.split(',') + : options.packages; + displayNewlyAddedDepsMessage( + context.projectName, + await syncDeps( + context.projectName, + projectPackageJson, + projectPackageJsonPath, + workspacePackageJson, + context.projectGraph, + packages + ) + ); +} + export function installAsync( workspaceRoot: string, options: ExpoInstallOptions diff --git a/packages/expo/src/executors/update/update.impl.ts b/packages/expo/src/executors/update/update.impl.ts index d5efb8a3f444a..3bb069403c07d 100644 --- a/packages/expo/src/executors/update/update.impl.ts +++ b/packages/expo/src/executors/update/update.impl.ts @@ -1,13 +1,9 @@ -import { ExecutorContext, names, readJsonFile } from '@nx/devkit'; -import { join, resolve as pathResolve } from 'path'; +import { ExecutorContext, names } from '@nx/devkit'; +import { resolve as pathResolve } from 'path'; import { ChildProcess, fork } from 'child_process'; import { resolveEas } from '../../utils/resolve-eas'; -import { - displayNewlyAddedDepsMessage, - syncDeps, -} from '../sync-deps/sync-deps.impl'; -import { installAsync } from '../install/install.impl'; +import { installAndUpdatePackageJson } from '../install/install.impl'; import { ExpoEasUpdateOptions } from './schema'; @@ -23,30 +19,11 @@ export default async function* buildExecutor( ): AsyncGenerator { const projectRoot = context.projectsConfigurations.projects[context.projectName].root; - const workspacePackageJsonPath = join(context.root, 'package.json'); - const projectPackageJsonPath = join( - context.root, - projectRoot, - 'package.json' - ); - - const workspacePackageJson = readJsonFile(workspacePackageJsonPath); - const projectPackageJson = readJsonFile(projectPackageJsonPath); - - await installAsync(context.root, { packages: ['expo-updates'] }); - displayNewlyAddedDepsMessage( - context.projectName, - await syncDeps( - context.projectName, - projectPackageJson, - projectPackageJsonPath, - workspacePackageJson, - context.projectGraph, - ['expo-updates'] - ) - ); try { + await installAndUpdatePackageJson(context, { + packages: ['expo-updates'], + }); await runCliUpdate(context.root, projectRoot, options); yield { success: true }; } finally {