From 650072e0294ed2c25dab9ab96e472cd44782af3b Mon Sep 17 00:00:00 2001 From: Emily Xiong Date: Tue, 4 Oct 2022 10:40:47 -0400 Subject: [PATCH] feat(expo): depcrecate expo-cli and use @expo/cli instead --- docs/generated/packages/expo.json | 866 +----------------- docs/generated/packages/react-native.json | 1 + docs/packages.json | 19 +- e2e/expo/src/expo.test.ts | 7 +- packages/expo/executors.json | 30 + packages/expo/migrations.json | 23 + packages/expo/package.json | 4 +- packages/expo/plugins/with-nx-webpack.ts | 2 +- .../build-android/build-android.impl.ts | 12 +- .../src/executors/build-ios/build-ios.impl.ts | 12 +- .../executors/build-list/build-list.impl.ts | 4 +- .../expo/src/executors/build-list/schema.d.ts | 1 + .../expo/src/executors/build-list/schema.json | 4 + .../build-status/build-status.impl.ts | 6 +- .../src/executors/build-web/build-web.impl.ts | 6 +- .../src/executors/download/download.impl.ts | 1 + packages/expo/src/executors/eject/compat.ts | 5 - packages/expo/src/executors/eject/schema.d.ts | 6 - packages/expo/src/executors/eject/schema.json | 23 - packages/expo/src/executors/export/compat.ts | 5 + .../expo/src/executors/export/export.impl.ts | 84 ++ .../expo/src/executors/export/schema.d.ts | 11 + .../expo/src/executors/export/schema.json | 46 + packages/expo/src/executors/install/compat.ts | 5 + .../src/executors/install/install.impl.ts | 81 ++ .../expo/src/executors/install/schema.d.ts | 7 + .../expo/src/executors/install/schema.json | 33 + .../expo/src/executors/prebuild/compat.ts | 5 + .../prebuild.impl.ts} | 34 +- .../expo/src/executors/prebuild/schema.d.ts | 9 + .../expo/src/executors/prebuild/schema.json | 26 + .../executors/publish-set/publish-set.impl.ts | 6 +- .../src/executors/publish/publish.impl.ts | 11 +- .../src/executors/rollback/rollback.impl.ts | 6 +- packages/expo/src/executors/run/run.impl.ts | 25 +- packages/expo/src/executors/run/schema.d.ts | 24 +- packages/expo/src/executors/run/schema.json | 14 +- packages/expo/src/executors/start/schema.d.ts | 16 +- packages/expo/src/executors/start/schema.json | 32 +- .../expo/src/executors/start/start.impl.ts | 18 +- .../expo/src/executors/sync-deps/schema.d.ts | 3 +- .../expo/src/executors/sync-deps/schema.json | 16 +- .../src/executors/sync-deps/sync-deps.impl.ts | 33 +- .../generators/application/lib/add-project.ts | 53 +- packages/expo/src/generators/init/init.ts | 4 +- .../add-eas-update-target.spec.ts | 2 +- .../add-new-expo-cli-targets.spec.ts | 45 + .../update-15-0-3/add-new-expo-cli-targets.ts | 68 ++ packages/expo/src/utils/pod-install-task.ts | 31 +- packages/expo/src/utils/versions.ts | 7 +- .../src/executors/bundle/schema.json | 1 + 51 files changed, 765 insertions(+), 1028 deletions(-) delete mode 100644 packages/expo/src/executors/eject/compat.ts delete mode 100644 packages/expo/src/executors/eject/schema.d.ts delete mode 100644 packages/expo/src/executors/eject/schema.json create mode 100644 packages/expo/src/executors/export/compat.ts create mode 100644 packages/expo/src/executors/export/export.impl.ts create mode 100644 packages/expo/src/executors/export/schema.d.ts create mode 100644 packages/expo/src/executors/export/schema.json create mode 100644 packages/expo/src/executors/install/compat.ts create mode 100644 packages/expo/src/executors/install/install.impl.ts create mode 100644 packages/expo/src/executors/install/schema.d.ts create mode 100644 packages/expo/src/executors/install/schema.json create mode 100644 packages/expo/src/executors/prebuild/compat.ts rename packages/expo/src/executors/{eject/eject.impl.ts => prebuild/prebuild.impl.ts} (60%) create mode 100644 packages/expo/src/executors/prebuild/schema.d.ts create mode 100644 packages/expo/src/executors/prebuild/schema.json create mode 100644 packages/expo/src/migrations/update-15-0-3/add-new-expo-cli-targets.spec.ts create mode 100644 packages/expo/src/migrations/update-15-0-3/add-new-expo-cli-targets.ts diff --git a/docs/generated/packages/expo.json b/docs/generated/packages/expo.json index c30204c524df76..a5603f5c726bfc 100644 --- a/docs/generated/packages/expo.json +++ b/docs/generated/packages/expo.json @@ -325,869 +325,5 @@ "path": "/packages/expo/src/generators/component/schema.json" } ], - "executors": [ - { - "name": "update", - "implementation": "/packages/expo/src/executors/update/update.impl.ts", - "schema": { - "version": 2, - "outputCapture": "direct-nodejs", - "$schema": "http://json-schema.org/schema", - "$id": "NxExpoEasUpdate", - "cli": "nx", - "title": "Expo EAS Update executor", - "description": "Start an EAS update for your expo project", - "type": "object", - "properties": { - "branch": { - "type": "string", - "description": "Branch to publish the update group on" - }, - "message": { - "type": "string", - "description": "A short message describing the update" - }, - "republish": { - "type": "boolean", - "description": "Enable JSON output, non-JSON messages will be printed to stderr", - "default": false - }, - "group": { - "type": "string", - "description": "Update group to republish" - }, - "inputDir": { - "type": "string", - "description": "Location of the bundle" - }, - "skipBundler": { - "type": "boolean", - "description": "Skip running Expo CLI to bundle the app before publishing", - "default": false - }, - "platform": { - "enum": ["ios", "android", "all"], - "alias": "p", - "description": "The platform to build the app, example values: ios, android, all.", - "default": "all" - }, - "json": { - "type": "boolean", - "description": "Enable JSON output, non-JSON messages will be printed to stderr", - "default": false - }, - "auto": { - "type": "boolean", - "description": "Use the current git branch and commit message for the EAS branch and update message", - "default": false - }, - "privateKeyPath": { - "type": "string", - "description": "File containing the PEM-encoded private key corresponding to the certificate in expo-updates' configuration. Defaults to a file named \"private-key.pem\" in the certificate's directory." - }, - "nonInteractive": { - "type": "boolean", - "description": "Run command in non-interactive mode", - "default": false - } - }, - "required": [], - "presets": [] - }, - "description": "Start an EAS update for your expo project", - "aliases": [], - "hidden": false, - "path": "/packages/expo/src/executors/update/schema.json" - }, - { - "name": "build", - "implementation": "/packages/expo/src/executors/build/build.impl.ts", - "schema": { - "version": 2, - "outputCapture": "direct-nodejs", - "$schema": "http://json-schema.org/schema", - "$id": "NxExpoEasBuild", - "cli": "nx", - "title": "Expo EAS Build executor", - "description": "Start an EAS build for your expo project", - "type": "object", - "properties": { - "platform": { - "enum": ["ios", "android", "all"], - "alias": "p", - "description": "The platform to build the app, example values: ios, android, all." - }, - "json": { - "type": "boolean", - "description": "Enable JSON output, non-JSON messages will be printed to stderr", - "default": false - }, - "profile": { - "type": "string", - "description": "Name of the build profile from eas.json. Defaults to \"production\" if defined in eas.json.", - "examples": ["PROFILE_NAME"] - }, - "nonInteractive": { - "type": "boolean", - "description": "Run command in non-interactive mode", - "default": false - }, - "local": { - "type": "boolean", - "description": "Run build locally [experimental]", - "default": false - }, - "wait": { - "type": "boolean", - "description": "Wait for build(s) to complete", - "default": true - }, - "clearCache": { - "type": "boolean", - "description": "Clear cache before the build", - "default": false - }, - "autoSubmit": { - "type": "boolean", - "description": "Submit on build complete using the submit profile with the same name as the build profile", - "default": false - }, - "autoSubmitWithProfile": { - "type": "string", - "description": "Submit on build complete using the submit profile with provided name", - "examples": ["PROFILE_NAME"] - } - }, - "required": [], - "presets": [] - }, - "description": "Start an EAS build for your expo project", - "aliases": [], - "hidden": false, - "path": "/packages/expo/src/executors/build/schema.json" - }, - { - "name": "build-list", - "implementation": "/packages/expo/src/executors/build-list/build-list.impl.ts", - "schema": { - "version": 2, - "outputCapture": "direct-nodejs", - "$schema": "http://json-schema.org/schema", - "$id": "NxExpoEasBuildList", - "cli": "nx", - "title": "Expo EAS Build List executor", - "description": "List all EAS builds for your Expo project", - "type": "object", - "properties": { - "platform": { - "enum": ["ios", "android", "all"], - "alias": "p", - "description": "The platform to build the app, example values: ios, android, all." - }, - "json": { - "type": "boolean", - "description": "Enable JSON output, non-JSON messages will be printed to stderr" - }, - "status": { - "enum": [ - "new", - "in-queue", - "in-progress", - "errored", - "finished", - "canceled" - ], - "description": "Status of EAS build" - }, - "distribution": { - "enum": ["store", "internal", "simulator"], - "description": "Distribution of EAS build" - }, - "channel": { - "type": "string", - "description": "Channel of EAS build" - }, - "appVersion": { - "type": "string", - "description": "App version of EAS build" - }, - "appBuildVersion": { - "type": "string", - "description": "App build version of EAS build" - }, - "sdkVersion": { - "type": "string", - "description": "SDK version of EAS build" - }, - "runtimeVersion": { - "type": "string", - "description": "Runtime version of EAS build" - }, - "appIdentifier": { - "type": "string", - "description": "App identifier of EAS build" - }, - "buildProfile": { - "type": "string", - "description": "Build profile of EAS build" - }, - "gitCommitHash": { - "type": "string", - "description": "Git commit hash of EAS build" - }, - "limit": { - "type": "number", - "description": "Limit of numbers to list EAS builds" - } - }, - "required": [], - "presets": [] - }, - "description": "List all EAS builds for your Expo project", - "aliases": [], - "hidden": false, - "path": "/packages/expo/src/executors/build-list/schema.json" - }, - { - "name": "download", - "implementation": "/packages/expo/src/executors/download/download.impl.ts", - "schema": { - "version": 2, - "outputCapture": "direct-nodejs", - "$schema": "http://json-schema.org/schema", - "$id": "NxExpoDownloadEasBuild", - "cli": "nx", - "title": "Download EAS Build executor", - "description": "Download an EAS build", - "type": "object", - "properties": { - "platform": { - "enum": ["ios", "android"], - "alias": "p", - "description": "The platform to build the app, example values: ios, android, all." - }, - "distribution": { - "enum": ["store", "internal", "simulator"], - "description": "Distribution of EAS build" - }, - "channel": { - "type": "string", - "description": "Channel of EAS build" - }, - "appVersion": { - "type": "string", - "description": "App version of EAS build" - }, - "appBuildVersion": { - "type": "string", - "description": "App build version of EAS build" - }, - "sdkVersion": { - "type": "string", - "description": "SDK version of EAS build" - }, - "runtimeVersion": { - "type": "string", - "description": "Runtime version of EAS build" - }, - "appIdentifier": { - "type": "string", - "description": "App identifier of EAS build" - }, - "buildProfile": { - "type": "string", - "description": "Build profile of EAS build" - }, - "gitCommitHash": { - "type": "string", - "description": "Git commit hash of EAS build" - }, - "output": { - "type": "string", - "description": "Output directory for the download build" - } - }, - "required": ["output"], - "presets": [] - }, - "description": "Download an EAS build", - "aliases": [], - "hidden": false, - "path": "/packages/expo/src/executors/download/schema.json" - }, - { - "name": "build-ios", - "implementation": "/packages/expo/src/executors/build-ios/build-ios.impl.ts", - "schema": { - "version": 2, - "outputCapture": "direct-nodejs", - "$schema": "http://json-schema.org/schema", - "$id": "NxExpoBuildIOS", - "cli": "nx", - "title": "Expo iOS Build executor", - "description": "Build and sign a standalone IPA for the Apple App Store", - "type": "object", - "properties": { - "clearCredentials": { - "type": "boolean", - "description": "Clear all credentials stored on Expo servers.", - "alias": "c" - }, - "clearDistCert": { - "type": "boolean", - "description": "Remove Distribution Certificate stored on Expo servers." - }, - "clearPushKey": { - "type": "boolean", - "description": "Remove Push Notifications Key stored on Expo servers." - }, - "clearPushCert": { - "type": "boolean", - "description": "Remove Push Notifications Certificate stored on Expo servers. Use of Push Notifications Certificates is deprecated." - }, - "clearProvisioningProfile": { - "type": "boolean", - "description": "Remove Provisioning Profile stored on Expo servers." - }, - "revokeCredentials": { - "type": "boolean", - "description": "Revoke credentials on developer.apple.com, select appropriate using --clear-* options.", - "alias": "r" - }, - "appleId": { - "type": "string", - "description": "Apple ID username (please also set the Apple ID password as EXPO_APPLE_PASSWORD environment variable)." - }, - "type": { - "enum": ["archive", "simulator"], - "description": "Type of build: [archive⎮simulator].", - "alias": "t" - }, - "releaseChannel": { - "type": "string", - "description": "Pull from specified release channel." - }, - "noPublish": { - "type": "boolean", - "description": "Disable automatic publishing before building." - }, - "noWait": { - "type": "boolean", - "description": "Exit immediately after scheduling build." - }, - "teamId": { "type": "string", "description": "Apple Team ID." }, - "distP12Path": { - "type": "string", - "description": "Path to your Distribution Certificate P12 (set password as EXPO_IOS_DIST_P12_PASSWORD environment variable)." - }, - "pushP8Path": { - "type": "string", - "description": "Path to your Push Key .p8 file." - }, - "provisioningProfilePath": { - "type": "string", - "description": "Path to your Provisioning Profile." - }, - "publicUrl": { - "type": "string", - "description": "The URL of an externally hosted manifest (for self-hosted apps)." - }, - "skipCredentialsCheck": { - "type": "boolean", - "description": "Skip checking credentials." - }, - "skipWorkflowCheck": { - "type": "boolean", - "description": "Skip warning about build service bare workflow limitations." - }, - "sync": { - "type": "boolean", - "description": "Syncs npm dependencies to package.json (for React Native autolink). Always true when --install is used.", - "default": true - } - }, - "required": [], - "presets": [] - }, - "description": "Build and sign a standalone IPA for the Apple App Store", - "aliases": [], - "hidden": false, - "path": "/packages/expo/src/executors/build-ios/schema.json" - }, - { - "name": "build-android", - "implementation": "/packages/expo/src/executors/build-android/build-android.impl.ts", - "schema": { - "version": 2, - "outputCapture": "direct-nodejs", - "$schema": "http://json-schema.org/schema", - "$id": "NxExpoBuildAndroid", - "cli": "nx", - "title": "Expo Android Build executor", - "description": "Build and sign a standalone APK or App Bundle for the Google Play Store", - "type": "object", - "properties": { - "clearCredentials": { - "type": "boolean", - "description": "Clear all credentials stored on Expo servers.", - "alias": "c" - }, - "type": { - "enum": ["app-bundle", "apk"], - "description": "Type of build: [app-bundle⎮apk].", - "alias": "t" - }, - "releaseChannel": { - "type": "string", - "description": "Pull from specified release channel." - }, - "noPublish": { - "type": "boolean", - "description": "Disable automatic publishing before building." - }, - "noWait": { - "type": "boolean", - "description": "Exit immediately after scheduling build." - }, - "keystorePath": { - "type": "string", - "description": "Path to your Keystore: *.jks." - }, - "keystoreAlias": { - "type": "string", - "description": "Keystore Alias" - }, - "publicUrl": { - "type": "string", - "description": "The URL of an externally hosted manifest (for self-hosted apps)." - }, - "skipWorkflowCheck": { - "type": "boolean", - "description": "Skip warning about build service bare workflow limitations." - }, - "sync": { - "type": "boolean", - "description": "Syncs npm dependencies to package.json (for React Native autolink). Always true when --install is used.", - "default": true - } - }, - "required": [], - "presets": [] - }, - "description": "Build and sign a standalone APK or App Bundle for the Google Play Store", - "aliases": [], - "hidden": false, - "path": "/packages/expo/src/executors/build-android/schema.json" - }, - { - "name": "build-web", - "implementation": "/packages/expo/src/executors/build-web/build-web.impl.ts", - "schema": { - "version": 2, - "outputCapture": "direct-nodejs", - "$schema": "http://json-schema.org/schema", - "$id": "NxExpoBuildWeb", - "cli": "nx", - "title": "Expo web Build executor", - "description": "Build the web app for production", - "type": "object", - "properties": { - "clear": { - "type": "boolean", - "description": "Clear all cached build files and assets.", - "alias": "c" - }, - "noPwa": { - "type": "boolean", - "description": "Prevent webpack from generating the manifest.json and injecting meta into the index.html head." - }, - "dev": { - "type": "boolean", - "description": "Turns dev flag on before bundling" - } - }, - "required": [], - "presets": [] - }, - "description": "Build the web app for production", - "aliases": [], - "hidden": false, - "path": "/packages/expo/src/executors/build-web/schema.json" - }, - { - "name": "build-status", - "implementation": "/packages/expo/src/executors/build-status/build-status.impl.ts", - "schema": { - "version": 2, - "outputCapture": "direct-nodejs", - "$schema": "http://json-schema.org/schema", - "$id": "NxExpoBuildStatus", - "cli": "nx", - "title": "Expo web Build executor", - "description": "Get the status of the latest build for the project", - "type": "object", - "properties": { - "publicUrl": { - "type": "string", - "description": "The URL of an externally hosted manifest (for self-hosted apps)." - } - }, - "required": [], - "presets": [] - }, - "description": "Get the status of the latest build for the project", - "aliases": [], - "hidden": false, - "path": "/packages/expo/src/executors/build-status/schema.json" - }, - { - "name": "publish", - "implementation": "/packages/expo/src/executors/publish/publish.impl.ts", - "schema": { - "version": 2, - "outputCapture": "direct-nodejs", - "cli": "nx", - "$id": "NxExpoPublish", - "$schema": "http://json-schema.org/schema", - "title": "Publish for Expo", - "description": "Deploy a project to Expo hosting", - "type": "object", - "properties": { - "quiet": { - "type": "boolean", - "description": "Suppress verbose output from the Metro bundler", - "default": false, - "alias": "q" - }, - "sendTo": { - "type": "string", - "description": "A phone number or email address to send a link to", - "alias": "s" - }, - "clear": { - "type": "boolean", - "description": "Clear the Metro bundler cache", - "default": false, - "alias": "c" - }, - "target": { - "enum": ["managed", "bare"], - "default": "managed", - "description": "Target environment for which this publish is intended. Options are managed or bare.", - "alias": "t" - }, - "maxWorkers": { - "type": "number", - "description": "Maximum number of tasks to allow Metro to spawn" - }, - "releaseChannel": { - "type": "string", - "description": "The release channel to publish to. Default is 'default'.", - "default": "default" - } - }, - "presets": [] - }, - "description": "Deploy a project to Expo hosting", - "aliases": [], - "hidden": false, - "path": "/packages/expo/src/executors/publish/schema.json" - }, - { - "name": "publish-set", - "implementation": "/packages/expo/src/executors/publish-set/publish-set.impl.ts", - "schema": { - "version": 2, - "outputCapture": "direct-nodejs", - "cli": "nx", - "$id": "NxExpoPublishSet", - "$schema": "http://json-schema.org/schema", - "title": "Set Publish Channel for Expo", - "description": "Specify the channel to serve a published release", - "type": "object", - "properties": { - "releaseChannel": { - "type": "string", - "description": "The release channel to publish to." - }, - "publishId": { - "type": "string", - "description": "The id of the published release to serve from the channel." - } - }, - "required": ["releaseChannel", "publishId"], - "presets": [] - }, - "description": "Specify the channel to serve a published release", - "aliases": [], - "hidden": false, - "path": "/packages/expo/src/executors/publish-set/schema.json" - }, - { - "name": "rollback", - "implementation": "/packages/expo/src/executors/rollback/rollback.impl.ts", - "schema": { - "version": 2, - "outputCapture": "direct-nodejs", - "cli": "nx", - "$id": "NxExpoRollback", - "$schema": "http://json-schema.org/schema", - "title": "Rollback Publish Command for Expo", - "description": "Undo an update to a channel", - "type": "object", - "properties": { - "releaseChannel": { - "type": "string", - "description": "The release channel to publish to." - }, - "sdkVersion": { - "type": "string", - "description": "The sdk version to rollback." - }, - "platform": { - "enum": ["ios", "android"], - "description": "The platform to rollback." - } - }, - "required": ["releaseChannel", "sdkVersion"], - "presets": [] - }, - "description": "Undo an update to a channel", - "aliases": [], - "hidden": false, - "path": "/packages/expo/src/executors/rollback/schema.json" - }, - { - "name": "run", - "implementation": "/packages/expo/src/executors/run/run.impl.ts", - "schema": { - "version": 2, - "outputCapture": "direct-nodejs", - "cli": "nx", - "$id": "NxExpoRun", - "$schema": "http://json-schema.org/schema", - "title": "Run iOS or Android application", - "description": "Run Expo target options", - "type": "object", - "properties": { - "platform": { - "description": "Platform to run for (ios, android).", - "enum": ["ios", "android"], - "default": "ios" - }, - "xcodeConfiguration": { - "type": "string", - "description": "(iOS) Xcode configuration to use. Debug or Release", - "default": "Debug" - }, - "scheme": { - "type": "string", - "description": "(iOS) Explicitly set the Xcode scheme to use" - }, - "variant": { - "type": "string", - "description": "(Android) Specify your app's build variant (e.g. debug, release).", - "default": "debug" - }, - "device": { - "type": "string", - "description": "Device name or UDID to build the app on. The value is not required if you have a single device connected.", - "alias": "d" - }, - "sync": { - "type": "boolean", - "description": "Syncs npm dependencies to package.json (for React Native autolink). Always true when --install is used.", - "default": true - }, - "port": { - "type": "number", - "description": "Port to start the Metro bundler on", - "default": 8081, - "alias": "p" - }, - "bundler": { - "type": "boolean", - "description": "Whether to skip starting the Metro bundler. True to start it, false to skip it.", - "default": true - } - }, - "required": ["platform"], - "presets": [] - }, - "description": "Run the Android app binary locally or run the iOS app binary locally", - "aliases": [], - "hidden": false, - "path": "/packages/expo/src/executors/run/schema.json" - }, - { - "name": "start", - "implementation": "/packages/expo/src/executors/start/start.impl.ts", - "schema": { - "version": 2, - "outputCapture": "direct-nodejs", - "cli": "nx", - "$id": "NxExpoStart", - "$schema": "http://json-schema.org/schema", - "title": "Packager Server for Expo", - "description": "Packager Server target options", - "type": "object", - "properties": { - "port": { - "type": "number", - "description": "Port to start the native Metro bundler on (does not apply to web or tunnel)", - "default": 19000, - "alias": "p" - }, - "clear": { - "type": "boolean", - "description": "Clear the Metro bundler cache", - "alias": "c" - }, - "maxWorkers": { - "type": "number", - "description": "Maximum number of tasks to allow Metro to spawn" - }, - "dev": { - "type": "boolean", - "description": "Turn development mode on or off" - }, - "devClient": { - "type": "boolean", - "description": "Experimental: Starts the bundler for use with the expo-development-client" - }, - "minify": { - "type": "boolean", - "description": "Whether or not to minify code" - }, - "https": { - "type": "boolean", - "description": "To start webpack with https or http protocol" - }, - "scheme": { - "type": "string", - "description": "Custom URI protocol to use with a development build" - }, - "sentTo": { - "type": "string", - "description": "An email address to send a link to", - "alias": "s" - }, - "android": { - "type": "boolean", - "description": "Opens your app in Expo Go on a connected Android device", - "alias": "a" - }, - "ios": { - "type": "boolean", - "description": "Opens your app in Expo Go in a currently running iOS simulator on your computer", - "alias": "i" - }, - "host": { - "type": "string", - "description": "lan (default), tunnel, localhost. Type of host to use. \"tunnel\" allows you to view your link on other networks", - "alias": "m" - }, - "tunnel": { - "type": "boolean", - "description": "Same as --host tunnel" - }, - "lan": { "type": "boolean", "description": "Same as --host lan" }, - "localhost": { - "type": "boolean", - "description": "Same as --host localhost" - }, - "offline": { - "type": "boolean", - "description": "Allows this command to run while offline" - }, - "webpack": { - "type": "boolean", - "description": "Start a Webpack dev server for the web app." - } - }, - "presets": [] - }, - "description": "Start a local dev server for the app or start a Webpack dev server for the web app", - "aliases": [], - "hidden": false, - "path": "/packages/expo/src/executors/start/schema.json" - }, - { - "name": "sync-deps", - "implementation": "/packages/expo/src/executors/sync-deps/sync-deps.impl.ts", - "schema": { - "version": 2, - "outputCapture": "direct-nodejs", - "cli": "nx", - "$id": "NxExpoSyncDeps", - "$schema": "http://json-schema.org/schema", - "title": "Sync Deps for Expo", - "description": "Updates package.json with project dependencies", - "type": "object", - "properties": { - "include": { - "type": "string", - "description": "A comma-separated list of additional npm packages to include. e.g. 'nx sync-deps --include=react-native-gesture-handler,react-native-safe-area-context'" - } - }, - "presets": [] - }, - "description": "Syncs dependencies to package.json (required for autolinking).", - "aliases": [], - "hidden": false, - "path": "/packages/expo/src/executors/sync-deps/schema.json" - }, - { - "name": "ensure-symlink", - "implementation": "/packages/expo/src/executors/ensure-symlink/ensure-symlink.impl.ts", - "schema": { - "version": 2, - "outputCapture": "direct-nodejs", - "cli": "nx", - "$id": "NxExpoEnsureSymlink", - "$schema": "http://json-schema.org/schema", - "title": "Ensure Symlink for Expo", - "description": "Ensure workspace node_modules is symlink under app's node_modules folder.", - "type": "object", - "properties": {}, - "presets": [] - }, - "description": "Ensure workspace node_modules is symlink under app's node_modules folder.", - "aliases": [], - "hidden": false, - "path": "/packages/expo/src/executors/ensure-symlink/schema.json" - }, - { - "name": "eject", - "implementation": "/packages/expo/src/executors/eject/eject.impl.ts", - "schema": { - "version": 2, - "outputCapture": "direct-nodejs", - "cli": "nx", - "$id": "NxExpoEject", - "$schema": "http://json-schema.org/schema", - "title": "Expo Eject", - "description": "Create native iOS and Android project files", - "type": "object", - "properties": { - "install": { - "type": "boolean", - "description": "Install CocoaPods.", - "default": true - }, - "platform": { - "type": "string", - "description": "Platforms to sync", - "default": "all", - "examples": ["ios", "android", "all"] - } - }, - "presets": [] - }, - "description": "Create native iOS and Android project files.", - "aliases": [], - "hidden": false, - "path": "/packages/expo/src/executors/eject/schema.json" - } - ] + "executors": [] } diff --git a/docs/generated/packages/react-native.json b/docs/generated/packages/react-native.json index cd9798ba7610c9..0dcec68b6749d4 100644 --- a/docs/generated/packages/react-native.json +++ b/docs/generated/packages/react-native.json @@ -725,6 +725,7 @@ }, "platform": { "enum": ["ios", "android"], + "alias": "p", "description": "Platform to build for." }, "transformer": { diff --git a/docs/packages.json b/docs/packages.json index ec475fcaf6bd17..68f9f7701b8263 100644 --- a/docs/packages.json +++ b/docs/packages.json @@ -133,24 +133,7 @@ "description": "The Expo Plugin for Nx contains executors and generators for managing and developing an expo application within your workspace. For example, you can directly build for different target platforms as well as generate projects and publish your code.", "path": "generated/packages/expo.json", "schemas": { - "executors": [ - "update", - "build", - "build-list", - "download", - "build-ios", - "build-android", - "build-web", - "build-status", - "publish", - "publish-set", - "rollback", - "run", - "start", - "sync-deps", - "ensure-symlink", - "eject" - ], + "executors": [], "generators": ["init", "application", "library", "component"] } }, diff --git a/e2e/expo/src/expo.test.ts b/e2e/expo/src/expo.test.ts index e1cc236b3df5fc..d48c40c35f2f81 100644 --- a/e2e/expo/src/expo.test.ts +++ b/e2e/expo/src/expo.test.ts @@ -16,7 +16,7 @@ describe('expo', () => { ); afterEach(() => cleanupProject()); - it('should test, lint', async () => { + it('should test, lint and export', async () => { const appName = uniq('my-app'); const libName = uniq('lib'); const componentName = uniq('component'); @@ -41,5 +41,10 @@ describe('expo', () => { const libLintResults = await runCLIAsync(`lint ${libName}`); expect(libLintResults.combinedOutput).toContain('All files pass linting.'); + + const exportResults = await runCLIAsync(`export ${appName}`); + expect(exportResults.combinedOutput).toContain( + 'Export was successful. Your exported files can be found' + ); }, 1000000); }); diff --git a/packages/expo/executors.json b/packages/expo/executors.json index 9c4c9b93c3ce10..1b6d97ccbe7dfb 100644 --- a/packages/expo/executors.json +++ b/packages/expo/executors.json @@ -79,6 +79,21 @@ "implementation": "./src/executors/eject/eject.impl", "schema": "./src/executors/eject/schema.json", "description": "Create native iOS and Android project files." + }, + "prebuild": { + "implementation": "./src/executors/prebuild/prebuild.impl", + "schema": "./src/executors/prebuild/schema.json", + "description": "Create native iOS and Android project files for building natively." + }, + "install": { + "implementation": "./src/executors/install/install.impl", + "schema": "./src/executors/install/schema.json", + "description": "Install a module or other package to a project." + }, + "export": { + "implementation": "./src/executors/export/export.impl", + "schema": "./src/executors/export/schema.json", + "description": "Export the JavaScript and assets for your app using Metro/webpack bundler" } }, "builders": { @@ -161,6 +176,21 @@ "implementation": "./src/executors/eject/compat", "schema": "./src/executors/eject/schema.json", "description": "Create native iOS and Android project files." + }, + "prebuild": { + "implementation": "./src/executors/prebuild/compat", + "schema": "./src/executors/prebuild/schema.json", + "description": "Create native iOS and Android project files for building natively." + }, + "install": { + "implementation": "./src/executors/install/compat", + "schema": "./src/executors/install/schema.json", + "description": "Install a module or other package to a project." + }, + "export": { + "implementation": "./src/executors/export/compat", + "schema": "./src/executors/export/schema.json", + "description": "Export the JavaScript and assets for your app using Metro/webpack bundler" } } } diff --git a/packages/expo/migrations.json b/packages/expo/migrations.json index 4490c7536a1796..871208417ede27 100644 --- a/packages/expo/migrations.json +++ b/packages/expo/migrations.json @@ -29,6 +29,12 @@ "cli": "nx", "description": "Change jest config preset tof expo projects", "factory": "./src/migrations/update-15-0-3/change-jest-preset" + }, + "add-new-expo-cli-targets": { + "version": "15.0.3-beta.0", + "cli": "nx", + "description": "Add targets for @expo/cli and replace eject target", + "factory": "./src/migrations/update-15-0-3/add-new-expo-cli-targets" } }, "packageJsonUpdates": { @@ -456,6 +462,23 @@ "@testing-library/jest-native": { "version": "5.0.0", "alwaysAddToPackageJson": false + }, + "expo": { + "version": "46.0.16", + "alwaysAddToPackageJson": false + }, + "expo-cli": { + "version": "6.0.6", + "alwaysAddToPackageJson": false + }, + "eas-cli": { + "version": "2.4.1", + "alwaysAddToPackageJson": false + }, + "@expo/cli": { + "version": "0.3.2", + "alwaysAddToPackageJson": false, + "addToPackageJson": "devDependencies" } } } diff --git a/packages/expo/package.json b/packages/expo/package.json index 3d7291e7ab0e87..6e4d80c67eb4e5 100644 --- a/packages/expo/package.json +++ b/packages/expo/package.json @@ -31,7 +31,7 @@ "@nrwl/jest": "file:../jest", "@nrwl/linter": "file:../linter", "@nrwl/react": "file:../react", - "@nrwl/web": "file:../web", + "@nrwl/webpack": "file:../webpack", "@nrwl/workspace": "file:../workspace", "@svgr/webpack": "^6.1.2", "chalk": "^4.1.0", @@ -44,7 +44,7 @@ "tsconfig-paths-webpack-plugin": "^3.5.2" }, "peerDependencies": { - "expo": "^46.0.13" + "expo": "^46.0.16" }, "builders": "./executors.json", "ng-update": { diff --git a/packages/expo/plugins/with-nx-webpack.ts b/packages/expo/plugins/with-nx-webpack.ts index d609fa4c1faaa6..445d01506458e7 100644 --- a/packages/expo/plugins/with-nx-webpack.ts +++ b/packages/expo/plugins/with-nx-webpack.ts @@ -12,7 +12,7 @@ export async function withNxWebpack(config) { test: /\.(mjs|[jt]sx?)$/, exclude: /node_modules/, use: { - loader: require.resolve('@nrwl/web/src/utils/web-babel-loader.js'), + loader: require.resolve('@nrwl/webpack/src/utils/web-babel-loader.js'), options: { presets: [ [ diff --git a/packages/expo/src/executors/build-android/build-android.impl.ts b/packages/expo/src/executors/build-android/build-android.impl.ts index c84e66a8e78614..71610e87ea6b9c 100644 --- a/packages/expo/src/executors/build-android/build-android.impl.ts +++ b/packages/expo/src/executors/build-android/build-android.impl.ts @@ -1,4 +1,4 @@ -import { ExecutorContext, names } from '@nrwl/devkit'; +import { ExecutorContext, logger, names } from '@nrwl/devkit'; import { join } from 'path'; import { ChildProcess, fork } from 'child_process'; @@ -20,12 +20,20 @@ export default async function* buildAndroidExecutor( options: ExpoBuildAndroidOptions, context: ExecutorContext ): AsyncGenerator { + logger.warn( + '@nrwl/expo:build-android is deprecated and will be removed in Nx 16. Please switch to expo:prebuild and expo:build.' + ); const projectRoot = context.workspace.projects[context.projectName].root; ensureNodeModulesSymlink(context.root, projectRoot); if (options.sync) { displayNewlyAddedDepsMessage( context.projectName, - await syncDeps(context.projectName, projectRoot) + await syncDeps( + context.projectName, + projectRoot, + context.root, + context.projectGraph + ) ); } diff --git a/packages/expo/src/executors/build-ios/build-ios.impl.ts b/packages/expo/src/executors/build-ios/build-ios.impl.ts index e0aa01f0cbd5b6..3fc722b99e26e6 100644 --- a/packages/expo/src/executors/build-ios/build-ios.impl.ts +++ b/packages/expo/src/executors/build-ios/build-ios.impl.ts @@ -1,4 +1,4 @@ -import { ExecutorContext, names } from '@nrwl/devkit'; +import { ExecutorContext, logger, names } from '@nrwl/devkit'; import { join } from 'path'; import { ChildProcess, fork } from 'child_process'; @@ -19,12 +19,20 @@ export default async function* buildIosExecutor( options: ExpoBuildIOSOptions, context: ExecutorContext ): AsyncGenerator { + logger.warn( + '@nrwl/expo:build-status is deprecated and will be removed in Nx 16. Please switch to expo:prebuild and expo:build.' + ); const projectRoot = context.workspace.projects[context.projectName].root; ensureNodeModulesSymlink(context.root, projectRoot); if (options.sync) { displayNewlyAddedDepsMessage( context.projectName, - await syncDeps(context.projectName, projectRoot) + await syncDeps( + context.projectName, + projectRoot, + context.root, + context.projectGraph + ) ); } diff --git a/packages/expo/src/executors/build-list/build-list.impl.ts b/packages/expo/src/executors/build-list/build-list.impl.ts index 9bfb4a953206a9..480f8c78930600 100644 --- a/packages/expo/src/executors/build-list/build-list.impl.ts +++ b/packages/expo/src/executors/build-list/build-list.impl.ts @@ -39,7 +39,9 @@ function createBuildListOptions(options: ExpoEasBuildListOptions): string[] { return Object.keys(options).reduce((acc, k) => { const v = options[k]; if (!nxOptions.includes(k)) { - if (typeof v === 'boolean') { + if (k === 'nonInteractive') { + acc.push(`--non-interactive`); + } else if (typeof v === 'boolean') { if (v === true) { // when true, does not need to pass the value true, just need to pass the flag in camel case acc.push(`--${names(k).propertyName}`); diff --git a/packages/expo/src/executors/build-list/schema.d.ts b/packages/expo/src/executors/build-list/schema.d.ts index 1d1d688b7f4cdb..6eeb17a441efa6 100644 --- a/packages/expo/src/executors/build-list/schema.d.ts +++ b/packages/expo/src/executors/build-list/schema.d.ts @@ -2,6 +2,7 @@ // options from https://github.com/expo/eas-cli/blob/main/packages/eas-cli/src/commands/build/list.ts export interface ExpoEasBuildListOptions { platform: 'ios' | 'android' | 'all'; + nonInteractive?: boolean; json?: boolean; // status and distribution enum from https://github.com/expo/eas-cli/blob/main/packages/eas-cli/src/build/types.ts status?: diff --git a/packages/expo/src/executors/build-list/schema.json b/packages/expo/src/executors/build-list/schema.json index e3b172acc9cc8a..0879a8a790e4c2 100644 --- a/packages/expo/src/executors/build-list/schema.json +++ b/packages/expo/src/executors/build-list/schema.json @@ -17,6 +17,10 @@ "type": "boolean", "description": "Enable JSON output, non-JSON messages will be printed to stderr" }, + "nonInteractive": { + "type": "boolean", + "description": "Run the command in non-interactive mode." + }, "status": { "enum": [ "new", diff --git a/packages/expo/src/executors/build-status/build-status.impl.ts b/packages/expo/src/executors/build-status/build-status.impl.ts index 784d0019545907..6ca0b08d633be2 100644 --- a/packages/expo/src/executors/build-status/build-status.impl.ts +++ b/packages/expo/src/executors/build-status/build-status.impl.ts @@ -1,4 +1,4 @@ -import { ExecutorContext, names } from '@nrwl/devkit'; +import { ExecutorContext, logger, names } from '@nrwl/devkit'; import { join } from 'path'; import { ChildProcess, fork } from 'child_process'; @@ -16,6 +16,10 @@ export default async function* buildStatusExecutor( options: ExpoBuildStatusOptions, context: ExecutorContext ): AsyncGenerator { + logger.warn( + '@nrwl/expo:build-status is deprecated and will be removed in Nx 16. Please switch to expo:build-list.' + ); + const projectRoot = context.workspace.projects[context.projectName].root; ensureNodeModulesSymlink(context.root, projectRoot); diff --git a/packages/expo/src/executors/build-web/build-web.impl.ts b/packages/expo/src/executors/build-web/build-web.impl.ts index 428b77c2c34a49..0bdd4e298103d2 100644 --- a/packages/expo/src/executors/build-web/build-web.impl.ts +++ b/packages/expo/src/executors/build-web/build-web.impl.ts @@ -1,4 +1,4 @@ -import { ExecutorContext, names } from '@nrwl/devkit'; +import { ExecutorContext, logger, names } from '@nrwl/devkit'; import { join } from 'path'; import { ChildProcess, fork } from 'child_process'; @@ -16,6 +16,10 @@ export default async function* buildWebExecutor( options: ExpoBuildWebOptions, context: ExecutorContext ): AsyncGenerator { + logger.warn( + '@nrwl/expo:build-web is deprecated and will be removed in Nx 16. Please switch to expo:export --bundler webpack.' + ); + const projectRoot = context.workspace.projects[context.projectName].root; ensureNodeModulesSymlink(context.root, projectRoot); diff --git a/packages/expo/src/executors/download/download.impl.ts b/packages/expo/src/executors/download/download.impl.ts index 368705deb318c2..687db05f99186b 100644 --- a/packages/expo/src/executors/download/download.impl.ts +++ b/packages/expo/src/executors/download/download.impl.ts @@ -83,6 +83,7 @@ export function getBuild( ) { const buildList = runCliBuildList(workspaceRoot, projectRoot, { ...options, + nonInteractive: true, json: true, status: 'finished', limit: 1, diff --git a/packages/expo/src/executors/eject/compat.ts b/packages/expo/src/executors/eject/compat.ts deleted file mode 100644 index 4f1b8c5432acf4..00000000000000 --- a/packages/expo/src/executors/eject/compat.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { convertNxExecutor } from '@nrwl/devkit'; - -import ejectExecutor from './eject.impl'; - -export default convertNxExecutor(ejectExecutor); diff --git a/packages/expo/src/executors/eject/schema.d.ts b/packages/expo/src/executors/eject/schema.d.ts deleted file mode 100644 index 38f363d4958f88..00000000000000 --- a/packages/expo/src/executors/eject/schema.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -// options from https://docs.expo.dev/workflow/expo-cli/#eject - -export interface ExpoEjectOptions { - install: boolean; // default is true - platform: 'all' | 'android' | 'ios'; // default is all -} diff --git a/packages/expo/src/executors/eject/schema.json b/packages/expo/src/executors/eject/schema.json deleted file mode 100644 index 4df03052104ede..00000000000000 --- a/packages/expo/src/executors/eject/schema.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "version": 2, - "outputCapture": "direct-nodejs", - "cli": "nx", - "$id": "NxExpoEject", - "$schema": "http://json-schema.org/schema", - "title": "Expo Eject", - "description": "Create native iOS and Android project files", - "type": "object", - "properties": { - "install": { - "type": "boolean", - "description": "Install CocoaPods.", - "default": true - }, - "platform": { - "type": "string", - "description": "Platforms to sync", - "default": "all", - "examples": ["ios", "android", "all"] - } - } -} diff --git a/packages/expo/src/executors/export/compat.ts b/packages/expo/src/executors/export/compat.ts new file mode 100644 index 00000000000000..7bc584476207ac --- /dev/null +++ b/packages/expo/src/executors/export/compat.ts @@ -0,0 +1,5 @@ +import { convertNxExecutor } from '@nrwl/devkit'; + +import exportExecutor from './export.impl'; + +export default convertNxExecutor(exportExecutor); diff --git a/packages/expo/src/executors/export/export.impl.ts b/packages/expo/src/executors/export/export.impl.ts new file mode 100644 index 00000000000000..203b4c5611481f --- /dev/null +++ b/packages/expo/src/executors/export/export.impl.ts @@ -0,0 +1,84 @@ +import { ExecutorContext, names } from '@nrwl/devkit'; +import { ChildProcess, fork } from 'child_process'; +import { join } from 'path'; + +import { ensureNodeModulesSymlink } from '../../utils/ensure-node-modules-symlink'; +import { ExportExecutorSchema } from './schema'; + +export interface ExpoExportOutput { + success: boolean; +} + +let childProcess: ChildProcess; + +export default async function* exportExecutor( + options: ExportExecutorSchema, + context: ExecutorContext +): AsyncGenerator { + const projectRoot = context.workspace.projects[context.projectName].root; + ensureNodeModulesSymlink(context.root, projectRoot); + + try { + await exportAsync(context.root, projectRoot, options); + + yield { + success: true, + }; + } finally { + if (childProcess) { + childProcess.kill(); + } + } +} + +function exportAsync( + workspaceRoot: string, + projectRoot: string, + options: ExportExecutorSchema +): Promise { + return new Promise((resolve, reject) => { + childProcess = fork( + join(workspaceRoot, './node_modules/@expo/cli/build/bin/cli'), + [ + `export${options.bundler === 'webpack' ? ':web' : ''}`, + '.', + ...createExportOptions(options), + ], + { cwd: join(workspaceRoot, projectRoot) } + ); + + // Ensure the child process is killed when the parent exits + process.on('exit', () => childProcess.kill()); + process.on('SIGTERM', () => childProcess.kill()); + + childProcess.on('error', (err) => { + reject(err); + }); + childProcess.on('exit', (code) => { + if (code === 0) { + resolve(code); + } else { + reject(code); + } + }); + }); +} + +const nxOptions = ['bundler']; +// options from https://github.com/expo/expo/blob/main/packages/@expo/cli/src/export/index.ts +function createExportOptions(options: ExportExecutorSchema) { + return Object.keys(options).reduce((acc, k) => { + if (!nxOptions.includes(k)) { + const v = options[k]; + if (typeof v === 'boolean') { + if (v === true) { + // when true, does not need to pass the value true, just need to pass the flag in kebob case + acc.push(`--${names(k).fileName}`); + } + } else { + acc.push(`--${names(k).fileName}`, v); + } + } + return acc; + }, []); +} diff --git a/packages/expo/src/executors/export/schema.d.ts b/packages/expo/src/executors/export/schema.d.ts new file mode 100644 index 00000000000000..e93be69b912666 --- /dev/null +++ b/packages/expo/src/executors/export/schema.d.ts @@ -0,0 +1,11 @@ +// options form https://github.com/expo/expo/blob/main/packages/%40expo/cli/src/export/resolveOptions.ts +export interface ExportExecutorSchema { + platform?: 'ios' | 'android' | 'all' | 'web'; // default is 'all' + outputDir?: string; + clear?: boolean; + dev?: boolean; + maxWorkers?: number; + dumpAssetmap?: boolean; + dumpSourcemap?: boolean; + bundler: 'metro' | 'webpack'; +} diff --git a/packages/expo/src/executors/export/schema.json b/packages/expo/src/executors/export/schema.json new file mode 100644 index 00000000000000..431d3b0570a8d4 --- /dev/null +++ b/packages/expo/src/executors/export/schema.json @@ -0,0 +1,46 @@ +{ + "cli": "nx", + "version": 2, + "$id": "NxExpoExport", + "$schema": "http://json-schema.org/schema", + "title": "Expo Export", + "description": "Export the JavaScript and assets for your app using Metro/webpack bundler", + "type": "object", + "properties": { + "platform": { + "description": "Choose the platform to compile for", + "enum": ["ios", "android", "all", "web"], + "alias": "p" + }, + "dev": { + "type": "boolean", + "description": "Bundle for development environments without minifying code or stripping the __DEV__ boolean. Configure static files for developing locally using a non-https server." + }, + "clear": { + "type": "boolean", + "description": "Clear the bundler cache before exporting" + }, + "outputDir": { + "type": "string", + "description": "The directory to export the static files to. Default: dist" + }, + "maxWorkers": { + "type": "number", + "description": "Maximum number of tasks to allow Metro to spawn" + }, + "dumpAssetmap": { + "type": "string", + "description": "Dump the asset map for further processing" + }, + "dumpSourcemap": { + "type": "string", + "description": "Dump the source map for debugging the JS bundle" + }, + "bundler": { + "enum": ["metro", "webpack"], + "description": "Choose the bundler to compile for", + "default": "metro" + } + }, + "required": ["bundler"] +} diff --git a/packages/expo/src/executors/install/compat.ts b/packages/expo/src/executors/install/compat.ts new file mode 100644 index 00000000000000..d9900bab859bb6 --- /dev/null +++ b/packages/expo/src/executors/install/compat.ts @@ -0,0 +1,5 @@ +import { convertNxExecutor } from '@nrwl/devkit'; + +import installExecutor from './install.impl'; + +export default convertNxExecutor(installExecutor); diff --git a/packages/expo/src/executors/install/install.impl.ts b/packages/expo/src/executors/install/install.impl.ts new file mode 100644 index 00000000000000..c5978967f41d35 --- /dev/null +++ b/packages/expo/src/executors/install/install.impl.ts @@ -0,0 +1,81 @@ +import { ExecutorContext, names } from '@nrwl/devkit'; +import { ChildProcess, fork } from 'child_process'; +import { join } from 'path'; + +import { ensureNodeModulesSymlink } from '../../utils/ensure-node-modules-symlink'; +import { ExpoInstallOptions } from './schema'; + +export interface ExpoInstallOutput { + success: boolean; +} + +let childProcess: ChildProcess; + +export default async function* installExecutor( + options: ExpoInstallOptions, + context: ExecutorContext +): AsyncGenerator { + const projectRoot = context.workspace.projects[context.projectName].root; + + try { + await installAsync(context.root, options); + ensureNodeModulesSymlink(context.root, projectRoot); + + yield { + success: true, + }; + } finally { + if (childProcess) { + childProcess.kill(); + } + } +} + +export function installAsync( + workspaceRoot: string, + options: ExpoInstallOptions +): Promise { + return new Promise((resolve, reject) => { + childProcess = fork( + join(workspaceRoot, './node_modules/@expo/cli/build/bin/cli'), + ['install', ...createInstallOptions(options)], + { cwd: workspaceRoot } + ); + + // Ensure the child process is killed when the parent exits + process.on('exit', () => childProcess.kill()); + process.on('SIGTERM', () => childProcess.kill()); + + childProcess.on('error', (err) => { + reject(err); + }); + childProcess.on('exit', (code) => { + if (code === 0) { + resolve(code); + } else { + reject(code); + } + }); + }); +} + +// options from https://github.com/expo/expo/blob/main/packages/%40expo/cli/src/install/index.ts +function createInstallOptions(options: ExpoInstallOptions) { + return Object.keys(options).reduce((acc, k) => { + const v = options[k]; + if (k === 'packages') { + const packages = typeof v === 'string' ? v.split(',') : v; + acc.push(...packages); + } else { + if (typeof v === 'boolean') { + if (v === true) { + // when true, does not need to pass the value true, just need to pass the flag in kebob case + acc.push(`--${names(k).fileName}`); + } + } else { + acc.push(`--${names(k).fileName}`, v); + } + } + return acc; + }, []); +} diff --git a/packages/expo/src/executors/install/schema.d.ts b/packages/expo/src/executors/install/schema.d.ts new file mode 100644 index 00000000000000..8a0ca6ce5e55fb --- /dev/null +++ b/packages/expo/src/executors/install/schema.d.ts @@ -0,0 +1,7 @@ +// options from https://github.com/expo/expo/blob/main/packages/@expo/cli/src/install/index.ts + +export interface ExpoInstallOptions { + packages?: string | string[]; // either a string seperated by comma or a string array + check: boolean; // default is true + fix: boolean; // default is false +} diff --git a/packages/expo/src/executors/install/schema.json b/packages/expo/src/executors/install/schema.json new file mode 100644 index 00000000000000..f2c753db2a1d0a --- /dev/null +++ b/packages/expo/src/executors/install/schema.json @@ -0,0 +1,33 @@ +{ + "cli": "nx", + "version": 2, + "$id": "NxExpoInstall", + "$schema": "http://json-schema.org/schema", + "title": "Expo Install", + "description": "Install a module or other package to a project", + "type": "object", + "properties": { + "packages": { + "type": "array", + "items": { + "type": "string" + }, + "default": [], + "description": "The names of packages to install", + "$default": { + "$source": "argv", + "index": 0 + } + }, + "check": { + "type": "boolean", + "description": "Check which installed packages need to be updated", + "default": true + }, + "fix": { + "type": "boolean", + "description": "Automatically update any invalid package versions", + "default": false + } + } +} diff --git a/packages/expo/src/executors/prebuild/compat.ts b/packages/expo/src/executors/prebuild/compat.ts new file mode 100644 index 00000000000000..75d6be9106885e --- /dev/null +++ b/packages/expo/src/executors/prebuild/compat.ts @@ -0,0 +1,5 @@ +import { convertNxExecutor } from '@nrwl/devkit'; + +import prebuildExecutor from './prebuild.impl'; + +export default convertNxExecutor(prebuildExecutor); diff --git a/packages/expo/src/executors/eject/eject.impl.ts b/packages/expo/src/executors/prebuild/prebuild.impl.ts similarity index 60% rename from packages/expo/src/executors/eject/eject.impl.ts rename to packages/expo/src/executors/prebuild/prebuild.impl.ts index 07b3c7f6519a70..7d44424534e768 100644 --- a/packages/expo/src/executors/eject/eject.impl.ts +++ b/packages/expo/src/executors/prebuild/prebuild.impl.ts @@ -1,28 +1,33 @@ -import { ExecutorContext } from '@nrwl/devkit'; +import { ExecutorContext, names } from '@nrwl/devkit'; import { ChildProcess, fork } from 'child_process'; import { join } from 'path'; import { ensureNodeModulesSymlink } from '../../utils/ensure-node-modules-symlink'; import { podInstall } from '../../utils/pod-install-task'; -import { ExpoEjectOptions } from './schema'; +import { installAsync } from '../install/install.impl'; +import { ExpoPrebuildOptions } from './schema'; -export interface ExpoEjectOutput { +export interface ExpoPrebuildOutput { success: boolean; } let childProcess: ChildProcess; -export default async function* ejectExecutor( - options: ExpoEjectOptions, +export default async function* prebuildExecutor( + options: ExpoPrebuildOptions, context: ExecutorContext -): AsyncGenerator { +): AsyncGenerator { const projectRoot = context.workspace.projects[context.projectName].root; ensureNodeModulesSymlink(context.root, projectRoot); try { - await ejectAsync(context.root, projectRoot, options); + await prebuildAsync(context.root, projectRoot, options); if (options.install) { + await installAsync(context.root, { + check: true, + fix: false, + }); await podInstall(join(context.root, projectRoot, 'ios')); } @@ -36,15 +41,15 @@ export default async function* ejectExecutor( } } -function ejectAsync( +function prebuildAsync( workspaceRoot: string, projectRoot: string, - options: ExpoEjectOptions + options: ExpoPrebuildOptions ): Promise { return new Promise((resolve, reject) => { childProcess = fork( - join(workspaceRoot, './node_modules/expo-cli/bin/expo.js'), - ['eject', ...createEjectOptions(options), '--no-install'], + join(workspaceRoot, './node_modules/@expo/cli/build/bin/cli'), + ['prebuild', ...createPrebuildOptions(options), '--no-install'], { cwd: join(workspaceRoot, projectRoot) } ); @@ -66,11 +71,12 @@ function ejectAsync( } const nxOptions = ['install']; -function createEjectOptions(options: ExpoEjectOptions) { +// options from https://github.com/expo/expo/blob/main/packages/%40expo/cli/src/prebuild/index.ts +function createPrebuildOptions(options: ExpoPrebuildOptions) { return Object.keys(options).reduce((acc, k) => { - const v = options[k]; if (!nxOptions.includes(k)) { - acc.push(`--${k}`, v); + const v = options[k]; + acc.push(`--${names(k).fileName}`, v); } return acc; }, []); diff --git a/packages/expo/src/executors/prebuild/schema.d.ts b/packages/expo/src/executors/prebuild/schema.d.ts new file mode 100644 index 00000000000000..b0905612de511f --- /dev/null +++ b/packages/expo/src/executors/prebuild/schema.d.ts @@ -0,0 +1,9 @@ +// options from https://github.com/expo/expo/blob/main/packages/%40expo/cli/src/prebuild/index.ts + +import { string } from 'yargs'; + +export interface ExpoPrebuildOptions { + install: boolean; // default is true + platform: 'all' | 'android' | 'ios'; // default is all + template?: string; +} diff --git a/packages/expo/src/executors/prebuild/schema.json b/packages/expo/src/executors/prebuild/schema.json new file mode 100644 index 00000000000000..d26ab3c3a19e2d --- /dev/null +++ b/packages/expo/src/executors/prebuild/schema.json @@ -0,0 +1,26 @@ +{ + "cli": "nx", + "version": 2, + "$id": "NxExpoPrebuild", + "$schema": "http://json-schema.org/schema", + "title": "Expo Prebuild", + "description": "Create native iOS and Android project files for building natively", + "type": "object", + "properties": { + "install": { + "type": "boolean", + "description": "Installing npm packages and CocoaPods.", + "default": false + }, + "platform": { + "description": "Platforms to sync", + "default": "all", + "enum": ["ios", "android", "all"], + "alias": "p" + }, + "template": { + "type": "string", + "description": "Project template to clone from. File path pointing to a local tar file or a github repo" + } + } +} diff --git a/packages/expo/src/executors/publish-set/publish-set.impl.ts b/packages/expo/src/executors/publish-set/publish-set.impl.ts index 90a767094d5835..522cb16f6a287f 100644 --- a/packages/expo/src/executors/publish-set/publish-set.impl.ts +++ b/packages/expo/src/executors/publish-set/publish-set.impl.ts @@ -1,4 +1,4 @@ -import { ExecutorContext, names } from '@nrwl/devkit'; +import { ExecutorContext, logger, names } from '@nrwl/devkit'; import { join } from 'path'; import { ChildProcess, fork } from 'child_process'; @@ -15,6 +15,10 @@ export default async function* publishSetExecutor( options: ExpoPublishSetOptions, context: ExecutorContext ): AsyncGenerator { + logger.warn( + '@nrwl/expo:publish-set is deprecated and will be removed in Nx 16.' + ); + const projectRoot = context.workspace.projects[context.projectName].root; ensureNodeModulesSymlink(context.root, projectRoot); diff --git a/packages/expo/src/executors/publish/publish.impl.ts b/packages/expo/src/executors/publish/publish.impl.ts index 1f1d0eec7e707d..eab83b3105cc08 100644 --- a/packages/expo/src/executors/publish/publish.impl.ts +++ b/packages/expo/src/executors/publish/publish.impl.ts @@ -1,4 +1,4 @@ -import { ExecutorContext, names } from '@nrwl/devkit'; +import { ExecutorContext, logger, names } from '@nrwl/devkit'; import { join } from 'path'; import { ChildProcess, fork } from 'child_process'; @@ -19,12 +19,19 @@ export default async function* publishExecutor( options: ExpoPublishOptions, context: ExecutorContext ): AsyncGenerator { + logger.warn('@nrwl/expo:publish is deprecated and will be removed in Nx 16.'); + const projectRoot = context.workspace.projects[context.projectName].root; ensureNodeModulesSymlink(context.root, projectRoot); if (options.sync) { displayNewlyAddedDepsMessage( context.projectName, - await syncDeps(context.projectName, projectRoot) + await syncDeps( + context.projectName, + projectRoot, + context.root, + context.projectGraph + ) ); } diff --git a/packages/expo/src/executors/rollback/rollback.impl.ts b/packages/expo/src/executors/rollback/rollback.impl.ts index 3c294137dc27f7..c81eeaaf00f3a0 100644 --- a/packages/expo/src/executors/rollback/rollback.impl.ts +++ b/packages/expo/src/executors/rollback/rollback.impl.ts @@ -1,4 +1,4 @@ -import { ExecutorContext, names } from '@nrwl/devkit'; +import { ExecutorContext, logger, names } from '@nrwl/devkit'; import { join } from 'path'; import { ChildProcess, fork } from 'child_process'; @@ -15,6 +15,10 @@ export default async function* rollbackExecutor( options: ExpoRollbackOptions, context: ExecutorContext ): AsyncGenerator { + logger.warn( + '@nrwl/expo:rollback is deprecated and will be removed in Nx 16.' + ); + const projectRoot = context.workspace.projects[context.projectName].root; ensureNodeModulesSymlink(context.root, projectRoot); diff --git a/packages/expo/src/executors/run/run.impl.ts b/packages/expo/src/executors/run/run.impl.ts index 746d4b381a7c1d..19a96e1dc2e2cb 100644 --- a/packages/expo/src/executors/run/run.impl.ts +++ b/packages/expo/src/executors/run/run.impl.ts @@ -28,7 +28,12 @@ export default async function* runExecutor( if (options.sync) { displayNewlyAddedDepsMessage( context.projectName, - await syncDeps(context.projectName, projectRoot) + await syncDeps( + context.projectName, + projectRoot, + context.root, + context.projectGraph + ) ); } @@ -50,7 +55,7 @@ function runCliRun( ) { return new Promise((resolve, reject) => { childProcess = fork( - join(workspaceRoot, './node_modules/expo-cli/bin/expo.js'), + join(workspaceRoot, './node_modules/@expo/cli/build/bin/cli'), ['run:' + options.platform, ...createRunOptions(options)], { cwd: projectRoot, @@ -77,7 +82,11 @@ function runCliRun( const nxOptions = ['sync', 'platform']; const iOSOptions = ['xcodeConfiguration', 'schema']; const androidOptions = ['variant']; - +/* + * run options: + * ios: https://github.com/expo/expo/blob/main/packages/@expo/cli/src/run/ios/index.ts + * android: https://github.com/expo/expo/blob/main/packages/@expo/cli/src/run/android/index.ts + */ function createRunOptions(options: ExpoRunOptions) { return Object.keys(options).reduce((acc, k) => { if ( @@ -91,14 +100,10 @@ function createRunOptions(options: ExpoRunOptions) { { if (k === 'xcodeConfiguration') { acc.push('--configuration', v); - } else if (k === 'bundler') { - if (v === false) { - acc.push('--no-bundler'); - } } else if (typeof v === 'boolean') { - if (v === true) { - // when true, does not need to pass the value true, just need to pass the flag in kebob case - acc.push(`--${names(k).fileName}`); + // no need to pass in the flag when it is true, pass the --no- when it is false + if (v === false) { + acc.push(`--no-${names(k).fileName}`); } } else { acc.push(`--${names(k).fileName}`, v); diff --git a/packages/expo/src/executors/run/schema.d.ts b/packages/expo/src/executors/run/schema.d.ts index b67a428ad9b520..dc8521d6c4f4ee 100644 --- a/packages/expo/src/executors/run/schema.d.ts +++ b/packages/expo/src/executors/run/schema.d.ts @@ -1,11 +1,23 @@ -// options from https://docs.expo.dev/workflow/expo-cli/#expo-runios and https://docs.expo.dev/workflow/expo-cli/#expo-runandroid +/* + * options from + * - android: https://github.com/expo/expo/blob/main/packages/%40expo/cli/src/run/android/resolveOptions.ts + * - ios: https://github.com/expo/expo/blob/main/packages/%40expo/cli/src/run/ios/options/resolveOptions.ts + */ export interface ExpoRunOptions { platform: 'ios' | 'android'; - xcodeConfiguration: string; // iOS only, default is Debug - scheme?: string; // iOS only - variant: string; // android only, default is debug + sync: boolean; // default is true + + // ios only + scheme?: string | boolean; // Xcode scheme to build. + xcodeConfiguration?: XcodeConfiguration; // Xcode configuration to build. Default `Debug` + + // android only + variant?: string; + + // shared between ios and android + device?: string | boolean; port: number; // default is 8081 bundler: boolean; // default is true - sync: boolean; // default is true - device?: string; + install?: boolean; + buildCache?: boolean; } diff --git a/packages/expo/src/executors/run/schema.json b/packages/expo/src/executors/run/schema.json index 72383131938446..96e801e8234f40 100644 --- a/packages/expo/src/executors/run/schema.json +++ b/packages/expo/src/executors/run/schema.json @@ -11,7 +11,8 @@ "platform": { "description": "Platform to run for (ios, android).", "enum": ["ios", "android"], - "default": "ios" + "default": "ios", + "alias": "p" }, "xcodeConfiguration": { "type": "string", @@ -45,8 +46,15 @@ }, "bundler": { "type": "boolean", - "description": "Whether to skip starting the Metro bundler. True to start it, false to skip it.", - "default": true + "description": "Whether to skip starting the Metro bundler. True to start it, false to skip it." + }, + "install": { + "type": "boolean", + "description": "Should install missing dependencies before building." + }, + "buildCache": { + "type": "boolean", + "description": "Should use derived data for builds." } }, "required": ["platform"] diff --git a/packages/expo/src/executors/start/schema.d.ts b/packages/expo/src/executors/start/schema.d.ts index 7f6940efd6e576..9a40b79f9717a2 100644 --- a/packages/expo/src/executors/start/schema.d.ts +++ b/packages/expo/src/executors/start/schema.d.ts @@ -1,6 +1,8 @@ -// options from https://docs.expo.dev/workflow/expo-cli/#expo-start +// options from https://github.com/expo/expo/blob/main/packages/%40expo/cli/src/start/resolveOptions.ts export interface ExpoStartOptions { + forceManifestType: 'classic' | 'expo-updates'; + privateKeyPath?: string; port: number; dev?: boolean; devClient?: boolean; @@ -9,14 +11,20 @@ export interface ExpoStartOptions { clear?: boolean; maxWorkers?: number; scheme?: string; - sendTo?: string; ios?: boolean; android?: boolean; web?: boolean; - host?: string; + host?: 'localhost' | 'lan' | 'tunnel'; lan?: boolean; localhost?: boolean; tunnel?: boolean; offline?: boolean; - webpack?: boolean; + /** + * @deprecated + */ + sendTo?: string; // deprecated from @expo/cli + /** + * @deprecated + */ + webpack?: boolean; // deprecated from @expo/cli } diff --git a/packages/expo/src/executors/start/schema.json b/packages/expo/src/executors/start/schema.json index 387c67f479c433..9932338b1a3917 100644 --- a/packages/expo/src/executors/start/schema.json +++ b/packages/expo/src/executors/start/schema.json @@ -8,6 +8,15 @@ "description": "Packager Server target options", "type": "object", "properties": { + "forceManifestType": { + "type": "string", + "description": "Override auto detection of manifest type.", + "enum": ["expo-updates", "classic"] + }, + "privateKeyPath": { + "type": "string", + "description": "Path to private key for code signing. Default: 'private-key.pem' in the same directory as the certificate specified by the expo-updates configuration in app.json." + }, "port": { "type": "number", "description": "Port to start the native Metro bundler on (does not apply to web or tunnel)", @@ -43,11 +52,6 @@ "type": "string", "description": "Custom URI protocol to use with a development build" }, - "sentTo": { - "type": "string", - "description": "An email address to send a link to", - "alias": "s" - }, "android": { "type": "boolean", "description": "Opens your app in Expo Go on a connected Android device", @@ -58,10 +62,15 @@ "description": "Opens your app in Expo Go in a currently running iOS simulator on your computer", "alias": "i" }, + "web": { + "type": "boolean", + "description": " Opens your app in a web browser", + "alias": "w" + }, "host": { "type": "string", - "description": "lan (default), tunnel, localhost. Type of host to use. \"tunnel\" allows you to view your link on other networks", - "alias": "m" + "description": "lan (default), tunnel, localhost. Type of host to use. lan uses the local network; tunnel ues any network by tunnel through ngrok; localhost connects to the dev server over localhost.", + "enum": ["localhost", "lan", "tunnel"] }, "tunnel": { "type": "boolean", @@ -79,9 +88,16 @@ "type": "boolean", "description": "Allows this command to run while offline" }, + "sentTo": { + "type": "string", + "description": "An email address to send a link to", + "alias": "s", + "x-deprecated": true + }, "webpack": { "type": "boolean", - "description": "Start a Webpack dev server for the web app." + "description": "Start a Webpack dev server for the web app.", + "x-deprecated": true } } } diff --git a/packages/expo/src/executors/start/start.impl.ts b/packages/expo/src/executors/start/start.impl.ts index 474daef925ea3b..0bf2d89cb5a60a 100644 --- a/packages/expo/src/executors/start/start.impl.ts +++ b/packages/expo/src/executors/start/start.impl.ts @@ -44,8 +44,8 @@ function startAsync( ): Promise { return new Promise((resolve, reject) => { childProcess = fork( - join(workspaceRoot, './node_modules/expo-cli/bin/expo.js'), - [options.webpack ? 'web' : 'start', ...createStartOptions(options)], + join(workspaceRoot, './node_modules/@expo/cli/build/bin/cli'), + ['start', ...createStartOptions(options)], { cwd: join(workspaceRoot, projectRoot) } ); @@ -66,17 +66,15 @@ function startAsync( }); } -const nxOptions = ['webpack']; +// options from https://github.com/expo/expo/blob/main/packages/%40expo/cli/src/start/index.ts function createStartOptions(options: ExpoStartOptions) { return Object.keys(options).reduce((acc, k) => { const v = options[k]; - if (k === 'dev' && v === false) { - acc.push(`--no-dev`); - } else if (k === 'minify' && v === false) { - acc.push(`--no-minify`); - } else if (k === 'https' && v === false) { - acc.push(`--no-https`); - } else if (!nxOptions.includes(k)) { + if (k === 'dev') { + if (v === false) { + acc.push(`--no-dev`); + } + } else { if (typeof v === 'boolean') { if (v === true) { // when true, does not need to pass the value true, just need to pass the flag in kebob case diff --git a/packages/expo/src/executors/sync-deps/schema.d.ts b/packages/expo/src/executors/sync-deps/schema.d.ts index e8043201c433d6..1778132fee6bee 100644 --- a/packages/expo/src/executors/sync-deps/schema.d.ts +++ b/packages/expo/src/executors/sync-deps/schema.d.ts @@ -1,3 +1,4 @@ export interface ExpoSyncDepsOptions { - include: string; + include: string[] | string; // default is an empty array [] + exclude: string[] | string; // default is an empty array [] } diff --git a/packages/expo/src/executors/sync-deps/schema.json b/packages/expo/src/executors/sync-deps/schema.json index afc8736677034a..57f60ad4752fcd 100644 --- a/packages/expo/src/executors/sync-deps/schema.json +++ b/packages/expo/src/executors/sync-deps/schema.json @@ -9,8 +9,20 @@ "type": "object", "properties": { "include": { - "type": "string", - "description": "A comma-separated list of additional npm packages to include. e.g. 'nx sync-deps --include=react-native-gesture-handler,react-native-safe-area-context'" + "type": "array", + "items": { + "type": "string" + }, + "default": [], + "description": "An array of additional npm packages to include." + }, + "exclude": { + "type": "array", + "items": { + "type": "string" + }, + "default": [], + "description": "An array of npm packages to exclude." } } } diff --git a/packages/expo/src/executors/sync-deps/sync-deps.impl.ts b/packages/expo/src/executors/sync-deps/sync-deps.impl.ts index 94e2dee2288a0c..b3313ee2e9ca15 100644 --- a/packages/expo/src/executors/sync-deps/sync-deps.impl.ts +++ b/packages/expo/src/executors/sync-deps/sync-deps.impl.ts @@ -3,9 +3,9 @@ import * as chalk from 'chalk'; import { ExecutorContext, logger, + ProjectGraph, readJsonFile, writeJsonFile, - createProjectGraphAsync, } from '@nrwl/devkit'; import { findAllNpmDependencies } from '../../utils/find-all-npm-dependencies'; @@ -23,7 +23,18 @@ export default async function* syncDepsExecutor( const projectRoot = context.workspace.projects[context.projectName].root; displayNewlyAddedDepsMessage( context.projectName, - await syncDeps(context.projectName, projectRoot, options.include) + await syncDeps( + context.projectName, + projectRoot, + context.root, + context.projectGraph, + typeof options.include === 'string' + ? options.include.split(',') + : options.include, + typeof options.exclude === 'string' + ? options.exclude.split(',') + : options.exclude + ) ); yield { success: true }; @@ -32,14 +43,15 @@ export default async function* syncDepsExecutor( export async function syncDeps( projectName: string, projectRoot: string, - include?: string + workspaceRoot: string, + projectGraph: ProjectGraph, + include: string[] = [], + exclude: string[] = [] ): Promise { - const graph = await createProjectGraphAsync(); - const npmDeps = findAllNpmDependencies(graph, projectName); - const packageJsonPath = join(projectRoot, 'package.json'); + let npmDeps = findAllNpmDependencies(projectGraph, projectName); + const packageJsonPath = join(workspaceRoot, projectRoot, 'package.json'); const packageJson = readJsonFile(packageJsonPath); const newDeps = []; - const includeDeps = include?.split(','); let updated = false; if (!packageJson.dependencies) { @@ -47,8 +59,11 @@ export async function syncDeps( updated = true; } - if (includeDeps) { - npmDeps.push(...includeDeps); + if (include && include.length) { + npmDeps.push(...include); + } + if (exclude && exclude.length) { + npmDeps = npmDeps.filter((dep) => !exclude.includes(dep)); } npmDeps.forEach((dep) => { diff --git a/packages/expo/src/generators/application/lib/add-project.ts b/packages/expo/src/generators/application/lib/add-project.ts index 7e56788b578016..c7d3a9d128d0a5 100644 --- a/packages/expo/src/generators/application/lib/add-project.ts +++ b/packages/expo/src/generators/application/lib/add-project.ts @@ -1,5 +1,6 @@ import { addProjectConfiguration, + offsetFromRoot, ProjectConfiguration, readWorkspaceConfiguration, TargetConfiguration, @@ -43,14 +44,6 @@ function getTargets(options: NormalizedSchema) { }, }; - architect.web = { - executor: '@nrwl/expo:start', - options: { - port: 8081, - webpack: true, - }, - }; - architect.serve = { executor: 'nx:run-commands', options: { @@ -89,21 +82,25 @@ function getTargets(options: NormalizedSchema) { }, }; + // @deprecated, no longer supported in @expo/cli architect['build-ios'] = { executor: '@nrwl/expo:build-ios', options: {}, }; + // @deprecated, no longer supported in @expo/cli architect['build-android'] = { executor: '@nrwl/expo:build-android', options: {}, }; + // @deprecated, no longer supported in @expo/cli architect['build-web'] = { executor: '@nrwl/expo:build-web', options: {}, }; + // @deprecated, no longer supported in @expo/cli architect['build-status'] = { executor: '@nrwl/expo:build-web', options: {}, @@ -119,25 +116,63 @@ function getTargets(options: NormalizedSchema) { options: {}, }; + // @deprecated, no longer supported in @expo/cli architect['publish'] = { executor: '@nrwl/expo:publish', options: {}, }; + // @deprecated, no longer supported in @expo/cli architect['publish-set'] = { executor: '@nrwl/expo:publish-set', options: {}, }; + // @deprecated, no longer supported in @expo/cli architect['rollback'] = { executor: '@nrwl/expo:rollback', options: {}, }; + architect['prebuild'] = { + executor: '@nrwl/expo:prebuild', + options: {}, + }; + + // @deprecated, no longer supported in @expo/cli architect['eject'] = { - executor: '@nrwl/expo:eject', + executor: 'nx:run-commands', + options: { + command: `nx prebuild ${options.name}`, + }, + }; + + architect['install'] = { + executor: '@nrwl/expo:install', + options: {}, + }; + + architect['update'] = { + executor: '@nrwl/expo:update', options: {}, }; + architect['export'] = { + executor: '@nrwl/expo:export', + options: { + platform: 'all', + outputDir: `${offsetFromRoot(options.appProjectRoot)}dist/${ + options.appProjectRoot + }`, + }, + }; + + architect['export-web'] = { + executor: '@nrwl/expo:export', + options: { + bundler: 'webpack', + }, + }; + return architect; } diff --git a/packages/expo/src/generators/init/init.ts b/packages/expo/src/generators/init/init.ts index 497a6f4fe97822..29a861f2abdd62 100644 --- a/packages/expo/src/generators/init/init.ts +++ b/packages/expo/src/generators/init/init.ts @@ -24,6 +24,7 @@ import { svgrWebpackVersion, babelPresetExpoVersion, easCliVersion, + deprecatedExpoCliVersion, } from '../../utils/versions'; import { @@ -85,7 +86,8 @@ export function updateDependencies(host: Tree) { 'react-test-renderer': reactTestRendererVersion, '@testing-library/react-native': testingLibraryReactNativeVersion, '@testing-library/jest-native': testingLibraryJestNativeVersion, - 'expo-cli': expoCliVersion, + 'expo-cli': deprecatedExpoCliVersion, + '@expo/cli': expoCliVersion, 'eas-cli': easCliVersion, '@svgr/webpack': svgrWebpackVersion, 'babel-preset-expo': babelPresetExpoVersion, diff --git a/packages/expo/src/migrations/update-14-5-1/add-eas-update-target.spec.ts b/packages/expo/src/migrations/update-14-5-1/add-eas-update-target.spec.ts index f0d2e76b6266bb..2ae7b367e98cfc 100644 --- a/packages/expo/src/migrations/update-14-5-1/add-eas-update-target.spec.ts +++ b/packages/expo/src/migrations/update-14-5-1/add-eas-update-target.spec.ts @@ -18,7 +18,7 @@ describe('add-eas-update-target', () => { }); }); - it(`should update project.json with target build and build-list`, async () => { + it(`should update project.json with target update`, async () => { await update(tree); getProjects(tree).forEach((project) => { diff --git a/packages/expo/src/migrations/update-15-0-3/add-new-expo-cli-targets.spec.ts b/packages/expo/src/migrations/update-15-0-3/add-new-expo-cli-targets.spec.ts new file mode 100644 index 00000000000000..cd0d340de557a3 --- /dev/null +++ b/packages/expo/src/migrations/update-15-0-3/add-new-expo-cli-targets.spec.ts @@ -0,0 +1,45 @@ +import { addProjectConfiguration, getProjects, Tree } from '@nrwl/devkit'; +import { createTreeWithEmptyWorkspace } from '@nrwl/devkit/testing'; +import update from './add-new-expo-cli-targets'; + +describe('add-eas-update-target', () => { + let tree: Tree; + + beforeEach(async () => { + tree = createTreeWithEmptyWorkspace(); + addProjectConfiguration(tree, 'product', { + root: 'apps/product', + sourceRoot: 'apps/product/src', + targets: { + start: { + executor: '@nrwl/expo:start', + }, + }, + }); + }); + + it(`should update project.json with target prebuild, install and eject`, async () => { + await update(tree); + + getProjects(tree).forEach((project) => { + expect(project.targets['eject']).toEqual({ + executor: 'nx:run-commands', + options: { + command: `nx prebuild product`, + }, + }); + expect(project.targets['install']).toEqual({ + executor: '@nrwl/expo:install', + options: {}, + }); + expect(project.targets['prebuild']).toEqual({ + executor: '@nrwl/expo:prebuild', + options: {}, + }); + expect(project.targets['update']).toEqual({ + executor: '@nrwl/expo:update', + options: {}, + }); + }); + }); +}); diff --git a/packages/expo/src/migrations/update-15-0-3/add-new-expo-cli-targets.ts b/packages/expo/src/migrations/update-15-0-3/add-new-expo-cli-targets.ts new file mode 100644 index 00000000000000..94ba65067c4709 --- /dev/null +++ b/packages/expo/src/migrations/update-15-0-3/add-new-expo-cli-targets.ts @@ -0,0 +1,68 @@ +import { + Tree, + formatFiles, + getProjects, + updateProjectConfiguration, + offsetFromRoot, +} from '@nrwl/devkit'; + +/** + * Add new @expi/cli targets: + * - add target prebuild + * - add target install + * - add target update + * - replace target eject + */ +export default async function update(tree: Tree) { + const projects = getProjects(tree); + + for (const [name, config] of projects.entries()) { + if (config.targets?.['start']?.executor === '@nrwl/expo:start') { + if (!config.targets['prebuild']) { + config.targets['prebuild'] = { + executor: '@nrwl/expo:prebuild', + options: {}, + }; + } + if (!config.targets['install']) { + config.targets['install'] = { + executor: '@nrwl/expo:install', + options: {}, + }; + } + if (!config.targets['update']) { + config.targets['update'] = { + executor: '@nrwl/expo:update', + options: {}, + }; + } + if (!config.targets['export']) { + config.targets['export'] = { + executor: '@nrwl/expo:export', + options: { + platform: 'all', + outputDir: `${offsetFromRoot(config.root)}dist/${config.root}`, + }, + }; + } + if (!config.targets['export-web']) { + config.targets['export-web'] = { + executor: '@nrwl/expo:export', + options: { + bundler: 'webpack', + }, + }; + } + config.targets['eject'] = { + executor: 'nx:run-commands', + options: { + command: `nx prebuild ${name}`, + }, + }; + } + + updateProjectConfiguration(tree, name, config); + } + + await formatFiles(tree); +} diff --git a/packages/expo/src/utils/pod-install-task.ts b/packages/expo/src/utils/pod-install-task.ts index 31fb65fb77d135..fda361d92a0f1d 100644 --- a/packages/expo/src/utils/pod-install-task.ts +++ b/packages/expo/src/utils/pod-install-task.ts @@ -1,4 +1,4 @@ -import { spawn } from 'child_process'; +import { execSync } from 'child_process'; import { platform } from 'os'; import * as chalk from 'chalk'; import { GeneratorCallback, logger } from '@nrwl/devkit'; @@ -19,13 +19,21 @@ ${chalk.bold('sudo xcode-select --switch /Applications/Xcode.app')} * @param iosDirectory ios directory that contains Podfile * @returns resolve with 0 if not error, reject with error otherwise */ -export function runPodInstall(iosDirectory: string): GeneratorCallback { +export function runPodInstall( + iosDirectory: string, + install: boolean = true +): GeneratorCallback { return () => { if (platform() !== 'darwin') { logger.info('Skipping `pod install` on non-darwin platform'); return; } + if (!install) { + logger.info('Skipping `pod install`'); + return; + } + logger.info(`Running \`pod install\` from "${iosDirectory}"`); return podInstall(iosDirectory); @@ -34,21 +42,14 @@ export function runPodInstall(iosDirectory: string): GeneratorCallback { export function podInstall(iosDirectory: string): Promise { return new Promise((resolve, reject) => { - const process = spawn('pod', ['install'], { + const result = execSync('pod install', { cwd: iosDirectory, - stdio: [0, 1, 2], - }); - - process.on('close', (code: number) => { - if (code === 0) { - resolve(); - } else { - reject(new Error(podInstallErrorMessage)); - } }); - - process.on('error', () => { + logger.info(result.toString()); + if (result.toString().includes('Pod installation complete')) { + resolve(); + } else { reject(new Error(podInstallErrorMessage)); - }); + } }); } diff --git a/packages/expo/src/utils/versions.ts b/packages/expo/src/utils/versions.ts index 87bde66e5c8efd..3de8c1ca7b9fbb 100644 --- a/packages/expo/src/utils/versions.ts +++ b/packages/expo/src/utils/versions.ts @@ -1,11 +1,12 @@ export const nxVersion = '*'; -export const expoVersion = '46.0.13'; +export const expoVersion = '46.0.16'; export const expoMetroConfigVersion = '0.3.22'; export const expoSplashScreenVersion = '~0.16.2'; export const expoStatusBarVersion = '~1.4.0'; -export const expoCliVersion = '6.0.6'; -export const easCliVersion = '2.1.0'; +export const deprecatedExpoCliVersion = '6.0.6'; // expo-cli +export const expoCliVersion = '0.3.2'; // @expo/cli +export const easCliVersion = '2.4.1'; export const babelPresetExpoVersion = '~9.2.0'; export const reactNativeVersion = '0.69.6'; diff --git a/packages/react-native/src/executors/bundle/schema.json b/packages/react-native/src/executors/bundle/schema.json index 290c0cee45b57e..23843b4cb1b4aa 100644 --- a/packages/react-native/src/executors/bundle/schema.json +++ b/packages/react-native/src/executors/bundle/schema.json @@ -16,6 +16,7 @@ }, "platform": { "enum": ["ios", "android"], + "alias": "p", "description": "Platform to build for." }, "transformer": {