feat(react-native): upgrade react-native to 0.72 (#17810)
This commit is contained in:
parent
6529be96cf
commit
699a20ca03
@ -50,7 +50,7 @@ nx start my-app
|
||||
To generate a new library run:
|
||||
|
||||
```shell
|
||||
npx nx g @nx/react-native:lib your-lib-name
|
||||
npx nx g @nx/expo:lib your-lib-name
|
||||
```
|
||||
|
||||
### Generating Components
|
||||
@ -58,7 +58,7 @@ npx nx g @nx/react-native:lib your-lib-name
|
||||
To generate a new component inside library run:
|
||||
|
||||
```shell
|
||||
npx nx g @nx/react-native:component your-component-name --project=your-lib-name --export
|
||||
npx nx g @nx/expo:component your-component-name --project=your-lib-name --export
|
||||
```
|
||||
|
||||
Replace `your-lib-name` with the app's name as defined in your `tsconfig.base.json` file or the `name` property of your `package.json`
|
||||
@ -247,6 +247,28 @@ To check the details of your build status, run:
|
||||
nx build-list <app-name>
|
||||
```
|
||||
|
||||
### Submit an EAS Build
|
||||
|
||||
EAS Submit is a hosted service for uploading and submitting your app binaries to the app stores. Since it's a hosted service, you can submit your app to both stores as long as you can run EAS CLI on your machine.
|
||||
|
||||
To submit an EAS build:
|
||||
|
||||
```shell
|
||||
nx submit <app-name>
|
||||
```
|
||||
|
||||
### Update an EAS Build
|
||||
|
||||
EAS Update is a hosted service that serves updates for projects using the `expo-updates` library.
|
||||
|
||||
EAS Update makes fixing small bugs and pushing quick fixes a snap in between app store submissions. It accomplishes this by allowing an end-user's app to swap out the non-native parts of their app (for example, JS, styling, and image changes) with a new update that contains bug fixes and other updates.
|
||||
|
||||
To update an EAS build:
|
||||
|
||||
```shell
|
||||
nx update <app-name>
|
||||
```
|
||||
|
||||
### Testing Projects
|
||||
|
||||
You can run unit tests with:
|
||||
@ -269,6 +291,8 @@ Below table is a map between expo commands and Nx commands:
|
||||
| `expo install` | `nx install <app-name>` |
|
||||
| `eas build` | `nx build <app-name>` |
|
||||
| `eas build:list` | `nx build-list <app-name>` |
|
||||
| `eas update` | `nx update <app-name>` |
|
||||
| `eas submit` | `nx submit <app-name>` |
|
||||
|
||||
## More Documentation
|
||||
|
||||
|
||||
@ -46,7 +46,8 @@
|
||||
},
|
||||
"output": {
|
||||
"type": "string",
|
||||
"description": "Output path for local build"
|
||||
"description": "Output path for local build",
|
||||
"examples": ["../../dist/MyApp.tar.gz", "../../dist"]
|
||||
},
|
||||
"wait": {
|
||||
"type": "boolean",
|
||||
|
||||
@ -42,6 +42,7 @@
|
||||
"type": "boolean",
|
||||
"description": "Syncs npm dependencies to package.json (for React Native autolink).",
|
||||
"default": true,
|
||||
"x-deprecated": "Add sync-deps to dependsOn in project.json for this target instead",
|
||||
"x-priority": "internal"
|
||||
},
|
||||
"port": {
|
||||
|
||||
@ -88,6 +88,7 @@
|
||||
"sync": {
|
||||
"type": "boolean",
|
||||
"description": "Syncs npm dependencies to package.json (for React Native autolink).",
|
||||
"x-deprecated": "Add sync-deps to dependsOn in project.json for this target instead",
|
||||
"default": true
|
||||
}
|
||||
},
|
||||
|
||||
@ -45,7 +45,8 @@
|
||||
"packager": {
|
||||
"type": "boolean",
|
||||
"description": "Launch packager while building",
|
||||
"default": true
|
||||
"default": true,
|
||||
"x-deprecated": "Run `nx run <project>:start` instead. Will be removed in Nx 17."
|
||||
},
|
||||
"port": {
|
||||
"type": "number",
|
||||
@ -53,8 +54,10 @@
|
||||
"default": 8081
|
||||
},
|
||||
"tasks": {
|
||||
"type": "array",
|
||||
"items": { "type": "string" },
|
||||
"oneOf": [
|
||||
{ "type": "array", "items": { "type": "string" } },
|
||||
{ "type": "string" }
|
||||
],
|
||||
"description": "Run custom Gradle tasks. By default it's \"assembleDebug\". Will override passed mode and variant arguments.",
|
||||
"examples": [
|
||||
"assembleDebug",
|
||||
@ -71,8 +74,12 @@
|
||||
"default": false
|
||||
},
|
||||
"extraParams": {
|
||||
"type": "string",
|
||||
"description": "Custom params passed to gradle build command"
|
||||
"oneOf": [
|
||||
{ "type": "array", "items": { "type": "string" } },
|
||||
{ "type": "string" }
|
||||
],
|
||||
"description": "Custom params passed to gradle build command",
|
||||
"examples": ["-x lint -x test"]
|
||||
},
|
||||
"interactive": {
|
||||
"type": "boolean",
|
||||
@ -81,7 +88,8 @@
|
||||
"sync": {
|
||||
"type": "boolean",
|
||||
"description": "Syncs npm dependencies to `package.json` (for React Native autolink).",
|
||||
"default": true
|
||||
"default": true,
|
||||
"x-deprecated": "Add sync-deps to dependsOn instead"
|
||||
},
|
||||
"resetCache": {
|
||||
"type": "boolean",
|
||||
|
||||
@ -11,11 +11,7 @@
|
||||
"presets": [
|
||||
{ "name": "Build iOS for a simulator", "keys": ["simulator"] },
|
||||
{ "name": "Build iOS for a device", "keys": ["device"] },
|
||||
{ "name": "Build iOS for a device with udid", "keys": ["udid"] },
|
||||
{
|
||||
"name": "Run `pod install` before building iOS app",
|
||||
"keys": ["install"]
|
||||
}
|
||||
{ "name": "Build iOS for a device with udid", "keys": ["udid"] }
|
||||
],
|
||||
"properties": {
|
||||
"simulator": {
|
||||
@ -72,17 +68,22 @@
|
||||
"description": "Explicitly select which scheme and configuration to use before running a build"
|
||||
},
|
||||
"extraParams": {
|
||||
"type": "string",
|
||||
"oneOf": [
|
||||
{ "type": "array", "items": { "type": "string" } },
|
||||
{ "type": "string" }
|
||||
],
|
||||
"description": "Custom params that will be passed to xcodebuild command."
|
||||
},
|
||||
"install": {
|
||||
"type": "boolean",
|
||||
"description": "Runs `pod install` for native modules before building iOS app.",
|
||||
"x-deprecated": "Add pod-install to dependsOn in project.json for this target instead",
|
||||
"default": true
|
||||
},
|
||||
"sync": {
|
||||
"type": "boolean",
|
||||
"description": "Syncs npm dependencies to `package.json` (for React Native autolink).",
|
||||
"x-deprecated": "Add sync-deps to dependsOn in project.json for this target instead",
|
||||
"default": true
|
||||
},
|
||||
"resetCache": {
|
||||
@ -93,7 +94,8 @@
|
||||
"packager": {
|
||||
"type": "boolean",
|
||||
"description": "Launch packager while building",
|
||||
"default": true
|
||||
"default": true,
|
||||
"x-deprecated": "Run `nx run <project>:start` instead. Will be removed in Nx 17."
|
||||
}
|
||||
},
|
||||
"required": [],
|
||||
|
||||
@ -12,9 +12,19 @@
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"buildFolder": {
|
||||
"description": "Location for iOS build artifacts. Corresponds to Xcode's \"-derivedDataPath\". Relative to ios directory",
|
||||
"description": "Location for iOS build artifacts. Corresponds to Xcode's \"-derivedDataPath\". Relative to ios directory.",
|
||||
"type": "string",
|
||||
"default": "./build"
|
||||
},
|
||||
"repoUpdate": {
|
||||
"description": "Force running `pod repo update` before install.",
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"deployment": {
|
||||
"description": "Disallow any changes to the Podfile or the Podfile.lock during installation.",
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
}
|
||||
},
|
||||
"required": ["buildFolder"],
|
||||
|
||||
@ -77,8 +77,10 @@
|
||||
"default": 8081
|
||||
},
|
||||
"tasks": {
|
||||
"type": "array",
|
||||
"items": { "type": "string" },
|
||||
"oneOf": [
|
||||
{ "type": "array", "items": { "type": "string" } },
|
||||
{ "type": "string" }
|
||||
],
|
||||
"description": "Run custom Gradle tasks. By default it's \"assembleDebug\". Will override passed mode and variant arguments.",
|
||||
"examples": [
|
||||
"assembleDebug",
|
||||
@ -95,7 +97,10 @@
|
||||
"default": false
|
||||
},
|
||||
"extraParams": {
|
||||
"type": "string",
|
||||
"oneOf": [
|
||||
{ "type": "array", "items": { "type": "string" } },
|
||||
{ "type": "string" }
|
||||
],
|
||||
"description": "Custom params passed to gradle build command"
|
||||
},
|
||||
"interactive": {
|
||||
@ -105,6 +110,7 @@
|
||||
"sync": {
|
||||
"type": "boolean",
|
||||
"description": "Syncs npm dependencies to `package.json` (for React Native autolink).",
|
||||
"x-deprecated": "Add sync-deps to dependsOn for this target in project.json instead",
|
||||
"default": true
|
||||
},
|
||||
"resetCache": {
|
||||
|
||||
@ -13,11 +13,7 @@
|
||||
"presets": [
|
||||
{ "name": "Run iOS on a simulator", "keys": ["simulator"] },
|
||||
{ "name": "Run iOS on a device", "keys": ["device"] },
|
||||
{ "name": "Run iOS on a device with udid", "keys": ["udid"] },
|
||||
{
|
||||
"name": "Run `pod install` before building iOS app",
|
||||
"keys": ["install"]
|
||||
}
|
||||
{ "name": "Run iOS on a device with udid", "keys": ["udid"] }
|
||||
],
|
||||
"properties": {
|
||||
"xcodeConfiguration": {
|
||||
@ -81,17 +77,22 @@
|
||||
"description": "Explicitly select which scheme and configuration to use before running a build"
|
||||
},
|
||||
"extraParams": {
|
||||
"type": "string",
|
||||
"oneOf": [
|
||||
{ "type": "array", "items": { "type": "string" } },
|
||||
{ "type": "string" }
|
||||
],
|
||||
"description": "Custom params that will be passed to xcodebuild command."
|
||||
},
|
||||
"install": {
|
||||
"type": "boolean",
|
||||
"description": "Runs `pod install` for native modules before building iOS app.",
|
||||
"default": true
|
||||
"default": true,
|
||||
"x-deprecated": "Add `pod-install` to dependsOn for this target in project.json instead."
|
||||
},
|
||||
"sync": {
|
||||
"type": "boolean",
|
||||
"description": "Syncs npm dependencies to `package.json` (for React Native autolink).",
|
||||
"x-deprecated": "Add `sync-deps` to dependsOn for this target in project.json instead.",
|
||||
"default": true
|
||||
},
|
||||
"resetCache": {
|
||||
|
||||
@ -50,7 +50,7 @@ nx start my-app
|
||||
To generate a new library run:
|
||||
|
||||
```shell
|
||||
npx nx g @nx/react-native:lib your-lib-name
|
||||
npx nx g @nx/expo:lib your-lib-name
|
||||
```
|
||||
|
||||
### Generating Components
|
||||
@ -58,7 +58,7 @@ npx nx g @nx/react-native:lib your-lib-name
|
||||
To generate a new component inside library run:
|
||||
|
||||
```shell
|
||||
npx nx g @nx/react-native:component your-component-name --project=your-lib-name --export
|
||||
npx nx g @nx/expo:component your-component-name --project=your-lib-name --export
|
||||
```
|
||||
|
||||
Replace `your-lib-name` with the app's name as defined in your `tsconfig.base.json` file or the `name` property of your `package.json`
|
||||
@ -247,6 +247,28 @@ To check the details of your build status, run:
|
||||
nx build-list <app-name>
|
||||
```
|
||||
|
||||
### Submit an EAS Build
|
||||
|
||||
EAS Submit is a hosted service for uploading and submitting your app binaries to the app stores. Since it's a hosted service, you can submit your app to both stores as long as you can run EAS CLI on your machine.
|
||||
|
||||
To submit an EAS build:
|
||||
|
||||
```shell
|
||||
nx submit <app-name>
|
||||
```
|
||||
|
||||
### Update an EAS Build
|
||||
|
||||
EAS Update is a hosted service that serves updates for projects using the `expo-updates` library.
|
||||
|
||||
EAS Update makes fixing small bugs and pushing quick fixes a snap in between app store submissions. It accomplishes this by allowing an end-user's app to swap out the non-native parts of their app (for example, JS, styling, and image changes) with a new update that contains bug fixes and other updates.
|
||||
|
||||
To update an EAS build:
|
||||
|
||||
```shell
|
||||
nx update <app-name>
|
||||
```
|
||||
|
||||
### Testing Projects
|
||||
|
||||
You can run unit tests with:
|
||||
@ -269,6 +291,8 @@ Below table is a map between expo commands and Nx commands:
|
||||
| `expo install` | `nx install <app-name>` |
|
||||
| `eas build` | `nx build <app-name>` |
|
||||
| `eas build:list` | `nx build-list <app-name>` |
|
||||
| `eas update` | `nx update <app-name>` |
|
||||
| `eas submit` | `nx submit <app-name>` |
|
||||
|
||||
## More Documentation
|
||||
|
||||
|
||||
@ -92,15 +92,15 @@ describe('expo', () => {
|
||||
expect(prebuildResult.combinedOutput).toContain('Config synced');
|
||||
});
|
||||
|
||||
// TODO(emily): expo-cli always fetches the latest version of react native
|
||||
// re-enable it when expo-cli is fixed
|
||||
// TODO(emily): this test failed due to version conflict with conflict with @config-plugins/detox
|
||||
// https://github.com/expo/config-plugins/issues/178
|
||||
xit('should install', async () => {
|
||||
// run install command
|
||||
const installResults = await runCLIAsync(
|
||||
`install ${appName} --no-interactive --check`
|
||||
`install ${appName} --no-interactive`
|
||||
);
|
||||
expect(installResults.combinedOutput).toContain(
|
||||
'Dependencies are up to date'
|
||||
'Successfully ran target install'
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
@ -208,7 +208,8 @@
|
||||
"magic-string": "~0.26.2",
|
||||
"markdown-factory": "^0.0.6",
|
||||
"memfs": "^3.0.1",
|
||||
"metro-resolver": "^0.74.1",
|
||||
"metro-config": "0.76.7",
|
||||
"metro-resolver": "0.76.7",
|
||||
"mini-css-extract-plugin": "~2.4.7",
|
||||
"minimatch": "3.0.5",
|
||||
"next-sitemap": "^3.1.10",
|
||||
|
||||
@ -342,12 +342,6 @@ describe('detox application generator', () => {
|
||||
'cd ../../../my-dir/my-app/android && ./gradlew assembleDebug assembleAndroidTest -DtestBuildType=debug',
|
||||
type: 'android.apk',
|
||||
},
|
||||
'android.eas': {
|
||||
binaryPath: '../../../my-dir/my-app/dist/MyDirMyApp.apk',
|
||||
build:
|
||||
'npx nx run my-dir-my-app:download --platform android --distribution simulator --output=../../../my-dir/my-app/dist/',
|
||||
type: 'android.apk',
|
||||
},
|
||||
'android.local': {
|
||||
binaryPath: '../../../my-dir/my-app/dist/MyDirMyApp.apk',
|
||||
build:
|
||||
@ -368,12 +362,6 @@ describe('detox application generator', () => {
|
||||
"cd ../../../my-dir/my-app/ios && xcodebuild -workspace MyDirMyApp.xcworkspace -scheme MyDirMyApp -configuration Debug -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 14' -derivedDataPath ./build -quiet",
|
||||
type: 'ios.app',
|
||||
},
|
||||
'ios.eas': {
|
||||
binaryPath: '../../../my-dir/my-app/dist/MyDirMyApp.app',
|
||||
build:
|
||||
'npx nx run my-dir-my-app:download --platform ios --distribution simulator --output=../../../my-dir/my-app/dist/',
|
||||
type: 'ios.app',
|
||||
},
|
||||
'ios.local': {
|
||||
binaryPath: '../../../my-dir/my-app/dist/MyDirMyApp.app',
|
||||
build:
|
||||
|
||||
@ -20,11 +20,6 @@
|
||||
"binaryPath": "<%= offsetFromRoot %><%= appRoot %>/ios/build/Build/Products/Release-iphonesimulator/<%= appClassName %>.app"
|
||||
},
|
||||
<% if (framework === 'expo') { %>
|
||||
"ios.eas": {
|
||||
"type": "ios.app",
|
||||
"build": "<%= exec %> nx run <%= appFileName %>:download --platform ios --distribution simulator --output=<%= offsetFromRoot %><%= appRoot %>/dist/",
|
||||
"binaryPath": "<%= offsetFromRoot %><%= appRoot %>/dist/<%= appExpoName %>.app"
|
||||
},
|
||||
"ios.local": {
|
||||
"type": "ios.app",
|
||||
"build": "<%= exec %> nx run <%= appFileName %>:build --platform ios --profile preview --wait --local --no-interactive --output=<%= offsetFromRoot %><%= appRoot %>/dist/<%= appExpoName %>.tar.gz",
|
||||
@ -42,11 +37,6 @@
|
||||
"binaryPath": "<%= offsetFromRoot %><%= appRoot %>/android/app/build/outputs/apk/release/app-release.apk"
|
||||
},
|
||||
<% if (framework === 'expo') { %>
|
||||
"android.eas": {
|
||||
"type": "android.apk",
|
||||
"build": "<%= exec %> nx run <%= appFileName %>:download --platform android --distribution simulator --output=<%= offsetFromRoot %><%= appRoot %>/dist/",
|
||||
"binaryPath": "<%= offsetFromRoot %><%= appRoot %>/dist/<%= appExpoName %>.apk"
|
||||
},
|
||||
"android.local": {
|
||||
"type": "android.apk",
|
||||
"build": "<%= exec %> nx run <%= appFileName %>:build --platform android --profile preview --wait --local --no-interactive --output=<%= offsetFromRoot %><%= appRoot %>/dist/<%= appExpoName %>.apk",
|
||||
@ -78,10 +68,6 @@
|
||||
"app": "ios.debug"
|
||||
},
|
||||
<% if (framework === 'expo') { %>
|
||||
"ios.sim.eas": {
|
||||
"device": "simulator",
|
||||
"app": "ios.eas"
|
||||
},
|
||||
"ios.sim.local": {
|
||||
"device": "simulator",
|
||||
"app": "ios.local"
|
||||
@ -96,10 +82,6 @@
|
||||
"app": "android.debug"
|
||||
},
|
||||
<% if (framework === 'expo') { %>
|
||||
"android.emu.eas": {
|
||||
"device": "emulator",
|
||||
"app": "android.eas"
|
||||
},
|
||||
"android.emu.local": {
|
||||
"device": "emulator",
|
||||
"app": "android.local"
|
||||
|
||||
@ -4,14 +4,10 @@ describe('getTargets', () => {
|
||||
it('should return ios test target for expo projects', () => {
|
||||
expect(expoTestTarget('ios.sim', 'test')).toEqual({
|
||||
options: {
|
||||
detoxConfiguration: 'ios.sim.eas',
|
||||
detoxConfiguration: 'ios.sim.local',
|
||||
buildTarget: 'test:build-ios',
|
||||
},
|
||||
configurations: {
|
||||
local: {
|
||||
detoxConfiguration: 'ios.sim.local',
|
||||
buildTarget: 'test:build-ios:local',
|
||||
},
|
||||
bare: {
|
||||
detoxConfiguration: 'ios.sim.debug',
|
||||
buildTarget: 'test:build-ios:bare',
|
||||
@ -27,12 +23,9 @@ describe('getTargets', () => {
|
||||
it('should return ios build target for expo projects', () => {
|
||||
expect(expoBuildTarget('ios.sim')).toEqual({
|
||||
options: {
|
||||
detoxConfiguration: 'ios.sim.eas',
|
||||
detoxConfiguration: 'ios.sim.local',
|
||||
},
|
||||
configurations: {
|
||||
local: {
|
||||
detoxConfiguration: 'ios.sim.local',
|
||||
},
|
||||
bare: {
|
||||
detoxConfiguration: 'ios.sim.debug',
|
||||
},
|
||||
|
||||
@ -14,12 +14,9 @@ export function reactNativeBuildTarget(platform: 'ios.sim' | 'android.emu') {
|
||||
export function expoBuildTarget(platform: 'ios.sim' | 'android.emu') {
|
||||
return {
|
||||
options: {
|
||||
detoxConfiguration: `${platform}.eas`,
|
||||
detoxConfiguration: `${platform}.local`,
|
||||
},
|
||||
configurations: {
|
||||
local: {
|
||||
detoxConfiguration: `${platform}.local`,
|
||||
},
|
||||
bare: {
|
||||
detoxConfiguration: `${platform}.debug`,
|
||||
},
|
||||
@ -58,14 +55,10 @@ export function expoTestTarget(
|
||||
|
||||
return {
|
||||
options: {
|
||||
detoxConfiguration: `${platform}.eas`,
|
||||
detoxConfiguration: `${platform}.local`,
|
||||
buildTarget: `${e2eName}:build-${buildPlatform}`,
|
||||
},
|
||||
configurations: {
|
||||
local: {
|
||||
detoxConfiguration: `${platform}.local`,
|
||||
buildTarget: `${e2eName}:build-${buildPlatform}:local`,
|
||||
},
|
||||
bare: {
|
||||
detoxConfiguration: `${platform}.debug`,
|
||||
buildTarget: `${e2eName}:build-${buildPlatform}:bare`,
|
||||
|
||||
@ -65,6 +65,18 @@
|
||||
"cli": "nx",
|
||||
"description": "Add app.json for detox",
|
||||
"factory": "./src/migrations/update-16-1-4/add-detox-app-json"
|
||||
},
|
||||
"update-16-6-0-add-dependsOn": {
|
||||
"cli": "nx",
|
||||
"version": "16.6.0-beta.0",
|
||||
"description": "Add dependsOn like ensure-symlink or sync-deps to targets",
|
||||
"implementation": "./src/migrations/update-16-6-0/add-depends-on"
|
||||
},
|
||||
"update-16-6-0-update-metro-config": {
|
||||
"cli": "nx",
|
||||
"version": "16.6.0-beta.0",
|
||||
"description": "Update metro.config.js to use the new metro config format",
|
||||
"implementation": "./src/migrations/update-16-6-0/update-metro-config"
|
||||
}
|
||||
},
|
||||
"packageJsonUpdates": {
|
||||
@ -855,6 +867,67 @@
|
||||
"alwaysAddToPackageJson": false
|
||||
}
|
||||
}
|
||||
},
|
||||
"16.6.0": {
|
||||
"version": "16.6.0-beta.0",
|
||||
"packages": {
|
||||
"expo": {
|
||||
"version": "^49.0.3",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"@expo/metro-config": {
|
||||
"version": "~0.10.6",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"expo-splash-screen": {
|
||||
"version": "~0.20.4",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"expo-status-bar": {
|
||||
"version": "~1.6.0",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"@expo/cli": {
|
||||
"version": "~0.10.10",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"eas-cli": {
|
||||
"version": "~3.15.0",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"babel-preset-expo": {
|
||||
"version": "~9.5.0",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"jest-expo": {
|
||||
"version": "~49.0.0",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"metro-resolver": {
|
||||
"version": "0.76.7",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"metro": {
|
||||
"version": "0.76.7",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"react-native": {
|
||||
"version": "0.72.3",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"@types/react-native": {
|
||||
"version": "0.72.2",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"react-native-web": {
|
||||
"version": "~0.19.6",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"react-native-svg": {
|
||||
"version": "13.9.0",
|
||||
"alwaysAddToPackageJson": false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -29,7 +29,8 @@
|
||||
"chalk": "^4.1.0",
|
||||
"enhanced-resolve": "^5.8.3",
|
||||
"fs-extra": "^11.1.0",
|
||||
"metro-resolver": "^0.74.1",
|
||||
"metro-config": "0.76.7",
|
||||
"metro-resolver": "0.76.7",
|
||||
"node-fetch": "^2.6.7",
|
||||
"tar-fs": "^2.1.1",
|
||||
"tsconfig-paths": "^4.1.2",
|
||||
@ -43,7 +44,9 @@
|
||||
"@nx/webpack": "file:../webpack"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"expo": "^48.0.19"
|
||||
"expo": ">= 49.0.0",
|
||||
"@expo/cli": ">= 0.10.0",
|
||||
"eas-cli": ">= 3.15.0"
|
||||
},
|
||||
"builders": "./executors.json",
|
||||
"ng-update": {
|
||||
|
||||
@ -1,4 +1,6 @@
|
||||
import { workspaceLayout, workspaceRoot } from '@nx/devkit';
|
||||
import { mergeConfig } from 'metro-config';
|
||||
import type { MetroConfig } from 'metro-config';
|
||||
import { join } from 'path';
|
||||
import { existsSync } from 'fs-extra';
|
||||
|
||||
@ -7,35 +9,39 @@ import { getResolveRequest } from './metro-resolver';
|
||||
interface WithNxOptions {
|
||||
debug?: boolean;
|
||||
extensions?: string[];
|
||||
/**
|
||||
* @deprecated TODO(v17) in the metro.config.js, pass in to the getDefaultConfig instead: getDefaultConfig(__dirname)
|
||||
*/
|
||||
projectRoot?: string;
|
||||
watchFolders?: string[];
|
||||
}
|
||||
|
||||
export function withNxMetro(config: any, opts: WithNxOptions = {}) {
|
||||
export async function withNxMetro(
|
||||
userConfig: MetroConfig,
|
||||
opts: WithNxOptions = {}
|
||||
) {
|
||||
const extensions = ['', 'ts', 'tsx', 'js', 'jsx', 'json'];
|
||||
if (opts.debug) process.env.NX_REACT_NATIVE_DEBUG = 'true';
|
||||
if (opts.extensions) extensions.push(...opts.extensions);
|
||||
|
||||
config.projectRoot = opts.projectRoot || workspaceRoot;
|
||||
|
||||
// Add support for paths specified by tsconfig
|
||||
config.resolver = {
|
||||
...config.resolver,
|
||||
resolveRequest: getResolveRequest(extensions),
|
||||
};
|
||||
|
||||
let watchFolders = config.watchFolders || [];
|
||||
watchFolders = watchFolders.concat([
|
||||
let watchFolders = [
|
||||
join(workspaceRoot, 'node_modules'),
|
||||
join(workspaceRoot, workspaceLayout().libsDir),
|
||||
join(workspaceRoot, 'packages'),
|
||||
]);
|
||||
join(workspaceRoot, '.storybook'),
|
||||
];
|
||||
if (opts.watchFolders?.length) {
|
||||
watchFolders = watchFolders.concat(opts.watchFolders);
|
||||
}
|
||||
|
||||
watchFolders = watchFolders.filter((folder) => existsSync(folder));
|
||||
config.watchFolders = watchFolders;
|
||||
|
||||
return config;
|
||||
const nxConfig: MetroConfig = {
|
||||
resolver: {
|
||||
resolveRequest: getResolveRequest(extensions),
|
||||
},
|
||||
watchFolders,
|
||||
};
|
||||
|
||||
return mergeConfig(userConfig, nxConfig);
|
||||
}
|
||||
|
||||
@ -2,7 +2,7 @@ import { TsconfigPathsPlugin } from 'tsconfig-paths-webpack-plugin';
|
||||
import { resolve } from 'path';
|
||||
|
||||
/**
|
||||
* @deprecated use bundler: 'metro' instead, will be removed in 16.0.0
|
||||
* @deprecated TODO(v17) use bundler: 'metro' instead, will be removed in 16.0.0
|
||||
* This function add additional rules to expo's webpack config to make expo web working
|
||||
*/
|
||||
export async function withNxWebpack(config) {
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { ExecutorContext, logger, names } from '@nx/devkit';
|
||||
import { join } from 'path';
|
||||
import { resolve as pathResolve } from 'path';
|
||||
import { ChildProcess, fork } from 'child_process';
|
||||
|
||||
import { ensureNodeModulesSymlink } from '../../utils/ensure-node-modules-symlink';
|
||||
@ -42,10 +42,10 @@ export function runCliBuildList(
|
||||
): Promise<string> {
|
||||
return new Promise((resolve, reject) => {
|
||||
childProcess = fork(
|
||||
join(workspaceRoot, './node_modules/eas-cli/bin/run'),
|
||||
require.resolve('eas-cli/bin/run'),
|
||||
['build:list', ...createBuildListOptions(options)],
|
||||
{
|
||||
cwd: join(workspaceRoot, projectRoot),
|
||||
cwd: pathResolve(workspaceRoot, projectRoot),
|
||||
env: process.env,
|
||||
stdio: ['inherit', 'pipe', 'inherit', 'ipc'], // only stream stdout on child process
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { ExecutorContext, names } from '@nx/devkit';
|
||||
import { join, normalize, sep } from 'path';
|
||||
import { ExecutorContext, names, output } from '@nx/devkit';
|
||||
import { normalize, sep, resolve as pathResolve, dirname } from 'path';
|
||||
import { ChildProcess, fork } from 'child_process';
|
||||
|
||||
import { ensureNodeModulesSymlink } from '../../utils/ensure-node-modules-symlink';
|
||||
@ -20,21 +20,22 @@ export default async function* buildExecutor(
|
||||
): AsyncGenerator<ReactNativeBuildOutput> {
|
||||
const projectRoot =
|
||||
context.projectsConfigurations.projects[context.projectName].root;
|
||||
ensureNodeModulesSymlink(context.root, projectRoot);
|
||||
|
||||
try {
|
||||
// remove the output app if it already existed
|
||||
if (options.local && options.output) {
|
||||
removeSync(options.output);
|
||||
if (options.output.endsWith('.tar.gz')) {
|
||||
// remove unzipped app if it already existed
|
||||
removeSync(options.output.replace('.tar.gz', '.app'));
|
||||
}
|
||||
}
|
||||
|
||||
await runCliBuild(context.root, projectRoot, options);
|
||||
|
||||
// unzip the build if it's a tar.gz
|
||||
if (options.local && options.output && options.output.endsWith('.tar.gz')) {
|
||||
const directoryPath = normalize(options.output).split(sep);
|
||||
directoryPath.pop();
|
||||
const outputDirectory = directoryPath.join(sep);
|
||||
const outputDirectory = dirname(options.output);
|
||||
await unzipBuild(options.output, outputDirectory);
|
||||
}
|
||||
yield { success: true };
|
||||
@ -52,10 +53,10 @@ function runCliBuild(
|
||||
) {
|
||||
return new Promise((resolve, reject) => {
|
||||
childProcess = fork(
|
||||
join(workspaceRoot, './node_modules/eas-cli/bin/run'),
|
||||
require.resolve('eas-cli/bin/run'),
|
||||
['build', ...createBuildOptions(options)],
|
||||
{
|
||||
cwd: join(workspaceRoot, projectRoot),
|
||||
cwd: pathResolve(workspaceRoot, projectRoot),
|
||||
env: process.env,
|
||||
}
|
||||
);
|
||||
|
||||
@ -55,7 +55,8 @@
|
||||
},
|
||||
"output": {
|
||||
"type": "string",
|
||||
"description": "Output path for local build"
|
||||
"description": "Output path for local build",
|
||||
"examples": ["../../dist/MyApp.tar.gz", "../../dist"]
|
||||
},
|
||||
"wait": {
|
||||
"type": "boolean",
|
||||
|
||||
@ -28,6 +28,7 @@ export interface ReactNativeDownloadOutput {
|
||||
const streamPipeline = promisify(pipeline);
|
||||
|
||||
/**
|
||||
* @deprecated TODO(v17) this executor is to be removed in NX 17. It is no longer used.
|
||||
* This executor downloads the latest EAS build.
|
||||
* It calls the build list executor to list EAS builds with options passed in.
|
||||
*/
|
||||
|
||||
@ -1,8 +1,7 @@
|
||||
import { ExecutorContext, names } from '@nx/devkit';
|
||||
import { ChildProcess, fork } from 'child_process';
|
||||
import { join } from 'path';
|
||||
import { resolve as pathResolve } from 'path';
|
||||
|
||||
import { ensureNodeModulesSymlink } from '../../utils/ensure-node-modules-symlink';
|
||||
import { ExportExecutorSchema } from './schema';
|
||||
|
||||
export interface ExpoExportOutput {
|
||||
@ -17,7 +16,6 @@ export default async function* exportExecutor(
|
||||
): AsyncGenerator<ExpoExportOutput> {
|
||||
const projectRoot =
|
||||
context.projectsConfigurations.projects[context.projectName].root;
|
||||
ensureNodeModulesSymlink(context.root, projectRoot);
|
||||
|
||||
try {
|
||||
await exportAsync(context.root, projectRoot, options);
|
||||
@ -39,13 +37,13 @@ function exportAsync(
|
||||
): Promise<number> {
|
||||
return new Promise((resolve, reject) => {
|
||||
childProcess = fork(
|
||||
join(workspaceRoot, './node_modules/@expo/cli/build/bin/cli'),
|
||||
require.resolve('@expo/cli/build/bin/cli'),
|
||||
[
|
||||
`export${options.bundler === 'webpack' ? ':web' : ''}`,
|
||||
'.',
|
||||
...createExportOptions(options),
|
||||
],
|
||||
{ cwd: join(workspaceRoot, projectRoot), env: process.env }
|
||||
{ cwd: pathResolve(workspaceRoot, projectRoot), env: process.env }
|
||||
);
|
||||
|
||||
// Ensure the child process is killed when the parent exits
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
import { ExecutorContext, names } from '@nx/devkit';
|
||||
import { ChildProcess, fork } from 'child_process';
|
||||
import { join } from 'path';
|
||||
|
||||
import { ensureNodeModulesSymlink } from '../../utils/ensure-node-modules-symlink';
|
||||
import { ExpoInstallOptions } from './schema';
|
||||
@ -38,7 +37,7 @@ export function installAsync(
|
||||
): Promise<number> {
|
||||
return new Promise((resolve, reject) => {
|
||||
childProcess = fork(
|
||||
join(workspaceRoot, './node_modules/@expo/cli/build/bin/cli'),
|
||||
require.resolve('@expo/cli/build/bin/cli'),
|
||||
['install', ...createInstallOptions(options)],
|
||||
{ cwd: workspaceRoot, env: process.env }
|
||||
);
|
||||
|
||||
@ -27,7 +27,7 @@ export default async function* prebuildExecutor(
|
||||
if (options.install) {
|
||||
await installAsync(context.root, {});
|
||||
if (options.platform === 'ios') {
|
||||
await podInstall(join(context.root, projectRoot, 'ios'));
|
||||
podInstall(join(context.root, projectRoot, 'ios'));
|
||||
}
|
||||
}
|
||||
|
||||
@ -48,7 +48,7 @@ export function prebuildAsync(
|
||||
): Promise<number> {
|
||||
return new Promise((resolve, reject) => {
|
||||
childProcess = fork(
|
||||
join(workspaceRoot, './node_modules/@expo/cli/build/bin/cli'),
|
||||
require.resolve('@expo/cli/build/bin/cli'),
|
||||
['prebuild', ...createPrebuildOptions(options), '--no-install'],
|
||||
{ cwd: join(workspaceRoot, projectRoot), env: process.env }
|
||||
);
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { ExecutorContext, names } from '@nx/devkit';
|
||||
import { join } from 'path';
|
||||
import { join, resolve as pathResolve } from 'path';
|
||||
import { ChildProcess, fork } from 'child_process';
|
||||
import { platform } from 'os';
|
||||
import { existsSync } from 'fs-extra';
|
||||
@ -29,18 +29,6 @@ export default async function* runExecutor(
|
||||
}
|
||||
const projectRoot =
|
||||
context.projectsConfigurations.projects[context.projectName].root;
|
||||
ensureNodeModulesSymlink(context.root, projectRoot);
|
||||
if (options.sync) {
|
||||
displayNewlyAddedDepsMessage(
|
||||
context.projectName,
|
||||
await syncDeps(
|
||||
context.projectName,
|
||||
projectRoot,
|
||||
context.root,
|
||||
context.projectGraph
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if (!existsSync(join(context.root, projectRoot, options.platform))) {
|
||||
await prebuildAsync(context.root, projectRoot, {
|
||||
@ -53,7 +41,7 @@ export default async function* runExecutor(
|
||||
if (options.install) {
|
||||
await installAsync(context.root, {});
|
||||
if (options.platform === 'ios') {
|
||||
await podInstall(join(context.root, projectRoot, 'ios'));
|
||||
podInstall(join(context.root, projectRoot, 'ios'));
|
||||
}
|
||||
}
|
||||
|
||||
@ -75,10 +63,11 @@ function runCliRun(
|
||||
) {
|
||||
return new Promise((resolve, reject) => {
|
||||
childProcess = fork(
|
||||
join(workspaceRoot, './node_modules/@expo/cli/build/bin/cli'),
|
||||
require.resolve('@expo/cli/build/bin/cli'),
|
||||
['run:' + options.platform, ...createRunOptions(options), '--no-install'], // pass in no-install to prevent node_modules install
|
||||
{
|
||||
cwd: projectRoot,
|
||||
cwd: pathResolve(workspaceRoot, projectRoot),
|
||||
env: process.env,
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
3
packages/expo/src/executors/run/schema.d.ts
vendored
3
packages/expo/src/executors/run/schema.d.ts
vendored
@ -6,6 +6,9 @@
|
||||
export interface ExpoRunOptions {
|
||||
// nx options
|
||||
platform: 'ios' | 'android';
|
||||
/**
|
||||
* @deprecated TODO(v17) Add sync-deps to dependsOn in project.json for this target instead
|
||||
*/
|
||||
sync: boolean; // default is true
|
||||
install?: boolean; // default is true
|
||||
clean?: boolean; // default is false
|
||||
|
||||
@ -39,6 +39,7 @@
|
||||
"type": "boolean",
|
||||
"description": "Syncs npm dependencies to package.json (for React Native autolink).",
|
||||
"default": true,
|
||||
"x-deprecated": "Add sync-deps to dependsOn in project.json for this target instead",
|
||||
"x-priority": "internal"
|
||||
},
|
||||
"port": {
|
||||
|
||||
@ -20,6 +20,8 @@ export interface ExpoStartOptions {
|
||||
tunnel?: boolean;
|
||||
offline?: boolean;
|
||||
|
||||
// nx options
|
||||
/**
|
||||
* @deprecated TODO(v17) Add sync-deps to dependsOn in project.json for this target instead
|
||||
*/
|
||||
sync?: boolean; // default is true
|
||||
}
|
||||
|
||||
@ -91,6 +91,7 @@
|
||||
"sync": {
|
||||
"type": "boolean",
|
||||
"description": "Syncs npm dependencies to package.json (for React Native autolink).",
|
||||
"x-deprecated": "Add sync-deps to dependsOn in project.json for this target instead",
|
||||
"default": true
|
||||
}
|
||||
},
|
||||
|
||||
@ -1,14 +1,9 @@
|
||||
import * as chalk from 'chalk';
|
||||
import { ExecutorContext, logger, names } from '@nx/devkit';
|
||||
import { ChildProcess, fork } from 'child_process';
|
||||
import { join } from 'path';
|
||||
import { resolve as pathResolve } from 'path';
|
||||
|
||||
import { ensureNodeModulesSymlink } from '../../utils/ensure-node-modules-symlink';
|
||||
import { ExpoStartOptions } from './schema';
|
||||
import {
|
||||
displayNewlyAddedDepsMessage,
|
||||
syncDeps,
|
||||
} from '../sync-deps/sync-deps.impl';
|
||||
|
||||
export interface ExpoStartOutput {
|
||||
baseUrl?: string;
|
||||
@ -23,18 +18,6 @@ export default async function* startExecutor(
|
||||
): AsyncGenerator<ExpoStartOutput> {
|
||||
const projectRoot =
|
||||
context.projectsConfigurations.projects[context.projectName].root;
|
||||
ensureNodeModulesSymlink(context.root, projectRoot);
|
||||
if (options.sync) {
|
||||
displayNewlyAddedDepsMessage(
|
||||
context.projectName,
|
||||
await syncDeps(
|
||||
context.projectName,
|
||||
projectRoot,
|
||||
context.root,
|
||||
context.projectGraph
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
try {
|
||||
const baseUrl = `http://localhost:${options.port}`;
|
||||
@ -60,9 +43,9 @@ function startAsync(
|
||||
): Promise<number> {
|
||||
return new Promise((resolve, reject) => {
|
||||
childProcess = fork(
|
||||
join(workspaceRoot, './node_modules/@expo/cli/build/bin/cli'),
|
||||
require.resolve('@expo/cli/build/bin/cli'),
|
||||
['start', ...createStartOptions(options)],
|
||||
{ cwd: join(workspaceRoot, projectRoot), env: process.env }
|
||||
{ cwd: pathResolve(workspaceRoot, projectRoot), env: process.env }
|
||||
);
|
||||
|
||||
// Ensure the child process is killed when the parent exits
|
||||
|
||||
@ -1,9 +1,7 @@
|
||||
import { ExecutorContext, names } from '@nx/devkit';
|
||||
import { join } from 'path';
|
||||
import { resolve as pathResolve } from 'path';
|
||||
import { ChildProcess, fork } from 'child_process';
|
||||
|
||||
import { ensureNodeModulesSymlink } from '../../utils/ensure-node-modules-symlink';
|
||||
|
||||
import { SubmitExecutorSchema } from './schema';
|
||||
|
||||
export interface ReactNativeSubmitOutput {
|
||||
@ -18,7 +16,6 @@ export default async function* submitExecutor(
|
||||
): AsyncGenerator<ReactNativeSubmitOutput> {
|
||||
const projectRoot =
|
||||
context.projectsConfigurations.projects[context.projectName].root;
|
||||
ensureNodeModulesSymlink(context.root, projectRoot);
|
||||
|
||||
try {
|
||||
await runCliSubmit(context.root, projectRoot, options);
|
||||
@ -38,10 +35,10 @@ function runCliSubmit(
|
||||
) {
|
||||
return new Promise((resolve, reject) => {
|
||||
childProcess = fork(
|
||||
join(workspaceRoot, './node_modules/eas-cli/bin/run'),
|
||||
require.resolve('eas-cli/bin/run'),
|
||||
['submit', ...createSubmitOptions(options)],
|
||||
{
|
||||
cwd: join(workspaceRoot, projectRoot),
|
||||
cwd: pathResolve(workspaceRoot, projectRoot),
|
||||
env: process.env,
|
||||
}
|
||||
);
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { ExecutorContext, names } from '@nx/devkit';
|
||||
import { join } from 'path';
|
||||
import { resolve as pathResolve } from 'path';
|
||||
import { ChildProcess, fork } from 'child_process';
|
||||
|
||||
import { ensureNodeModulesSymlink } from '../../utils/ensure-node-modules-symlink';
|
||||
@ -53,9 +53,9 @@ function runCliUpdate(
|
||||
) {
|
||||
return new Promise((resolve, reject) => {
|
||||
childProcess = fork(
|
||||
join(workspaceRoot, './node_modules/eas-cli/bin/run'),
|
||||
require.resolve('eas-cli/bin/run'),
|
||||
['update', ...createUpdateOptions(options)],
|
||||
{ cwd: join(workspaceRoot, projectRoot), env: process.env }
|
||||
{ cwd: pathResolve(workspaceRoot, projectRoot), env: process.env }
|
||||
);
|
||||
|
||||
// Ensure the child process is killed when the parent exits
|
||||
|
||||
@ -121,12 +121,6 @@ describe('app', () => {
|
||||
'cd ../../../apps/my-dir/my-app/android && ./gradlew assembleDebug assembleAndroidTest -DtestBuildType=debug',
|
||||
type: 'android.apk',
|
||||
},
|
||||
'android.eas': {
|
||||
binaryPath: '../../../apps/my-dir/my-app/dist/MyApp.apk',
|
||||
build:
|
||||
'npx nx run my-app:download --platform android --distribution simulator --output=../../../apps/my-dir/my-app/dist/',
|
||||
type: 'android.apk',
|
||||
},
|
||||
'android.local': {
|
||||
binaryPath: '../../../apps/my-dir/my-app/dist/MyApp.apk',
|
||||
build:
|
||||
@ -147,12 +141,6 @@ describe('app', () => {
|
||||
"cd ../../../apps/my-dir/my-app/ios && xcodebuild -workspace MyApp.xcworkspace -scheme MyApp -configuration Debug -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 14' -derivedDataPath ./build -quiet",
|
||||
type: 'ios.app',
|
||||
},
|
||||
'ios.eas': {
|
||||
binaryPath: '../../../apps/my-dir/my-app/dist/MyApp.app',
|
||||
build:
|
||||
'npx nx run my-app:download --platform ios --distribution simulator --output=../../../apps/my-dir/my-app/dist/',
|
||||
type: 'ios.app',
|
||||
},
|
||||
'ios.local': {
|
||||
binaryPath: '../../../apps/my-dir/my-app/dist/MyApp.app',
|
||||
build:
|
||||
@ -196,12 +184,6 @@ describe('app', () => {
|
||||
'cd ../../apps/my-app/android && ./gradlew assembleDebug assembleAndroidTest -DtestBuildType=debug',
|
||||
type: 'android.apk',
|
||||
},
|
||||
'android.eas': {
|
||||
binaryPath: '../../apps/my-app/dist/MyApp.apk',
|
||||
build:
|
||||
'npx nx run my-app:download --platform android --distribution simulator --output=../../apps/my-app/dist/',
|
||||
type: 'android.apk',
|
||||
},
|
||||
'android.local': {
|
||||
binaryPath: '../../apps/my-app/dist/MyApp.apk',
|
||||
build:
|
||||
@ -222,12 +204,6 @@ describe('app', () => {
|
||||
"cd ../../apps/my-app/ios && xcodebuild -workspace MyApp.xcworkspace -scheme MyApp -configuration Debug -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 14' -derivedDataPath ./build -quiet",
|
||||
type: 'ios.app',
|
||||
},
|
||||
'ios.eas': {
|
||||
binaryPath: '../../apps/my-app/dist/MyApp.app',
|
||||
build:
|
||||
'npx nx run my-app:download --platform ios --distribution simulator --output=../../apps/my-app/dist/',
|
||||
type: 'ios.app',
|
||||
},
|
||||
'ios.local': {
|
||||
binaryPath: '../../apps/my-app/dist/MyApp.app',
|
||||
build:
|
||||
@ -272,12 +248,6 @@ describe('app', () => {
|
||||
'cd ../../apps/my-app/android && ./gradlew assembleDebug assembleAndroidTest -DtestBuildType=debug',
|
||||
type: 'android.apk',
|
||||
},
|
||||
'android.eas': {
|
||||
binaryPath: '../../apps/my-app/dist/myappname.apk',
|
||||
build:
|
||||
'npx nx run my-app:download --platform android --distribution simulator --output=../../apps/my-app/dist/',
|
||||
type: 'android.apk',
|
||||
},
|
||||
'android.local': {
|
||||
binaryPath: '../../apps/my-app/dist/myappname.apk',
|
||||
build:
|
||||
@ -298,12 +268,6 @@ describe('app', () => {
|
||||
"cd ../../apps/my-app/ios && xcodebuild -workspace MyApp.xcworkspace -scheme MyApp -configuration Debug -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 14' -derivedDataPath ./build -quiet",
|
||||
type: 'ios.app',
|
||||
},
|
||||
'ios.eas': {
|
||||
binaryPath: '../../apps/my-app/dist/myappname.app',
|
||||
build:
|
||||
'npx nx run my-app:download --platform ios --distribution simulator --output=../../apps/my-app/dist/',
|
||||
type: 'ios.app',
|
||||
},
|
||||
'ios.local': {
|
||||
binaryPath: '../../apps/my-app/dist/myappname.app',
|
||||
build:
|
||||
|
||||
@ -1,25 +1,37 @@
|
||||
const { withNxMetro } = require('@nx/expo');
|
||||
const { getDefaultConfig } = require('@expo/metro-config');
|
||||
const { mergeConfig } = require('metro-config');
|
||||
const exclusionList = require('metro-config/src/defaults/exclusionList');
|
||||
|
||||
const defaultConfig = getDefaultConfig(__dirname);
|
||||
const { assetExts, sourceExts } = defaultConfig.resolver;
|
||||
|
||||
module.exports = (async () => {
|
||||
defaultConfig.transformer.babelTransformerPath = require.resolve(
|
||||
'react-native-svg-transformer'
|
||||
);
|
||||
defaultConfig.resolver.assetExts = defaultConfig.resolver.assetExts.filter(
|
||||
(ext) => ext !== 'svg'
|
||||
);
|
||||
defaultConfig.resolver.sourceExts.push('svg');
|
||||
return withNxMetro(defaultConfig, {
|
||||
// Change this to true to see debugging info.
|
||||
// Useful if you have issues resolving modules
|
||||
debug: false,
|
||||
// all the file extensions used for imports other than 'ts', 'tsx', 'js', 'jsx'
|
||||
extensions: [],
|
||||
// the project root to start the metro server
|
||||
projectRoot: __dirname,
|
||||
// Specify any additional (to projectRoot) watch folders, this is used to know which files to watch
|
||||
watchFolders: []
|
||||
});
|
||||
})();
|
||||
/**
|
||||
* Metro configuration
|
||||
* https://facebook.github.io/metro/docs/configuration
|
||||
*
|
||||
* @type {import('metro-config').MetroConfig}
|
||||
*/
|
||||
const customConfig = {
|
||||
transformer: {
|
||||
babelTransformerPath: require.resolve('react-native-svg-transformer'),
|
||||
},
|
||||
resolver: {
|
||||
assetExts: assetExts.filter((ext) => ext !== 'svg'),
|
||||
sourceExts: [...sourceExts, 'svg'],
|
||||
blockList: exclusionList([/^(?!.*node_modules).*\/dist\/.*/]),
|
||||
unstable_enableSymlinks: true,
|
||||
unstable_enablePackageExports: true,
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
module.exports = withNxMetro(mergeConfig(defaultConfig, customConfig), {
|
||||
// Change this to true to see debugging info.
|
||||
// Useful if you have issues resolving modules
|
||||
debug: false,
|
||||
// all the file extensions used for imports other than 'ts', 'tsx', 'js', 'jsx', 'json'
|
||||
extensions: [],
|
||||
// Specify folders to watch, in addition to Nx defaults (workspace libraries and node_modules)
|
||||
watchFolders: [],
|
||||
});
|
||||
|
||||
@ -5,6 +5,7 @@
|
||||
"dependencies": {
|
||||
"@testing-library/jest-native": "*",
|
||||
"@testing-library/react-native": "*",
|
||||
"metro-config": "*",
|
||||
"react-native": "*",
|
||||
"expo": "*",
|
||||
"react-native-svg": "*",
|
||||
|
||||
@ -29,6 +29,7 @@ function getTargets(options: NormalizedSchema) {
|
||||
|
||||
architect.start = {
|
||||
executor: '@nx/expo:start',
|
||||
dependsOn: ['ensure-symlink', 'sync-deps'],
|
||||
options: {
|
||||
port: 8081,
|
||||
},
|
||||
@ -43,6 +44,7 @@ function getTargets(options: NormalizedSchema) {
|
||||
|
||||
architect['run-ios'] = {
|
||||
executor: '@nx/expo:run',
|
||||
dependsOn: ['ensure-symlink', 'sync-deps'],
|
||||
options: {
|
||||
platform: 'ios',
|
||||
},
|
||||
@ -50,6 +52,7 @@ function getTargets(options: NormalizedSchema) {
|
||||
|
||||
architect['run-android'] = {
|
||||
executor: '@nx/expo:run',
|
||||
dependsOn: ['ensure-symlink', 'sync-deps'],
|
||||
options: {
|
||||
platform: 'android',
|
||||
},
|
||||
@ -70,6 +73,9 @@ function getTargets(options: NormalizedSchema) {
|
||||
options: {},
|
||||
};
|
||||
|
||||
/**
|
||||
* @deprecated TODO(v17) this executor is no longer used, to be removed in v17
|
||||
*/
|
||||
architect['download'] = {
|
||||
executor: '@nx/expo:download',
|
||||
options: {
|
||||
@ -89,6 +95,7 @@ function getTargets(options: NormalizedSchema) {
|
||||
|
||||
architect['prebuild'] = {
|
||||
executor: '@nx/expo:prebuild',
|
||||
dependsOn: ['ensure-symlink', 'sync-deps'],
|
||||
options: {},
|
||||
};
|
||||
|
||||
@ -104,6 +111,7 @@ function getTargets(options: NormalizedSchema) {
|
||||
|
||||
architect['export'] = {
|
||||
executor: '@nx/expo:export',
|
||||
dependsOn: ['ensure-symlink', 'sync-deps'],
|
||||
options: {
|
||||
platform: 'all',
|
||||
outputDir: `${offsetFromRoot(options.appProjectRoot)}dist/${
|
||||
|
||||
21
packages/expo/src/migrations/update-16-6-0/add-depends-on.ts
Normal file
21
packages/expo/src/migrations/update-16-6-0/add-depends-on.ts
Normal file
@ -0,0 +1,21 @@
|
||||
import { Tree, getProjects, updateProjectConfiguration } from '@nx/devkit';
|
||||
|
||||
/**
|
||||
* This migration adds dependsOn to project.json.
|
||||
*
|
||||
*/
|
||||
export default async function update(tree: Tree) {
|
||||
const projects = getProjects(tree);
|
||||
|
||||
for (const [name, config] of projects.entries()) {
|
||||
if (config.targets?.['start']?.executor === '@nx/expo:start') {
|
||||
config.targets['start'].dependsOn = ['ensure-symlink', 'sync-deps'];
|
||||
config.targets['run-ios'].dependsOn = ['ensure-symlink', 'sync-deps'];
|
||||
config.targets['run-android'].dependsOn = ['ensure-symlink', 'sync-deps'];
|
||||
config.targets['prebuild'].dependsOn = ['ensure-symlink', 'sync-deps'];
|
||||
config.targets['export'].dependsOn = ['ensure-symlink', 'sync-deps'];
|
||||
|
||||
updateProjectConfiguration(tree, name, config);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,73 @@
|
||||
import { Tree, getProjects } from '@nx/devkit';
|
||||
import { join } from 'path';
|
||||
|
||||
/**
|
||||
* This migration updates metro.config.js to export config as a default.
|
||||
*
|
||||
*/
|
||||
export default async function update(tree: Tree) {
|
||||
const projects = getProjects(tree);
|
||||
|
||||
for (const [_, config] of projects.entries()) {
|
||||
if (config.targets?.['start']?.executor === '@nx/expo:start') {
|
||||
if (tree.exists(join(config.root, 'metro.config.js'))) {
|
||||
const oldConfig = tree
|
||||
.read(join(config.root, 'metro.config.js'))
|
||||
.toString();
|
||||
tree.write(
|
||||
join(config.root, 'metro-v71.config.js'),
|
||||
oldConfigComment + oldConfig
|
||||
);
|
||||
tree.write(join(config.root, 'metro.config.js'), content);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const oldConfigComment = `/**
|
||||
* Old custom configuration for React Native v0.71.
|
||||
* From @react-native/metro-config 0.72.1, it is no longer necessary to use a config function to access the complete default config.
|
||||
* Please port your custom configuration to metro.config.js.
|
||||
* Please see https://docs.expo.dev/guides/customizing-metro/ to learn about configuration.
|
||||
*/
|
||||
`;
|
||||
|
||||
const content = `
|
||||
const { withNxMetro } = require('@nx/expo');
|
||||
const { getDefaultConfig } = require('@expo/metro-config');
|
||||
const { mergeConfig } = require('metro-config');
|
||||
const exclusionList = require('metro-config/src/defaults/exclusionList');
|
||||
|
||||
const defaultConfig = getDefaultConfig(__dirname);
|
||||
const { assetExts, sourceExts } = defaultConfig.resolver;
|
||||
|
||||
/**
|
||||
* Metro configuration
|
||||
* https://facebook.github.io/metro/docs/configuration
|
||||
*
|
||||
* @type {import('metro-config').MetroConfig}
|
||||
*/
|
||||
const customConfig = {
|
||||
transformer: {
|
||||
babelTransformerPath: require.resolve('react-native-svg-transformer'),
|
||||
},
|
||||
resolver: {
|
||||
assetExts: assetExts.filter((ext) => ext !== 'svg'),
|
||||
sourceExts: [...sourceExts, 'svg'],
|
||||
blockList: exclusionList([/^(?!.*node_modules).*\/dist\/.*/]),
|
||||
unstable_enableSymlinks: true,
|
||||
unstable_enablePackageExports: true,
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
module.exports = withNxMetro(mergeConfig(defaultConfig, customConfig), {
|
||||
// Change this to true to see debugging info.
|
||||
// Useful if you have issues resolving modules
|
||||
debug: false,
|
||||
// all the file extensions used for imports other than 'ts', 'tsx', 'js', 'jsx', 'json'
|
||||
extensions: [],
|
||||
// Specify folders to watch, in addition to Nx defaults (workspace libraries and node_modules)
|
||||
watchFolders: [],
|
||||
});
|
||||
`;
|
||||
@ -1,28 +1,27 @@
|
||||
export const nxVersion = require('../../package.json').version;
|
||||
|
||||
export const expoVersion = '48.0.19';
|
||||
export const expoMetroConfigVersion = '0.7.1';
|
||||
export const expoSplashScreenVersion = '~0.18.2';
|
||||
export const expoStatusBarVersion = '~1.4.4';
|
||||
export const expoUpdatesVersion = '~0.16.4';
|
||||
export const expoCliVersion = '~0.7.3'; // @expo/cli
|
||||
export const easCliVersion = '~3.13.3';
|
||||
export const babelPresetExpoVersion = '~9.3.2';
|
||||
export const expoVersion = '49.0.3';
|
||||
export const expoMetroConfigVersion = '~0.10.6';
|
||||
export const expoSplashScreenVersion = '~0.20.4';
|
||||
export const expoStatusBarVersion = '~1.6.0';
|
||||
export const expoCliVersion = '~0.10.10'; // @expo/cli
|
||||
export const easCliVersion = '~3.15.1';
|
||||
export const babelPresetExpoVersion = '~9.5.0';
|
||||
|
||||
export const reactVersion = '18.2.0';
|
||||
export const reactDomVersion = '18.2.0';
|
||||
export const reactTestRendererVersion = '18.2.0';
|
||||
export const typesReactVersion = '18.0.28';
|
||||
|
||||
export const reactNativeVersion = '0.71.8';
|
||||
export const typesReactNativeVersion = '0.71.7';
|
||||
export const reactNativeWebVersion = '~0.18.12';
|
||||
export const reactNativeVersion = '0.72.3';
|
||||
export const typesReactNativeVersion = '0.72.2';
|
||||
export const reactNativeWebVersion = '~0.19.6';
|
||||
|
||||
export const reactNativeSvgTransformerVersion = '1.0.0';
|
||||
export const reactNativeSvgVersion = '13.4.0';
|
||||
export const reactNativeSvgVersion = '13.9.0';
|
||||
|
||||
export const metroVersion = '0.74.1';
|
||||
export const metroVersion = '0.76.7';
|
||||
|
||||
export const testingLibraryReactNativeVersion = '12.1.2';
|
||||
export const testingLibraryJestNativeVersion = '5.4.2';
|
||||
export const jestExpoVersion = '~48.0.2';
|
||||
export const jestExpoVersion = '~49.0.0';
|
||||
|
||||
@ -89,6 +89,18 @@
|
||||
"version": "16.1.0-beta.0",
|
||||
"description": "Upgrade @storybook/react-native to 6.5",
|
||||
"implementation": "./src/migrations/update-16-1-0/upgrade-storybook-6-5"
|
||||
},
|
||||
"update-16-6-0-add-dependsOn": {
|
||||
"cli": "nx",
|
||||
"version": "16.6.0-beta.0",
|
||||
"description": "Add dependsOn like ensure-symlink or sync-deps to targets",
|
||||
"implementation": "./src/migrations/update-16-6-0/add-depends-on"
|
||||
},
|
||||
"update-16-6-0-update-metro-config": {
|
||||
"cli": "nx",
|
||||
"version": "16.6.0-beta.0",
|
||||
"description": "Update metro.config.js to use the new metro config format",
|
||||
"implementation": "./src/migrations/update-16-6-0/update-metro-config"
|
||||
}
|
||||
},
|
||||
"packageJsonUpdates": {
|
||||
@ -1348,6 +1360,72 @@
|
||||
"alwaysAddToPackageJson": false
|
||||
}
|
||||
}
|
||||
},
|
||||
"16.6.0": {
|
||||
"version": "16.6.0-beta.0",
|
||||
"packages": {
|
||||
"react-native": {
|
||||
"version": "0.72.3",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"@types/react-native": {
|
||||
"version": "0.72.2",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"metro": {
|
||||
"version": "0.76.7",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"metro-resolver": {
|
||||
"version": "0.76.7",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"metro-config": {
|
||||
"version": "0.76.7",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"metro-react-native-babel-preset": {
|
||||
"version": "0.76.7",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"metro-babel-register": {
|
||||
"version": "0.76.7",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"metro-react-native-babel-transformer": {
|
||||
"version": "0.76.7",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"@react-native/metro-config": {
|
||||
"version": "^0.72.9",
|
||||
"alwaysAddToPackageJson": false,
|
||||
"addToPackageJson": "devDependencies"
|
||||
},
|
||||
"@react-native-community/cli": {
|
||||
"version": "11.3.5",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"@react-native-community/cli-platform-android": {
|
||||
"version": "11.3.5",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"@react-native-community/cli-platform-ios": {
|
||||
"version": "11.3.5",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"@babel/runtime": {
|
||||
"version": "7.22.6",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"@react-native-async-storage/async-storage": {
|
||||
"version": "1.19.0",
|
||||
"alwaysAddToPackageJson": false
|
||||
},
|
||||
"react-native-safe-area-context": {
|
||||
"version": "4.7.1",
|
||||
"alwaysAddToPackageJson": false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -30,7 +30,8 @@
|
||||
"fs-extra": "^11.1.0",
|
||||
"glob": "7.1.4",
|
||||
"ignore": "^5.0.4",
|
||||
"metro-resolver": "^0.74.1",
|
||||
"metro-config": "0.76.7",
|
||||
"metro-resolver": "0.76.7",
|
||||
"minimatch": "3.0.5",
|
||||
"node-fetch": "^2.6.7",
|
||||
"tsconfig-paths": "^4.1.2",
|
||||
@ -43,7 +44,7 @@
|
||||
"@nx/workspace": "file:../workspace"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react-native": ">= 0.71.0"
|
||||
"react-native": ">= 0.72.0 < 0.73.0"
|
||||
},
|
||||
"builders": "./executors.json",
|
||||
"ng-update": {
|
||||
|
||||
@ -1,4 +1,6 @@
|
||||
import { workspaceLayout, workspaceRoot } from '@nx/devkit';
|
||||
import { mergeConfig } from 'metro-config';
|
||||
import type { MetroConfig } from 'metro-config';
|
||||
import { join } from 'path';
|
||||
import { existsSync } from 'fs-extra';
|
||||
|
||||
@ -7,36 +9,39 @@ import { getResolveRequest } from './metro-resolver';
|
||||
interface WithNxOptions {
|
||||
debug?: boolean;
|
||||
extensions?: string[];
|
||||
/**
|
||||
* @deprecated TODO(v17) in the metro.config.js, pass in to the getDefaultConfig instead: getDefaultConfig(__dirname)
|
||||
*/
|
||||
projectRoot?: string;
|
||||
watchFolders?: string[];
|
||||
}
|
||||
|
||||
export function withNxMetro(config: any, opts: WithNxOptions = {}) {
|
||||
export async function withNxMetro(
|
||||
userConfig: MetroConfig,
|
||||
opts: WithNxOptions = {}
|
||||
) {
|
||||
const extensions = ['', 'ts', 'tsx', 'js', 'jsx', 'json'];
|
||||
if (opts.debug) process.env.NX_REACT_NATIVE_DEBUG = 'true';
|
||||
if (opts.extensions) extensions.push(...opts.extensions);
|
||||
|
||||
config.projectRoot = opts.projectRoot || workspaceRoot;
|
||||
|
||||
// Add support for paths specified by tsconfig
|
||||
config.resolver = {
|
||||
...config.resolver,
|
||||
resolveRequest: getResolveRequest(extensions),
|
||||
};
|
||||
|
||||
let watchFolders = config.watchFolders || [];
|
||||
watchFolders = watchFolders.concat([
|
||||
let watchFolders = [
|
||||
join(workspaceRoot, 'node_modules'),
|
||||
join(workspaceRoot, workspaceLayout().libsDir),
|
||||
join(workspaceRoot, 'packages'),
|
||||
join(workspaceRoot, '.storybook'),
|
||||
]);
|
||||
];
|
||||
if (opts.watchFolders?.length) {
|
||||
watchFolders = watchFolders.concat(opts.watchFolders);
|
||||
}
|
||||
|
||||
watchFolders = watchFolders.filter((folder) => existsSync(folder));
|
||||
config.watchFolders = watchFolders;
|
||||
|
||||
return config;
|
||||
const nxConfig: MetroConfig = {
|
||||
resolver: {
|
||||
resolveRequest: getResolveRequest(extensions),
|
||||
},
|
||||
watchFolders,
|
||||
};
|
||||
|
||||
return mergeConfig(userConfig, nxConfig);
|
||||
}
|
||||
|
||||
@ -1,62 +1,24 @@
|
||||
import { ExecutorContext, names } from '@nx/devkit';
|
||||
import { join } from 'path';
|
||||
import { ensureNodeModulesSymlink } from '../../utils/ensure-node-modules-symlink';
|
||||
import { ExecutorContext } from '@nx/devkit';
|
||||
import { join, resolve as pathResolve } from 'path';
|
||||
import { ChildProcess, fork } from 'child_process';
|
||||
import { ReactNativeBuildAndroidOptions } from './schema';
|
||||
import { chmodAndroidGradlewFiles } from '../../utils/chmod-android-gradle-files';
|
||||
import { runCliStart } from '../start/start.impl';
|
||||
import {
|
||||
displayNewlyAddedDepsMessage,
|
||||
syncDeps,
|
||||
} from '../sync-deps/sync-deps.impl';
|
||||
import { getCliOptions } from '../../utils/get-cli-options';
|
||||
|
||||
export interface ReactNativeBuildOutput {
|
||||
success: boolean;
|
||||
}
|
||||
|
||||
let childProcess: ChildProcess;
|
||||
|
||||
export default async function* buildAndroidExecutor(
|
||||
options: ReactNativeBuildAndroidOptions,
|
||||
context: ExecutorContext
|
||||
): AsyncGenerator<ReactNativeBuildOutput> {
|
||||
const projectRoot =
|
||||
context.projectsConfigurations.projects[context.projectName].root;
|
||||
ensureNodeModulesSymlink(context.root, projectRoot);
|
||||
if (options.sync) {
|
||||
displayNewlyAddedDepsMessage(
|
||||
context.projectName,
|
||||
await syncDeps(
|
||||
context.projectName,
|
||||
projectRoot,
|
||||
context.root,
|
||||
context.projectGraph
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
chmodAndroidGradlewFiles(join(projectRoot, 'android'));
|
||||
|
||||
try {
|
||||
const tasks = [runCliBuild(context.root, projectRoot, options)];
|
||||
if (options.packager && options.mode !== 'release') {
|
||||
tasks.push(
|
||||
runCliStart(context.root, projectRoot, {
|
||||
port: options.port,
|
||||
resetCache: options.resetCache,
|
||||
interactive: options.interactive,
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
await Promise.all(tasks);
|
||||
yield { success: true };
|
||||
} finally {
|
||||
if (childProcess) {
|
||||
childProcess.kill();
|
||||
}
|
||||
}
|
||||
await runCliBuild(context.root, projectRoot, options);
|
||||
yield { success: true };
|
||||
}
|
||||
|
||||
function runCliBuild(
|
||||
@ -64,30 +26,39 @@ function runCliBuild(
|
||||
projectRoot: string,
|
||||
options: ReactNativeBuildAndroidOptions
|
||||
) {
|
||||
return new Promise((resolve, reject) => {
|
||||
return new Promise<ChildProcess>((res, reject) => {
|
||||
/**
|
||||
* Call the react native cli with option `--no-packager`
|
||||
* Not passing '--packager' due to cli will launch start command from the project root
|
||||
*/
|
||||
childProcess = fork(
|
||||
join(workspaceRoot, './node_modules/react-native/cli.js'),
|
||||
const childProcess = fork(
|
||||
require.resolve('react-native/cli.js'),
|
||||
['build-android', ...createBuildAndroidOptions(options), '--no-packager'],
|
||||
{
|
||||
cwd: join(workspaceRoot, projectRoot),
|
||||
stdio: 'inherit',
|
||||
cwd: pathResolve(workspaceRoot, projectRoot),
|
||||
env: { ...process.env, RCT_METRO_PORT: options.port.toString() },
|
||||
}
|
||||
);
|
||||
|
||||
// Ensure the child process is killed when the parent exits
|
||||
process.on('exit', () => childProcess.kill());
|
||||
process.on('SIGTERM', () => childProcess.kill());
|
||||
/**
|
||||
* Ensure the child process is killed when the parent exits
|
||||
*/
|
||||
const processExitListener = (signal?: number | NodeJS.Signals) => () => {
|
||||
childProcess.kill(signal);
|
||||
process.exit();
|
||||
};
|
||||
process.once('exit', (signal) => childProcess.kill(signal));
|
||||
process.once('SIGTERM', processExitListener);
|
||||
process.once('SIGINT', processExitListener);
|
||||
process.once('SIGQUIT', processExitListener);
|
||||
|
||||
childProcess.on('error', (err) => {
|
||||
reject(err);
|
||||
});
|
||||
childProcess.on('exit', (code) => {
|
||||
if (code === 0) {
|
||||
resolve(code);
|
||||
res(childProcess);
|
||||
} else {
|
||||
reject(code);
|
||||
}
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
// options taken from https://github.com/react-native-community/cli/blob/main/packages/cli-platform-android/src/commands/buildAndroid/index.ts
|
||||
// https://github.com/react-native-community/cli/blob/main/packages/cli-platform-android/README.md#build-android
|
||||
|
||||
import { ReactNativeStartOptions } from '../start/schema';
|
||||
|
||||
@ -20,12 +21,13 @@ export interface ReactNativeBuildAndroidOptions
|
||||
// react native options
|
||||
mode: string; // default is debug
|
||||
activeArchOnly: boolean; // default is false
|
||||
port: number; // default is 8081
|
||||
tasks?: Array<string>;
|
||||
tasks?: string | Array<string>;
|
||||
extraParams?: Array<string>;
|
||||
interactive?: boolean;
|
||||
interactive: boolean;
|
||||
|
||||
// nx options
|
||||
// @deprecated, no longer used
|
||||
packager: boolean; // default is true
|
||||
// @deprecated, add to sync-deps to dependsOn
|
||||
sync: boolean;
|
||||
}
|
||||
|
||||
@ -51,7 +51,8 @@
|
||||
"packager": {
|
||||
"type": "boolean",
|
||||
"description": "Launch packager while building",
|
||||
"default": true
|
||||
"default": true,
|
||||
"x-deprecated": "Run `nx run <project>:start` instead. Will be removed in Nx 17."
|
||||
},
|
||||
"port": {
|
||||
"type": "number",
|
||||
@ -59,10 +60,10 @@
|
||||
"default": 8081
|
||||
},
|
||||
"tasks": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"oneOf": [
|
||||
{ "type": "array", "items": { "type": "string" } },
|
||||
{ "type": "string" }
|
||||
],
|
||||
"description": "Run custom Gradle tasks. By default it's \"assembleDebug\". Will override passed mode and variant arguments.",
|
||||
"examples": [
|
||||
"assembleDebug",
|
||||
@ -79,8 +80,12 @@
|
||||
"default": false
|
||||
},
|
||||
"extraParams": {
|
||||
"type": "string",
|
||||
"description": "Custom params passed to gradle build command"
|
||||
"oneOf": [
|
||||
{ "type": "array", "items": { "type": "string" } },
|
||||
{ "type": "string" }
|
||||
],
|
||||
"description": "Custom params passed to gradle build command",
|
||||
"examples": ["-x lint -x test"]
|
||||
},
|
||||
"interactive": {
|
||||
"type": "boolean",
|
||||
@ -89,7 +94,8 @@
|
||||
"sync": {
|
||||
"type": "boolean",
|
||||
"description": "Syncs npm dependencies to `package.json` (for React Native autolink).",
|
||||
"default": true
|
||||
"default": true,
|
||||
"x-deprecated": "Add sync-deps to dependsOn instead"
|
||||
},
|
||||
"resetCache": {
|
||||
"type": "boolean",
|
||||
|
||||
@ -1,25 +1,16 @@
|
||||
import { ExecutorContext } from '@nx/devkit';
|
||||
import { join } from 'path';
|
||||
import { resolve as pathResolve } from 'path';
|
||||
import { ChildProcess, fork } from 'child_process';
|
||||
import { platform } from 'os';
|
||||
|
||||
import { ensureNodeModulesSymlink } from '../../utils/ensure-node-modules-symlink';
|
||||
import {
|
||||
displayNewlyAddedDepsMessage,
|
||||
syncDeps,
|
||||
} from '../sync-deps/sync-deps.impl';
|
||||
import { podInstall } from '../../utils/pod-install-task';
|
||||
import { ReactNativeBuildIosOptions } from './schema';
|
||||
import { runCliStart } from '../start/start.impl';
|
||||
import { getCliOptions } from '../../utils/get-cli-options';
|
||||
|
||||
export interface ReactNativeBuildIosOutput {
|
||||
success: boolean;
|
||||
}
|
||||
|
||||
let childProcess: ChildProcess;
|
||||
|
||||
export default async function* runIosExecutor(
|
||||
export default async function* buildIosExecutor(
|
||||
options: ReactNativeBuildIosOptions,
|
||||
context: ExecutorContext
|
||||
): AsyncGenerator<ReactNativeBuildIosOutput> {
|
||||
@ -28,77 +19,48 @@ export default async function* runIosExecutor(
|
||||
}
|
||||
const projectRoot =
|
||||
context.projectsConfigurations.projects[context.projectName].root;
|
||||
ensureNodeModulesSymlink(context.root, projectRoot);
|
||||
if (options.sync) {
|
||||
displayNewlyAddedDepsMessage(
|
||||
context.projectName,
|
||||
await syncDeps(
|
||||
context.projectName,
|
||||
projectRoot,
|
||||
context.root,
|
||||
context.projectGraph
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if (options.install) {
|
||||
await podInstall(
|
||||
join(context.root, projectRoot, 'ios'),
|
||||
options.buildFolder
|
||||
);
|
||||
}
|
||||
|
||||
try {
|
||||
const tasks = [runCliBuildIOS(context.root, projectRoot, options)];
|
||||
if (options.packager && options.mode !== 'Release') {
|
||||
tasks.push(
|
||||
runCliStart(context.root, projectRoot, {
|
||||
port: options.port,
|
||||
resetCache: options.resetCache,
|
||||
interactive: options.interactive,
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
await Promise.all(tasks);
|
||||
|
||||
yield { success: true };
|
||||
} finally {
|
||||
if (childProcess) {
|
||||
childProcess.kill();
|
||||
}
|
||||
}
|
||||
await runCliBuildIOS(context.root, projectRoot, options);
|
||||
return { success: true };
|
||||
}
|
||||
|
||||
function runCliBuildIOS(
|
||||
workspaceRoot: string,
|
||||
projectRoot: string,
|
||||
options: ReactNativeBuildIosOptions
|
||||
) {
|
||||
return new Promise((resolve, reject) => {
|
||||
/**
|
||||
* Call the react native cli with option `--no-packager`
|
||||
* Not passing '--packager' due to cli will launch start command from the project root
|
||||
*/
|
||||
childProcess = fork(
|
||||
join(workspaceRoot, './node_modules/react-native/cli.js'),
|
||||
['build-ios', ...createBuildIOSOptions(options)],
|
||||
): Promise<ChildProcess> {
|
||||
return new Promise<ChildProcess>((resolve, reject) => {
|
||||
const childProcess = fork(
|
||||
require.resolve('react-native/cli.js'),
|
||||
[
|
||||
'build-ios',
|
||||
...createBuildIOSOptions(options),
|
||||
...(process.env.NX_VERBOSE_LOGGING === 'true' ? ['--verbose'] : []),
|
||||
],
|
||||
{
|
||||
cwd: join(workspaceRoot, projectRoot),
|
||||
cwd: pathResolve(workspaceRoot, projectRoot),
|
||||
env: { ...process.env, RCT_METRO_PORT: options.port.toString() },
|
||||
}
|
||||
);
|
||||
|
||||
// Ensure the child process is killed when the parent exits
|
||||
process.on('exit', () => childProcess.kill());
|
||||
process.on('SIGTERM', () => childProcess.kill());
|
||||
/**
|
||||
* Ensure the child process is killed when the parent exits
|
||||
*/
|
||||
const processExitListener = (signal?: number | NodeJS.Signals) => () => {
|
||||
childProcess.kill(signal);
|
||||
process.exit();
|
||||
};
|
||||
process.once('exit', (signal) => childProcess.kill(signal));
|
||||
process.once('SIGTERM', processExitListener);
|
||||
process.once('SIGINT', processExitListener);
|
||||
process.once('SIGQUIT', processExitListener);
|
||||
|
||||
childProcess.on('error', (err) => {
|
||||
reject(err);
|
||||
});
|
||||
childProcess.on('exit', (code) => {
|
||||
if (code === 0) {
|
||||
resolve(code);
|
||||
resolve(childProcess);
|
||||
} else {
|
||||
reject(code);
|
||||
}
|
||||
|
||||
@ -16,7 +16,10 @@ export interface ReactNativeBuildIosOptions extends ReactNativeStartOptions {
|
||||
extraParams?: string;
|
||||
|
||||
// nx options
|
||||
// @deprecated, no longer used
|
||||
packager: boolean; // default is true
|
||||
// @deprecated, add to pod-install to dependsOn
|
||||
install: boolean; // default is true
|
||||
// @deprecated, add to sync-deps to dependsOn
|
||||
sync: boolean; // default is true
|
||||
}
|
||||
|
||||
@ -17,10 +17,6 @@
|
||||
{
|
||||
"name": "Build iOS for a device with udid",
|
||||
"keys": ["udid"]
|
||||
},
|
||||
{
|
||||
"name": "Run `pod install` before building iOS app",
|
||||
"keys": ["install"]
|
||||
}
|
||||
],
|
||||
"properties": {
|
||||
@ -78,17 +74,22 @@
|
||||
"description": "Explicitly select which scheme and configuration to use before running a build"
|
||||
},
|
||||
"extraParams": {
|
||||
"type": "string",
|
||||
"oneOf": [
|
||||
{ "type": "array", "items": { "type": "string" } },
|
||||
{ "type": "string" }
|
||||
],
|
||||
"description": "Custom params that will be passed to xcodebuild command."
|
||||
},
|
||||
"install": {
|
||||
"type": "boolean",
|
||||
"description": "Runs `pod install` for native modules before building iOS app.",
|
||||
"x-deprecated": "Add pod-install to dependsOn in project.json for this target instead",
|
||||
"default": true
|
||||
},
|
||||
"sync": {
|
||||
"type": "boolean",
|
||||
"description": "Syncs npm dependencies to `package.json` (for React Native autolink).",
|
||||
"x-deprecated": "Add sync-deps to dependsOn in project.json for this target instead",
|
||||
"default": true
|
||||
},
|
||||
"resetCache": {
|
||||
@ -99,7 +100,8 @@
|
||||
"packager": {
|
||||
"type": "boolean",
|
||||
"description": "Launch packager while building",
|
||||
"default": true
|
||||
"default": true,
|
||||
"x-deprecated": "Run `nx run <project>:start` instead. Will be removed in Nx 17."
|
||||
}
|
||||
},
|
||||
"required": [],
|
||||
|
||||
@ -1,18 +1,14 @@
|
||||
import { createDirectory } from '@nx/workspace/src/utilities/fileutils';
|
||||
import { names, ExecutorContext } from '@nx/devkit';
|
||||
import { dirname, join } from 'path';
|
||||
import { dirname, join, resolve as pathResolve } from 'path';
|
||||
import { ChildProcess, fork } from 'child_process';
|
||||
|
||||
import { ensureNodeModulesSymlink } from '../../utils/ensure-node-modules-symlink';
|
||||
|
||||
import { ReactNativeBundleOptions } from './schema';
|
||||
|
||||
export interface ReactNativeBundleOutput {
|
||||
success: boolean;
|
||||
}
|
||||
|
||||
let childProcess: ChildProcess;
|
||||
|
||||
export default async function* bundleExecutor(
|
||||
options: ReactNativeBundleOptions,
|
||||
context: ExecutorContext
|
||||
@ -23,41 +19,46 @@ export default async function* bundleExecutor(
|
||||
options.bundleOutput = join(context.root, options.bundleOutput);
|
||||
|
||||
createDirectory(dirname(options.bundleOutput));
|
||||
ensureNodeModulesSymlink(context.root, projectRoot);
|
||||
|
||||
try {
|
||||
await runCliBuild(context.root, projectRoot, options);
|
||||
yield { success: true };
|
||||
} finally {
|
||||
if (childProcess) {
|
||||
childProcess.kill();
|
||||
}
|
||||
}
|
||||
await runCliBuild(context.root, projectRoot, options);
|
||||
yield { success: true };
|
||||
}
|
||||
|
||||
function runCliBuild(
|
||||
workspaceRoot: string,
|
||||
projectRoot: string,
|
||||
options: ReactNativeBundleOptions
|
||||
) {
|
||||
return new Promise((resolve, reject) => {
|
||||
): Promise<ChildProcess> {
|
||||
return new Promise<ChildProcess>((resolve, reject) => {
|
||||
const cliOptions = createBundleOptions(options);
|
||||
childProcess = fork(
|
||||
join(workspaceRoot, './node_modules/react-native/cli.js'),
|
||||
const childProcess = fork(
|
||||
require.resolve('react-native/cli.js'),
|
||||
['bundle', ...cliOptions],
|
||||
{ cwd: join(workspaceRoot, projectRoot), env: process.env }
|
||||
{
|
||||
stdio: 'inherit',
|
||||
cwd: pathResolve(workspaceRoot, projectRoot),
|
||||
env: process.env,
|
||||
}
|
||||
);
|
||||
|
||||
// Ensure the child process is killed when the parent exits
|
||||
process.on('exit', () => childProcess.kill());
|
||||
process.on('SIGTERM', () => childProcess.kill());
|
||||
/**
|
||||
* Ensure the child process is killed when the parent exits
|
||||
*/
|
||||
const processExitListener = (signal?: number | NodeJS.Signals) => () => {
|
||||
childProcess.kill(signal);
|
||||
process.exit();
|
||||
};
|
||||
process.once('exit', (signal) => childProcess.kill(signal));
|
||||
process.once('SIGTERM', processExitListener);
|
||||
process.once('SIGINT', processExitListener);
|
||||
process.once('SIGQUIT', processExitListener);
|
||||
|
||||
childProcess.on('error', (err) => {
|
||||
reject(err);
|
||||
});
|
||||
childProcess.on('exit', (code) => {
|
||||
if (code === 0) {
|
||||
resolve(code);
|
||||
resolve(childProcess);
|
||||
} else {
|
||||
reject(code);
|
||||
}
|
||||
|
||||
@ -15,7 +15,7 @@ export default async function* podInstall(
|
||||
const projectRoot =
|
||||
context.projectsConfigurations.projects[context.projectName].root;
|
||||
const iosDirectory = join(context.root, projectRoot, 'ios');
|
||||
await runPodInstall(iosDirectory, true, options.buildFolder)();
|
||||
await runPodInstall(iosDirectory, true, options)();
|
||||
|
||||
yield { success: true };
|
||||
}
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
export interface ReactNativePodInstallOptions {
|
||||
buildFolder: string;
|
||||
buildFolder: string; // default is './build'
|
||||
repoUpdate: boolean; // default is false
|
||||
deployment: boolean; // default is false
|
||||
}
|
||||
|
||||
@ -9,9 +9,19 @@
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"buildFolder": {
|
||||
"description": "Location for iOS build artifacts. Corresponds to Xcode's \"-derivedDataPath\". Relative to ios directory",
|
||||
"description": "Location for iOS build artifacts. Corresponds to Xcode's \"-derivedDataPath\". Relative to ios directory.",
|
||||
"type": "string",
|
||||
"default": "./build"
|
||||
},
|
||||
"repoUpdate": {
|
||||
"description": "Force running `pod repo update` before install.",
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"deployment": {
|
||||
"description": "Disallow any changes to the Podfile or the Podfile.lock during installation.",
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
}
|
||||
},
|
||||
"required": ["buildFolder"]
|
||||
|
||||
@ -1,14 +1,9 @@
|
||||
import { ExecutorContext } from '@nx/devkit';
|
||||
import { join } from 'path';
|
||||
import { join, resolve as pathResolve } from 'path';
|
||||
import { ChildProcess, fork } from 'child_process';
|
||||
|
||||
import { ensureNodeModulesSymlink } from '../../utils/ensure-node-modules-symlink';
|
||||
import {
|
||||
displayNewlyAddedDepsMessage,
|
||||
syncDeps,
|
||||
} from '../sync-deps/sync-deps.impl';
|
||||
import { ReactNativeRunAndroidOptions } from './schema';
|
||||
import { runCliStart } from '../start/start.impl';
|
||||
import startExecutor from '../start/start.impl';
|
||||
import { chmodAndroidGradlewFiles } from '../../utils/chmod-android-gradle-files';
|
||||
import { getCliOptions } from '../../utils/get-cli-options';
|
||||
|
||||
@ -24,72 +19,72 @@ export default async function* runAndroidExecutor(
|
||||
): AsyncGenerator<ReactNativeRunAndroidOutput> {
|
||||
const projectRoot =
|
||||
context.projectsConfigurations.projects[context.projectName].root;
|
||||
ensureNodeModulesSymlink(context.root, projectRoot);
|
||||
chmodAndroidGradlewFiles(join(projectRoot, 'android'));
|
||||
|
||||
if (options.sync) {
|
||||
displayNewlyAddedDepsMessage(
|
||||
context.projectName,
|
||||
await syncDeps(
|
||||
context.projectName,
|
||||
projectRoot,
|
||||
context.root,
|
||||
context.projectGraph
|
||||
)
|
||||
if (options.packager && options.mode !== 'Release') {
|
||||
const startResults = startExecutor(
|
||||
{
|
||||
port: options.port,
|
||||
resetCache: options.resetCache,
|
||||
interactive: true,
|
||||
},
|
||||
context
|
||||
);
|
||||
for await (const result of startResults) {
|
||||
if (result.success) {
|
||||
await runCliRunAndroid(context.root, projectRoot, options);
|
||||
yield {
|
||||
success: true,
|
||||
};
|
||||
} else {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
await runCliRunAndroid(context.root, projectRoot, options);
|
||||
}
|
||||
|
||||
try {
|
||||
const tasks = [runCliRunAndroid(context.root, projectRoot, options)];
|
||||
if (options.packager) {
|
||||
tasks.push(
|
||||
runCliStart(context.root, projectRoot, {
|
||||
port: options.port,
|
||||
resetCache: options.resetCache,
|
||||
interactive: options.interactive,
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
await Promise.all(tasks);
|
||||
|
||||
yield { success: true };
|
||||
} finally {
|
||||
if (childProcess) {
|
||||
childProcess.kill();
|
||||
}
|
||||
}
|
||||
yield { success: true };
|
||||
}
|
||||
|
||||
function runCliRunAndroid(
|
||||
workspaceRoot: string,
|
||||
projectRoot: string,
|
||||
options: ReactNativeRunAndroidOptions
|
||||
) {
|
||||
return new Promise((resolve, reject) => {
|
||||
): Promise<ChildProcess> {
|
||||
return new Promise<ChildProcess>((resolve, reject) => {
|
||||
/**
|
||||
* Call the react native cli with option `--no-packager`
|
||||
* Not passing '--packager' due to cli will launch start command from the project root
|
||||
*/
|
||||
childProcess = fork(
|
||||
join(workspaceRoot, './node_modules/react-native/cli.js'),
|
||||
require.resolve('react-native/cli.js'),
|
||||
['run-android', ...createRunAndroidOptions(options), '--no-packager'],
|
||||
{
|
||||
cwd: join(workspaceRoot, projectRoot),
|
||||
stdio: 'inherit',
|
||||
cwd: pathResolve(workspaceRoot, projectRoot),
|
||||
env: { ...process.env, RCT_METRO_PORT: options.port.toString() },
|
||||
}
|
||||
);
|
||||
|
||||
// Ensure the child process is killed when the parent exits
|
||||
process.on('exit', () => childProcess.kill());
|
||||
process.on('SIGTERM', () => childProcess.kill());
|
||||
/**
|
||||
* Ensure the child process is killed when the parent exits
|
||||
*/
|
||||
const processExitListener = (signal?: number | NodeJS.Signals) => () => {
|
||||
childProcess.kill(signal);
|
||||
process.exit();
|
||||
};
|
||||
process.once('exit', (signal) => childProcess.kill(signal));
|
||||
process.once('SIGTERM', processExitListener);
|
||||
process.once('SIGINT', processExitListener);
|
||||
process.once('SIGQUIT', processExitListener);
|
||||
|
||||
childProcess.on('error', (err) => {
|
||||
reject(err);
|
||||
});
|
||||
childProcess.on('exit', (code) => {
|
||||
if (code === 0) {
|
||||
resolve(code);
|
||||
resolve(childProcess);
|
||||
} else {
|
||||
reject(code);
|
||||
}
|
||||
|
||||
@ -5,11 +5,11 @@ import { ReactNativeStartOptions } from '../start/schema';
|
||||
export interface ReactNativeRunAndroidOptions
|
||||
extends ReactNativeBuildAndroidOptions {
|
||||
/**
|
||||
* @deprecated use mode instead
|
||||
* @deprecated TODO(v17) use mode instead
|
||||
*/
|
||||
variant: string;
|
||||
/**
|
||||
* @deprecated no longer supported in react native cli
|
||||
* @deprecated TODO(v17) no longer supported in react native cli
|
||||
* https://github.com/react-native-community/cli/commit/7c003f2b1d9d80ec5c167614ba533a004272c685
|
||||
*/
|
||||
jetifier: boolean;
|
||||
|
||||
@ -77,10 +77,10 @@
|
||||
"default": 8081
|
||||
},
|
||||
"tasks": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"oneOf": [
|
||||
{ "type": "array", "items": { "type": "string" } },
|
||||
{ "type": "string" }
|
||||
],
|
||||
"description": "Run custom Gradle tasks. By default it's \"assembleDebug\". Will override passed mode and variant arguments.",
|
||||
"examples": [
|
||||
"assembleDebug",
|
||||
@ -97,7 +97,10 @@
|
||||
"default": false
|
||||
},
|
||||
"extraParams": {
|
||||
"type": "string",
|
||||
"oneOf": [
|
||||
{ "type": "array", "items": { "type": "string" } },
|
||||
{ "type": "string" }
|
||||
],
|
||||
"description": "Custom params passed to gradle build command"
|
||||
},
|
||||
"interactive": {
|
||||
@ -107,6 +110,7 @@
|
||||
"sync": {
|
||||
"type": "boolean",
|
||||
"description": "Syncs npm dependencies to `package.json` (for React Native autolink).",
|
||||
"x-deprecated": "Add sync-deps to dependsOn for this target in project.json instead",
|
||||
"default": true
|
||||
},
|
||||
"resetCache": {
|
||||
|
||||
@ -1,24 +1,16 @@
|
||||
import { ExecutorContext } from '@nx/devkit';
|
||||
import { join } from 'path';
|
||||
import { resolve as pathResolve } from 'path';
|
||||
import { ChildProcess, fork } from 'child_process';
|
||||
import { platform } from 'os';
|
||||
|
||||
import { ensureNodeModulesSymlink } from '../../utils/ensure-node-modules-symlink';
|
||||
import {
|
||||
displayNewlyAddedDepsMessage,
|
||||
syncDeps,
|
||||
} from '../sync-deps/sync-deps.impl';
|
||||
import { podInstall } from '../../utils/pod-install-task';
|
||||
import { ReactNativeRunIosOptions } from './schema';
|
||||
import { runCliStart } from '../start/start.impl';
|
||||
import startExecutor from '../start/start.impl';
|
||||
import { getCliOptions } from '../../utils/get-cli-options';
|
||||
|
||||
import { ReactNativeRunIosOptions } from './schema';
|
||||
export interface ReactNativeRunIosOutput {
|
||||
success: boolean;
|
||||
}
|
||||
|
||||
let childProcess: ChildProcess;
|
||||
|
||||
export default async function* runIosExecutor(
|
||||
options: ReactNativeRunIosOptions,
|
||||
context: ExecutorContext
|
||||
@ -28,77 +20,71 @@ export default async function* runIosExecutor(
|
||||
}
|
||||
const projectRoot =
|
||||
context.projectsConfigurations.projects[context.projectName].root;
|
||||
ensureNodeModulesSymlink(context.root, projectRoot);
|
||||
if (options.sync) {
|
||||
displayNewlyAddedDepsMessage(
|
||||
context.projectName,
|
||||
await syncDeps(
|
||||
context.projectName,
|
||||
projectRoot,
|
||||
context.root,
|
||||
context.projectGraph
|
||||
)
|
||||
|
||||
if (options.packager && options.mode !== 'Release') {
|
||||
const startResults = startExecutor(
|
||||
{
|
||||
port: options.port,
|
||||
resetCache: options.resetCache,
|
||||
interactive: true,
|
||||
},
|
||||
context
|
||||
);
|
||||
}
|
||||
|
||||
if (options.install) {
|
||||
await podInstall(
|
||||
join(context.root, projectRoot, 'ios'),
|
||||
options.buildFolder
|
||||
);
|
||||
}
|
||||
|
||||
try {
|
||||
const tasks = [runCliRunIOS(context.root, projectRoot, options)];
|
||||
if (options.packager && options.mode !== 'Release') {
|
||||
tasks.push(
|
||||
runCliStart(context.root, projectRoot, {
|
||||
port: options.port,
|
||||
resetCache: options.resetCache,
|
||||
interactive: options.interactive,
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
await Promise.all(tasks);
|
||||
|
||||
yield { success: true };
|
||||
} finally {
|
||||
if (childProcess) {
|
||||
childProcess.kill();
|
||||
for await (const result of startResults) {
|
||||
if (result.success) {
|
||||
await runCliRunIOS(context.root, projectRoot, options);
|
||||
yield {
|
||||
success: true,
|
||||
};
|
||||
} else {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
await runCliRunIOS(context.root, projectRoot, options);
|
||||
}
|
||||
|
||||
yield { success: true };
|
||||
}
|
||||
|
||||
function runCliRunIOS(
|
||||
workspaceRoot: string,
|
||||
projectRoot: string,
|
||||
options: ReactNativeRunIosOptions
|
||||
) {
|
||||
return new Promise((resolve, reject) => {
|
||||
): Promise<ChildProcess> {
|
||||
return new Promise<ChildProcess>((resolve, reject) => {
|
||||
/**
|
||||
* Call the react native cli with option `--no-packager`
|
||||
* Not passing '--packager' due to cli will launch start command from the project root
|
||||
*/
|
||||
childProcess = fork(
|
||||
join(workspaceRoot, './node_modules/react-native/cli.js'),
|
||||
const childProcess = fork(
|
||||
require.resolve('react-native/cli.js'),
|
||||
['run-ios', ...createRunIOSOptions(options), '--no-packager'],
|
||||
{
|
||||
cwd: join(workspaceRoot, projectRoot),
|
||||
stdio: 'inherit',
|
||||
cwd: pathResolve(workspaceRoot, projectRoot),
|
||||
env: { ...process.env, RCT_METRO_PORT: options.port.toString() },
|
||||
}
|
||||
);
|
||||
|
||||
// Ensure the child process is killed when the parent exits
|
||||
process.on('exit', () => childProcess.kill());
|
||||
process.on('SIGTERM', () => childProcess.kill());
|
||||
/**
|
||||
* Ensure the child process is killed when the parent exits
|
||||
*/
|
||||
const processExitListener = (signal?: number | NodeJS.Signals) => () => {
|
||||
childProcess.kill(signal);
|
||||
process.exit();
|
||||
};
|
||||
process.once('exit', (signal) => childProcess.kill(signal));
|
||||
process.once('SIGTERM', processExitListener);
|
||||
process.once('SIGINT', processExitListener);
|
||||
process.once('SIGQUIT', processExitListener);
|
||||
|
||||
childProcess.on('error', (err) => {
|
||||
reject(err);
|
||||
});
|
||||
childProcess.on('exit', (code) => {
|
||||
if (code === 0) {
|
||||
resolve(code);
|
||||
resolve(childProcess);
|
||||
} else {
|
||||
reject(code);
|
||||
}
|
||||
|
||||
@ -4,7 +4,7 @@ import { ReactNativeStartOptions } from '../start/schema';
|
||||
// part of options form https://github.com/react-native-community/cli/blob/main/packages/cli-platform-ios/src/commands/runIOS/index.ts
|
||||
export interface ReactNativeRunIosOptions extends ReactNativeBuildIosOptions {
|
||||
/**
|
||||
* @deprecated use mode instead, will be removed in nx 17.
|
||||
* @deprecated TODO(v17) use mode instead, will be removed in nx 17.
|
||||
*/
|
||||
xcodeConfiguration?: string;
|
||||
|
||||
|
||||
@ -19,10 +19,6 @@
|
||||
{
|
||||
"name": "Run iOS on a device with udid",
|
||||
"keys": ["udid"]
|
||||
},
|
||||
{
|
||||
"name": "Run `pod install` before building iOS app",
|
||||
"keys": ["install"]
|
||||
}
|
||||
],
|
||||
"properties": {
|
||||
@ -87,17 +83,22 @@
|
||||
"description": "Explicitly select which scheme and configuration to use before running a build"
|
||||
},
|
||||
"extraParams": {
|
||||
"type": "string",
|
||||
"oneOf": [
|
||||
{ "type": "array", "items": { "type": "string" } },
|
||||
{ "type": "string" }
|
||||
],
|
||||
"description": "Custom params that will be passed to xcodebuild command."
|
||||
},
|
||||
"install": {
|
||||
"type": "boolean",
|
||||
"description": "Runs `pod install` for native modules before building iOS app.",
|
||||
"default": true
|
||||
"default": true,
|
||||
"x-deprecated": "Add `pod-install` to dependsOn for this target in project.json instead."
|
||||
},
|
||||
"sync": {
|
||||
"type": "boolean",
|
||||
"description": "Syncs npm dependencies to `package.json` (for React Native autolink).",
|
||||
"x-deprecated": "Add `sync-deps` to dependsOn for this target in project.json instead.",
|
||||
"default": true
|
||||
},
|
||||
"resetCache": {
|
||||
|
||||
@ -1,18 +1,15 @@
|
||||
import * as chalk from 'chalk';
|
||||
import { ExecutorContext, logger } from '@nx/devkit';
|
||||
import { ChildProcess, fork } from 'child_process';
|
||||
import { join } from 'path';
|
||||
import { resolve as pathResolve } from 'path';
|
||||
import { ensureNodeModulesSymlink } from '../../utils/ensure-node-modules-symlink';
|
||||
import { isPackagerRunning } from './lib/is-packager-running';
|
||||
import { ReactNativeStartOptions } from './schema';
|
||||
|
||||
export interface ReactNativeStartOutput {
|
||||
baseUrl?: string;
|
||||
port?: number;
|
||||
success: boolean;
|
||||
}
|
||||
|
||||
let childProcess: ChildProcess;
|
||||
|
||||
export default async function* startExecutor(
|
||||
options: ReactNativeStartOptions,
|
||||
context: ExecutorContext
|
||||
@ -21,27 +18,27 @@ export default async function* startExecutor(
|
||||
context.projectsConfigurations.projects[context.projectName].root;
|
||||
ensureNodeModulesSymlink(context.root, projectRoot);
|
||||
|
||||
try {
|
||||
const baseUrl = `http://localhost:${options.port}`;
|
||||
const appName = context.projectName;
|
||||
logger.info(chalk.cyan(`Packager is ready at ${baseUrl}`));
|
||||
logger.info(
|
||||
`Use ${chalk.bold(`nx run-android ${appName}`)} or ${chalk.bold(
|
||||
`nx run-ios ${appName}`
|
||||
)} to run the native app.`
|
||||
);
|
||||
const startProcess = await runCliStart(context.root, projectRoot, options);
|
||||
|
||||
await runCliStart(context.root, projectRoot, options);
|
||||
yield {
|
||||
port: options.port,
|
||||
success: true,
|
||||
};
|
||||
|
||||
yield {
|
||||
baseUrl,
|
||||
success: true,
|
||||
};
|
||||
} finally {
|
||||
if (childProcess) {
|
||||
childProcess.kill();
|
||||
}
|
||||
if (!startProcess) {
|
||||
return;
|
||||
}
|
||||
await new Promise<void>((resolve) => {
|
||||
const processExitListener = (signal?: number | NodeJS.Signals) => () => {
|
||||
startProcess.kill(signal);
|
||||
resolve();
|
||||
process.exit();
|
||||
};
|
||||
process.once('exit', (signal) => startProcess.kill(signal));
|
||||
process.once('SIGTERM', processExitListener);
|
||||
process.once('SIGINT', processExitListener);
|
||||
process.once('SIGQUIT', processExitListener);
|
||||
});
|
||||
}
|
||||
|
||||
/*
|
||||
@ -52,10 +49,10 @@ export async function runCliStart(
|
||||
workspaceRoot: string,
|
||||
projectRoot: string,
|
||||
options: ReactNativeStartOptions
|
||||
): Promise<void> {
|
||||
): Promise<ChildProcess> {
|
||||
const result = await isPackagerRunning(options.port);
|
||||
if (result === 'running') {
|
||||
logger.info('JS server already running.');
|
||||
logger.info(`JS server already running on port ${options.port}.`);
|
||||
} else if (result === 'unrecognized') {
|
||||
logger.warn('JS server not recognized.');
|
||||
} else {
|
||||
@ -63,7 +60,7 @@ export async function runCliStart(
|
||||
logger.info('Starting JS server...');
|
||||
|
||||
try {
|
||||
await startAsync(workspaceRoot, projectRoot, options);
|
||||
return await startAsync(workspaceRoot, projectRoot, options);
|
||||
} catch (error) {
|
||||
logger.error(
|
||||
`Failed to start the packager server. Error details: ${error.message}`
|
||||
@ -77,24 +74,34 @@ function startAsync(
|
||||
workspaceRoot: string,
|
||||
projectRoot: string,
|
||||
options: ReactNativeStartOptions
|
||||
): Promise<number> {
|
||||
return new Promise((resolve, reject) => {
|
||||
childProcess = fork(
|
||||
join(workspaceRoot, './node_modules/react-native/cli.js'),
|
||||
): Promise<ChildProcess> {
|
||||
return new Promise<ChildProcess>((resolve, reject) => {
|
||||
const childProcess = fork(
|
||||
require.resolve('react-native/cli.js'),
|
||||
['start', ...createStartOptions(options)],
|
||||
{ cwd: join(workspaceRoot, projectRoot), env: process.env }
|
||||
{
|
||||
cwd: pathResolve(workspaceRoot, projectRoot),
|
||||
env: process.env,
|
||||
stdio: ['inherit', 'pipe', 'pipe', 'ipc'],
|
||||
}
|
||||
);
|
||||
|
||||
// Ensure the child process is killed when the parent exits
|
||||
process.on('exit', () => childProcess.kill());
|
||||
process.on('SIGTERM', () => childProcess.kill());
|
||||
childProcess.stdout.on('data', (data) => {
|
||||
process.stdout.write(data);
|
||||
if (data.toString().includes('reload the app')) {
|
||||
resolve(childProcess);
|
||||
}
|
||||
});
|
||||
childProcess.stderr.on('data', (data) => {
|
||||
process.stderr.write(data);
|
||||
});
|
||||
|
||||
childProcess.on('error', (err) => {
|
||||
reject(err);
|
||||
});
|
||||
childProcess.on('exit', (code) => {
|
||||
if (code === 0) {
|
||||
resolve(code);
|
||||
resolve(childProcess);
|
||||
} else {
|
||||
reject(code);
|
||||
}
|
||||
|
||||
@ -3,7 +3,7 @@ export interface ReactNativeStorybookOptions {
|
||||
outputFile: string;
|
||||
pattern: string;
|
||||
/**
|
||||
* @deprecated going to be removed in 17
|
||||
* @deprecated TODO(v17) no longer used going to be removed in 17
|
||||
*/
|
||||
silent: boolean;
|
||||
}
|
||||
|
||||
@ -7,7 +7,6 @@ import {
|
||||
Tree,
|
||||
} from '@nx/devkit';
|
||||
|
||||
import { runPodInstall } from '../../utils/pod-install-task';
|
||||
import { runSymlink } from '../../utils/symlink-task';
|
||||
import { addLinting } from '../../utils/add-linting';
|
||||
import { addJest } from '../../utils/add-jest';
|
||||
@ -48,10 +47,6 @@ export async function reactNativeApplicationGenerator(
|
||||
);
|
||||
const detoxTask = await addDetox(host, options);
|
||||
const symlinkTask = runSymlink(host.root, options.appProjectRoot);
|
||||
const podInstallTask = runPodInstall(
|
||||
joinPathFragments(host.root, options.iosProjectRoot),
|
||||
options.install
|
||||
);
|
||||
const chmodTaskGradlew = chmodAndroidGradlewFilesTask(
|
||||
joinPathFragments(host.root, options.androidProjectRoot)
|
||||
);
|
||||
@ -66,7 +61,6 @@ export async function reactNativeApplicationGenerator(
|
||||
jestTask,
|
||||
detoxTask,
|
||||
symlinkTask,
|
||||
podInstallTask,
|
||||
chmodTaskGradlew
|
||||
);
|
||||
}
|
||||
|
||||
@ -1 +0,0 @@
|
||||
2.7.6
|
||||
@ -1,6 +1,6 @@
|
||||
source 'https://rubygems.org'
|
||||
|
||||
# You may use http://rbenv.org/ or https://rvm.io/ to install and use this version
|
||||
ruby File.read(File.join(__dir__, '.ruby-version')).strip
|
||||
ruby ">= 2.6.10"
|
||||
|
||||
gem 'cocoapods', '~> 1.11', '>= 1.11.3'
|
||||
gem 'cocoapods', '~> 1.12'
|
||||
|
||||
@ -1,8 +1,6 @@
|
||||
apply plugin: "com.android.application"
|
||||
apply plugin: "com.facebook.react"
|
||||
|
||||
import com.android.build.OutputFile
|
||||
|
||||
/**
|
||||
* This is the configuration block to customize your React Native Android app.
|
||||
* By default you don't need to apply any configuration, just uncomment the lines you need.
|
||||
@ -13,8 +11,8 @@ react {
|
||||
// root = file("../")
|
||||
// The folder where the react-native NPM package is. Default is ../node_modules/react-native
|
||||
// reactNativeDir = file("../node_modules/react-native")
|
||||
// The folder where the react-native Codegen package is. Default is ../node_modules/react-native-codegen
|
||||
// codegenDir = file("../node_modules/react-native-codegen")
|
||||
// The folder where the react-native Codegen package is. Default is ../node_modules/@react-native/codegen
|
||||
// codegenDir = file("../node_modules/@react-native/codegen")
|
||||
// The cli.js file which is the React Native CLI entrypoint. Default is ../node_modules/react-native/cli.js
|
||||
// cliFile = file("../node_modules/react-native/cli.js")
|
||||
|
||||
@ -53,14 +51,6 @@ react {
|
||||
entryFile = file("../../<%= entryFile %>")
|
||||
}
|
||||
|
||||
/**
|
||||
* Set this to true to create four separate APKs instead of one,
|
||||
* one for each native architecture. This is useful if you don't
|
||||
* use App Bundles (https://developer.android.com/guide/app-bundle/)
|
||||
* and want to have separate APKs to upload to the Play Store.
|
||||
*/
|
||||
def enableSeparateBuildPerCPUArchitecture = false
|
||||
|
||||
/**
|
||||
* Set this to true to Run Proguard on Release builds to minify the Java bytecode.
|
||||
*/
|
||||
@ -79,16 +69,6 @@ def enableProguardInReleaseBuilds = false
|
||||
*/
|
||||
def jscFlavor = 'org.webkit:android-jsc:+'
|
||||
|
||||
/**
|
||||
* Private function to get the list of Native Architectures you want to build.
|
||||
* This reads the value from reactNativeArchitectures in your gradle.properties
|
||||
* file and works together with the --active-arch-only flag of react-native run-android.
|
||||
*/
|
||||
def reactNativeArchitectures() {
|
||||
def value = project.getProperties().get("reactNativeArchitectures")
|
||||
return value ? value.split(",") : ["armeabi-v7a", "x86", "x86_64", "arm64-v8a"]
|
||||
}
|
||||
|
||||
android {
|
||||
ndkVersion rootProject.ext.ndkVersion
|
||||
|
||||
@ -106,15 +86,6 @@ android {
|
||||
testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'
|
||||
<% } %>
|
||||
}
|
||||
|
||||
splits {
|
||||
abi {
|
||||
reset()
|
||||
enable enableSeparateBuildPerCPUArchitecture
|
||||
universalApk false // If true, also generate a universal APK
|
||||
include (*reactNativeArchitectures())
|
||||
}
|
||||
}
|
||||
signingConfigs {
|
||||
debug {
|
||||
storeFile file('debug.keystore')
|
||||
@ -138,22 +109,6 @@ android {
|
||||
<% } %>
|
||||
}
|
||||
}
|
||||
|
||||
// applicationVariants are e.g. debug, release
|
||||
applicationVariants.all { variant ->
|
||||
variant.outputs.each { output ->
|
||||
// For each separate APK per architecture, set a unique version code as described here:
|
||||
// https://developer.android.com/studio/build/configure-apk-splits.html
|
||||
// Example: versionCode 1 will generate 1001 for armeabi-v7a, 1002 for x86, etc.
|
||||
def versionCodes = ["armeabi-v7a": 1, "x86": 2, "arm64-v8a": 3, "x86_64": 4]
|
||||
def abi = output.getFilter(OutputFile.ABI)
|
||||
if (abi != null) { // null for the universal-debug, universal-release variants
|
||||
output.versionCodeOverride =
|
||||
defaultConfig.versionCode * 1000 + versionCodes.get(abi)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
@ -164,8 +119,6 @@ dependencies {
|
||||
// The version of react-native is set by the React Native Gradle Plugin
|
||||
implementation("com.facebook.react:react-android")
|
||||
|
||||
implementation("androidx.swiperefreshlayout:swiperefreshlayout:1.0.0")
|
||||
|
||||
debugImplementation("com.facebook.flipper:flipper:${FLIPPER_VERSION}")
|
||||
debugImplementation("com.facebook.flipper:flipper-network-plugin:${FLIPPER_VERSION}") {
|
||||
exclude group:'com.squareup.okhttp3', module:'okhttp'
|
||||
|
||||
@ -27,9 +27,6 @@ public class MainActivity extends ReactActivity {
|
||||
this,
|
||||
getMainComponentName(),
|
||||
// If you opted-in for the New Architecture, we enable the Fabric Renderer.
|
||||
DefaultNewArchitectureEntryPoint.getFabricEnabled(), // fabricEnabled
|
||||
// If you opted-in for the New Architecture, we enable Concurrent React (i.e. React 18).
|
||||
DefaultNewArchitectureEntryPoint.getConcurrentReactEnabled() // concurrentRootEnabled
|
||||
);
|
||||
DefaultNewArchitectureEntryPoint.getFabricEnabled());
|
||||
}
|
||||
}
|
||||
|
||||
@ -20,7 +20,7 @@
|
||||
android:insetBottom="@dimen/abc_edit_text_inset_bottom_material">
|
||||
|
||||
<selector>
|
||||
<!--
|
||||
<!--
|
||||
This file is a copy of abc_edit_text_material (https://bit.ly/3k8fX7I).
|
||||
The item below with state_pressed="false" and state_focused="false" causes a NullPointerException.
|
||||
NullPointerException:tempt to invoke virtual method 'android.graphics.drawable.Drawable android.graphics.drawable.Drawable$ConstantState.newDrawable(android.content.res.Resources)'
|
||||
|
||||
@ -16,7 +16,7 @@ buildscript {
|
||||
mavenCentral()
|
||||
}
|
||||
dependencies {
|
||||
classpath("com.android.tools.build:gradle:7.3.1")
|
||||
classpath("com.android.tools.build:gradle")
|
||||
classpath("com.facebook.react:react-native-gradle-plugin")
|
||||
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion")
|
||||
}
|
||||
|
||||
@ -25,7 +25,7 @@ android.useAndroidX=true
|
||||
android.enableJetifier=true
|
||||
|
||||
# Version of flipper SDK to use with React Native
|
||||
FLIPPER_VERSION=0.125.0
|
||||
FLIPPER_VERSION=0.182.0
|
||||
|
||||
# Use this property to specify which architecture you want to build.
|
||||
# You can also override it from the CLI using
|
||||
|
||||
Binary file not shown.
@ -1,5 +1,6 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-all.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.0.1-all.zip
|
||||
networkTimeout=10000
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
|
||||
@ -14,7 +14,7 @@
|
||||
@rem limitations under the License.
|
||||
@rem
|
||||
|
||||
@if "%DEBUG%" == "" @echo off
|
||||
@if "%DEBUG%"=="" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Gradle startup script for Windows
|
||||
@ -25,7 +25,8 @@
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%" == "" set DIRNAME=.
|
||||
if "%DIRNAME%"=="" set DIRNAME=.
|
||||
@rem This is normally unused
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@ -40,7 +41,7 @@ if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if "%ERRORLEVEL%" == "0" goto execute
|
||||
if %ERRORLEVEL% equ 0 goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
@ -75,13 +76,15 @@ set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||
if %ERRORLEVEL% equ 0 goto mainEnd
|
||||
|
||||
:fail
|
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||
rem the _cmd.exe /c_ return code!
|
||||
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||
exit /b 1
|
||||
set EXIT_CODE=%ERRORLEVEL%
|
||||
if %EXIT_CODE% equ 0 set EXIT_CODE=1
|
||||
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
|
||||
exit /b %EXIT_CODE%
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
||||
@ -55,7 +55,7 @@
|
||||
# Darwin, MinGW, and NonStop.
|
||||
#
|
||||
# (3) This script is generated from the Groovy template
|
||||
# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
||||
# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
||||
# within the Gradle project.
|
||||
#
|
||||
# You can find Gradle at https://github.com/gradle/gradle/.
|
||||
@ -80,10 +80,10 @@ do
|
||||
esac
|
||||
done
|
||||
|
||||
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
|
||||
|
||||
APP_NAME="Gradle"
|
||||
# This is normally unused
|
||||
# shellcheck disable=SC2034
|
||||
APP_BASE_NAME=${0##*/}
|
||||
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||
@ -143,12 +143,16 @@ fi
|
||||
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
|
||||
case $MAX_FD in #(
|
||||
max*)
|
||||
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
|
||||
# shellcheck disable=SC3045
|
||||
MAX_FD=$( ulimit -H -n ) ||
|
||||
warn "Could not query maximum file descriptor limit"
|
||||
esac
|
||||
case $MAX_FD in #(
|
||||
'' | soft) :;; #(
|
||||
*)
|
||||
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
|
||||
# shellcheck disable=SC3045
|
||||
ulimit -n "$MAX_FD" ||
|
||||
warn "Could not set maximum file descriptor limit to $MAX_FD"
|
||||
esac
|
||||
@ -205,6 +209,12 @@ set -- \
|
||||
org.gradle.wrapper.GradleWrapperMain \
|
||||
"$@"
|
||||
|
||||
# Stop when "xargs" is not available.
|
||||
if ! command -v xargs >/dev/null 2>&1
|
||||
then
|
||||
die "xargs is not available"
|
||||
fi
|
||||
|
||||
# Use "xargs" to parse quoted args.
|
||||
#
|
||||
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
rootProject.name = '<%= className %>'
|
||||
|
||||
apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings)
|
||||
include ':app'
|
||||
includeBuild('../node_modules/react-native-gradle-plugin')
|
||||
includeBuild('../node_modules/@react-native/gradle-plugin')
|
||||
|
||||
@ -1,5 +1,9 @@
|
||||
require_relative '<%= offsetFromRoot %>../node_modules/react-native/scripts/react_native_pods'
|
||||
require_relative '<%= offsetFromRoot %>../node_modules/@react-native-community/cli-platform-ios/native_modules'
|
||||
# Resolve react_native_pods.rb with node to allow for hoisting
|
||||
require Pod::Executable.execute_command('node', ['-p',
|
||||
'require.resolve(
|
||||
"react-native/scripts/react_native_pods.rb",
|
||||
{paths: [process.argv[1]]},
|
||||
)', __dir__]).strip
|
||||
|
||||
platform :ios, min_ios_version_supported
|
||||
prepare_react_native_project!
|
||||
@ -30,8 +34,6 @@ target '<%= className %>' do
|
||||
use_react_native!(
|
||||
:path => config[:reactNativePath],
|
||||
# Hermes is now enabled by default. Disable by setting this flag to false.
|
||||
# Upcoming versions of React Native may rely on get_default_flags(), but
|
||||
# we make it explicit here to aid in the React Native upgrade process.
|
||||
:hermes_enabled => flags[:hermes_enabled],
|
||||
:fabric_enabled => flags[:fabric_enabled],
|
||||
# Enables Flipper.
|
||||
@ -49,10 +51,10 @@ target '<%= className %>' do
|
||||
end
|
||||
|
||||
post_install do |installer|
|
||||
# https://github.com/facebook/react-native/blob/main/packages/react-native/scripts/react_native_pods.rb#L197-L202
|
||||
react_native_post_install(
|
||||
installer,
|
||||
# Set `mac_catalyst_enabled` to `true` in order to apply patches
|
||||
# necessary for Mac Catalyst builds
|
||||
config[:reactNativePath],
|
||||
:mac_catalyst_enabled => false
|
||||
)
|
||||
__apply_Xcode_12_5_M1_post_install_workaround(installer)
|
||||
|
||||
@ -564,7 +564,7 @@
|
||||
COPY_PHASE_STRIP = NO;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
ENABLE_TESTABILITY = YES;
|
||||
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = "";
|
||||
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = i386;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_DYNAMIC_NO_PIC = NO;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
@ -592,12 +592,14 @@
|
||||
);
|
||||
MTL_ENABLE_DEBUG_INFO = YES;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
OTHER_CFLAGS = "$(inherited)";
|
||||
OTHER_CPLUSPLUSFLAGS = (
|
||||
"$(OTHER_CFLAGS)",
|
||||
"-DFOLLY_NO_CONFIG",
|
||||
"-DFOLLY_MOBILE=1",
|
||||
"-DFOLLY_USE_LIBCPP=1",
|
||||
);
|
||||
REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native";
|
||||
SDKROOT = iphoneos;
|
||||
};
|
||||
name = Debug;
|
||||
@ -635,7 +637,7 @@
|
||||
COPY_PHASE_STRIP = YES;
|
||||
ENABLE_NS_ASSERTIONS = NO;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = "";
|
||||
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = i386;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
@ -655,12 +657,14 @@
|
||||
"\"$(inherited)\"",
|
||||
);
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
OTHER_CFLAGS = "$(inherited)";
|
||||
OTHER_CPLUSPLUSFLAGS = (
|
||||
"$(OTHER_CFLAGS)",
|
||||
"-DFOLLY_NO_CONFIG",
|
||||
"-DFOLLY_MOBILE=1",
|
||||
"-DFOLLY_USE_LIBCPP=1",
|
||||
);
|
||||
REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native";
|
||||
SDKROOT = iphoneos;
|
||||
VALIDATE_PRODUCT = YES;
|
||||
};
|
||||
|
||||
@ -23,14 +23,4 @@
|
||||
#endif
|
||||
}
|
||||
|
||||
/// This method controls whether the `concurrentRoot`feature of React18 is turned on or off.
|
||||
///
|
||||
/// @see: https://reactjs.org/blog/2022/03/29/react-v18.html
|
||||
/// @note: This requires to be rendering on Fabric (i.e. on the New Architecture).
|
||||
/// @return: `true` if the `concurrentRoot` feature is enabled. Otherwise, it returns `false`.
|
||||
- (BOOL)concurrentRootEnabled
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@ -1,38 +1,35 @@
|
||||
const { withNxMetro } = require('@nx/react-native');
|
||||
const { getDefaultConfig } = require('metro-config');
|
||||
const { getDefaultConfig, mergeConfig } = require('@react-native/metro-config');
|
||||
const exclusionList = require('metro-config/src/defaults/exclusionList');
|
||||
|
||||
module.exports = (async () => {
|
||||
const {
|
||||
resolver: { sourceExts, assetExts },
|
||||
} = await getDefaultConfig();
|
||||
return withNxMetro(
|
||||
{
|
||||
transformer: {
|
||||
getTransformOptions: async () => ({
|
||||
transform: {
|
||||
experimentalImportSupport: false,
|
||||
inlineRequires: true,
|
||||
},
|
||||
}),
|
||||
babelTransformerPath: require.resolve('react-native-svg-transformer'),
|
||||
},
|
||||
resolver: {
|
||||
assetExts: assetExts.filter((ext) => ext !== 'svg'),
|
||||
sourceExts: [...sourceExts, 'svg'],
|
||||
blockList: exclusionList([/^(?!.*node_modules).*\/dist\/.*/]),
|
||||
},
|
||||
},
|
||||
{
|
||||
// Change this to true to see debugging info.
|
||||
// Useful if you have issues resolving modules
|
||||
debug: false,
|
||||
// all the file extensions used for imports other than 'ts', 'tsx', 'js', 'jsx', 'json'
|
||||
extensions: [],
|
||||
// the project root to start the metro server
|
||||
projectRoot: __dirname,
|
||||
// Specify folders to watch, in addition to Nx defaults (workspace libraries and node_modules)
|
||||
watchFolders: []
|
||||
}
|
||||
);
|
||||
})();
|
||||
const defaultConfig = getDefaultConfig(__dirname);
|
||||
const { assetExts, sourceExts } = defaultConfig.resolver;
|
||||
|
||||
/**
|
||||
* Metro configuration
|
||||
* https://facebook.github.io/metro/docs/configuration
|
||||
*
|
||||
* @type {import('metro-config').MetroConfig}
|
||||
*/
|
||||
const customConfig = {
|
||||
transformer: {
|
||||
babelTransformerPath: require.resolve('react-native-svg-transformer'),
|
||||
},
|
||||
resolver: {
|
||||
assetExts: assetExts.filter((ext) => ext !== 'svg'),
|
||||
sourceExts: [...sourceExts, 'svg'],
|
||||
blockList: exclusionList([/^(?!.*node_modules).*\/dist\/.*/]),
|
||||
unstable_enableSymlinks: true,
|
||||
unstable_enablePackageExports: true,
|
||||
},
|
||||
};
|
||||
|
||||
module.exports = withNxMetro(mergeConfig(defaultConfig, customConfig), {
|
||||
// Change this to true to see debugging info.
|
||||
// Useful if you have issues resolving modules
|
||||
debug: false,
|
||||
// all the file extensions used for imports other than 'ts', 'tsx', 'js', 'jsx', 'json'
|
||||
extensions: [],
|
||||
// Specify folders to watch, in addition to Nx defaults (workspace libraries and node_modules)
|
||||
watchFolders: [],
|
||||
});
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
"version": "0.0.1",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@react-native/metro-config": "*",
|
||||
"@testing-library/jest-native": "*",
|
||||
"@testing-library/react-native": "*",
|
||||
"react": "*",
|
||||
|
||||
@ -25,6 +25,7 @@ function getTargets(options: NormalizedSchema) {
|
||||
|
||||
architect.start = {
|
||||
executor: '@nx/react-native:start',
|
||||
dependsOn: ['ensure-symlink', 'sync-deps', 'pod-install'],
|
||||
options: {
|
||||
port: 8081,
|
||||
},
|
||||
@ -39,11 +40,13 @@ function getTargets(options: NormalizedSchema) {
|
||||
|
||||
architect['run-ios'] = {
|
||||
executor: '@nx/react-native:run-ios',
|
||||
dependsOn: ['ensure-symlink', 'sync-deps', 'pod-install'],
|
||||
options: {},
|
||||
};
|
||||
|
||||
architect['bundle-ios'] = {
|
||||
executor: '@nx/react-native:bundle',
|
||||
dependsOn: ['ensure-symlink'],
|
||||
outputs: ['{options.bundleOutput}'],
|
||||
options: {
|
||||
entryFile: options.entryFile,
|
||||
@ -54,6 +57,7 @@ function getTargets(options: NormalizedSchema) {
|
||||
|
||||
architect['run-android'] = {
|
||||
executor: '@nx/react-native:run-android',
|
||||
dependsOn: ['ensure-symlink', 'sync-deps'],
|
||||
options: {},
|
||||
};
|
||||
|
||||
@ -63,12 +67,14 @@ function getTargets(options: NormalizedSchema) {
|
||||
`{projectRoot}/android/app/build/outputs/bundle`,
|
||||
`{projectRoot}/android/app/build/outputs/apk`,
|
||||
],
|
||||
dependsOn: ['ensure-symlink', 'sync-deps'],
|
||||
options: {},
|
||||
};
|
||||
|
||||
architect['build-ios'] = {
|
||||
executor: '@nx/react-native:build-ios',
|
||||
outputs: ['{projectRoot}/ios/build/Build'],
|
||||
dependsOn: ['ensure-symlink', 'sync-deps', 'pod-install'],
|
||||
options: {},
|
||||
};
|
||||
|
||||
@ -79,6 +85,7 @@ function getTargets(options: NormalizedSchema) {
|
||||
|
||||
architect['bundle-android'] = {
|
||||
executor: '@nx/react-native:bundle',
|
||||
dependsOn: ['ensure-symlink'],
|
||||
outputs: ['{options.bundleOutput}'],
|
||||
options: {
|
||||
entryFile: options.entryFile,
|
||||
|
||||
@ -24,6 +24,7 @@ import {
|
||||
reactNativeCommunityCli,
|
||||
reactNativeCommunityCliAndroid,
|
||||
reactNativeCommunityCliIos,
|
||||
reactNativeMetroConfigVersion,
|
||||
reactNativeSvgTransformerVersion,
|
||||
reactNativeSvgVersion,
|
||||
reactNativeVersion,
|
||||
@ -90,6 +91,7 @@ export function updateDependencies(host: Tree) {
|
||||
'@types/node': typesNodeVersion,
|
||||
'@types/react': typesReactVersion,
|
||||
'@types/react-native': typesReactNativeVersion,
|
||||
'@react-native/metro-config': reactNativeMetroConfigVersion,
|
||||
'@react-native-community/cli': reactNativeCommunityCli,
|
||||
'@react-native-community/cli-platform-android':
|
||||
reactNativeCommunityCliAndroid,
|
||||
@ -98,6 +100,7 @@ export function updateDependencies(host: Tree) {
|
||||
'@testing-library/jest-native': testingLibraryJestNativeVersion,
|
||||
'jest-react-native': jestReactNativeVersion,
|
||||
metro: metroVersion,
|
||||
'metro-config': metroVersion,
|
||||
'metro-resolver': metroVersion,
|
||||
'metro-babel-register': metroVersion,
|
||||
'metro-react-native-babel-preset': metroVersion,
|
||||
@ -108,7 +111,6 @@ export function updateDependencies(host: Tree) {
|
||||
'@babel/preset-react': babelPresetReactVersion,
|
||||
...(isPnpm
|
||||
? {
|
||||
'metro-config': metroVersion, // metro-config is used by metro.config.js
|
||||
'@babel/runtime': babelRuntimeVersion, // @babel/runtime is used by react-native-svg
|
||||
}
|
||||
: {}),
|
||||
|
||||
@ -170,7 +170,6 @@ function createFiles(host: Tree, options: NormalizedSchema) {
|
||||
{
|
||||
...options,
|
||||
...names(options.name),
|
||||
tmpl: '',
|
||||
offsetFromRoot: offsetFromRoot(options.projectRoot),
|
||||
rootTsConfigPath: getRelativePathToRootTsConfig(
|
||||
host,
|
||||
|
||||
@ -0,0 +1,39 @@
|
||||
import { Tree, getProjects, updateProjectConfiguration } from '@nx/devkit';
|
||||
|
||||
/**
|
||||
* This migration adds dependsOn to project.json.
|
||||
*
|
||||
*/
|
||||
export default async function update(tree: Tree) {
|
||||
const projects = getProjects(tree);
|
||||
|
||||
for (const [name, config] of projects.entries()) {
|
||||
if (config.targets?.['start']?.executor === '@nx/react-native:start') {
|
||||
config.targets['start'].dependsOn = [
|
||||
'ensure-symlink',
|
||||
'sync-deps',
|
||||
'pod-install',
|
||||
];
|
||||
config.targets['run-ios'].dependsOn = [
|
||||
'ensure-symlink',
|
||||
'sync-deps',
|
||||
'pod-install',
|
||||
];
|
||||
config.targets['bundle-ios'].dependsOn = ['ensure-symlink'];
|
||||
config.targets['run-android'].dependsOn = ['ensure-symlink', 'sync-deps'];
|
||||
config.targets['build-android'].dependsOn = [
|
||||
'ensure-symlink',
|
||||
'sync-deps',
|
||||
];
|
||||
config.targets['build-ios'].dependsOn = [
|
||||
'ensure-symlink',
|
||||
'sync-deps',
|
||||
'pod-install',
|
||||
];
|
||||
config.targets['pod-install'].dependsOn = ['ensure-symlink', 'sync-deps'];
|
||||
config.targets['bundle-android'].dependsOn = ['ensure-symlink'];
|
||||
|
||||
updateProjectConfiguration(tree, name, config);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,71 @@
|
||||
import { Tree, getProjects } from '@nx/devkit';
|
||||
import { join } from 'path';
|
||||
|
||||
/**
|
||||
* This migration updates metro.config.js to export config as a default.
|
||||
*
|
||||
*/
|
||||
export default async function update(tree: Tree) {
|
||||
const projects = getProjects(tree);
|
||||
|
||||
for (const [_, config] of projects.entries()) {
|
||||
if (config.targets?.['start']?.executor === '@nx/react-native:start') {
|
||||
if (tree.exists(join(config.root, 'metro.config.js'))) {
|
||||
const oldConfig = tree
|
||||
.read(join(config.root, 'metro.config.js'))
|
||||
.toString();
|
||||
tree.write(
|
||||
join(config.root, 'metro-v71.config.js'),
|
||||
oldConfigComment + oldConfig
|
||||
);
|
||||
tree.write(join(config.root, 'metro.config.js'), content);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const oldConfigComment = `/**
|
||||
* Old custom configuration for React Native v0.71.
|
||||
* From @react-native/metro-config 0.72.1, it is no longer necessary to use a config function to access the complete default config.
|
||||
* Please port your custom configuration to metro.config.js.
|
||||
* Please see https://reactnative.dev/docs/metro to learn about configuration.
|
||||
*/
|
||||
`;
|
||||
|
||||
const content = `
|
||||
const { withNxMetro } = require('@nx/react-native');
|
||||
const { getDefaultConfig, mergeConfig } = require('@react-native/metro-config');
|
||||
const exclusionList = require('metro-config/src/defaults/exclusionList');
|
||||
|
||||
const defaultConfig = getDefaultConfig(__dirname);
|
||||
const { assetExts, sourceExts } = defaultConfig.resolver;
|
||||
|
||||
/**
|
||||
* Metro configuration
|
||||
* https://facebook.github.io/metro/docs/configuration
|
||||
*
|
||||
* @type {import('metro-config').MetroConfig}
|
||||
*/
|
||||
const customConfig = {
|
||||
transformer: {
|
||||
babelTransformerPath: require.resolve('react-native-svg-transformer'),
|
||||
},
|
||||
resolver: {
|
||||
assetExts: assetExts.filter((ext) => ext !== 'svg'),
|
||||
sourceExts: [...sourceExts, 'svg'],
|
||||
blockList: exclusionList([/^(?!.*node_modules).*\/dist\/.*/]),
|
||||
unstable_enableSymlinks: true,
|
||||
unstable_enablePackageExports: true,
|
||||
},
|
||||
};
|
||||
|
||||
module.exports = withNxMetro(mergeConfig(defaultConfig, customConfig), {
|
||||
// Change this to true to see debugging info.
|
||||
// Useful if you have issues resolving modules
|
||||
debug: false,
|
||||
// all the file extensions used for imports other than 'ts', 'tsx', 'js', 'jsx', 'json'
|
||||
extensions: [],
|
||||
// Specify folders to watch, in addition to Nx defaults (workspace libraries and node_modules)
|
||||
watchFolders: [],
|
||||
});
|
||||
`;
|
||||
@ -18,7 +18,9 @@ export function getCliOptions<T>(
|
||||
const cliKey = optionKeysInCamelName.includes(optionKey)
|
||||
? names(optionKey).propertyName
|
||||
: names(optionKey).fileName; // cli uses kebab case as default
|
||||
if (typeof optionValue === 'boolean' && optionValue) {
|
||||
if (Array.isArray(optionValue)) {
|
||||
acc.push(`--${cliKey}`, optionValue.join(','));
|
||||
} else if (typeof optionValue === 'boolean' && optionValue) {
|
||||
// no need to pass in the value when it is true, just the flag name
|
||||
acc.push(`--${cliKey}`);
|
||||
} else {
|
||||
|
||||
@ -24,7 +24,15 @@ ${chalk.bold('sudo xcode-select --switch /Applications/Xcode.app')}
|
||||
export function runPodInstall(
|
||||
iosDirectory: string,
|
||||
install: boolean = true,
|
||||
buildFolder?: string
|
||||
options: {
|
||||
buildFolder?: string;
|
||||
repoUpdate?: boolean;
|
||||
deployment?: boolean;
|
||||
} = {
|
||||
buildFolder: './build',
|
||||
repoUpdate: false,
|
||||
deployment: false,
|
||||
}
|
||||
): GeneratorCallback {
|
||||
return () => {
|
||||
if (platform() !== 'darwin') {
|
||||
@ -39,16 +47,32 @@ export function runPodInstall(
|
||||
|
||||
logger.info(`Running \`pod install\` from "${iosDirectory}"`);
|
||||
|
||||
return podInstall(iosDirectory, buildFolder);
|
||||
return podInstall(iosDirectory, options);
|
||||
};
|
||||
}
|
||||
|
||||
export function podInstall(iosDirectory: string, buildFolder?: string) {
|
||||
export function podInstall(
|
||||
iosDirectory: string,
|
||||
options: {
|
||||
buildFolder?: string;
|
||||
repoUpdate?: boolean;
|
||||
deployment?: boolean;
|
||||
} = {
|
||||
buildFolder: './build',
|
||||
repoUpdate: false,
|
||||
deployment: false,
|
||||
}
|
||||
) {
|
||||
try {
|
||||
execSync('pod install', {
|
||||
cwd: iosDirectory,
|
||||
stdio: 'inherit',
|
||||
});
|
||||
execSync(
|
||||
`pod install ${options.repoUpdate ? '--repo-update' : ''} ${
|
||||
options.deployment ? '--deployment' : ''
|
||||
}`,
|
||||
{
|
||||
cwd: iosDirectory,
|
||||
stdio: 'inherit',
|
||||
}
|
||||
);
|
||||
} catch (e) {
|
||||
logger.error(podInstallErrorMessage);
|
||||
throw e;
|
||||
|
||||
@ -1,15 +1,16 @@
|
||||
export const nxVersion = require('../../package.json').version;
|
||||
|
||||
export const reactNativeVersion = '0.71.10';
|
||||
export const typesReactNativeVersion = '0.71.7';
|
||||
export const reactNativeVersion = '0.72.3';
|
||||
export const typesReactNativeVersion = '0.72.2';
|
||||
|
||||
export const typesNodeVersion = '18.14.4';
|
||||
|
||||
export const metroVersion = '0.74.1';
|
||||
export const metroVersion = '0.76.7';
|
||||
export const reactNativeMetroConfigVersion = '^0.72.9';
|
||||
|
||||
export const reactNativeCommunityCli = '10.2.2';
|
||||
export const reactNativeCommunityCliIos = '10.2.1';
|
||||
export const reactNativeCommunityCliAndroid = '10.2.0';
|
||||
export const reactNativeCommunityCli = '11.3.5';
|
||||
export const reactNativeCommunityCliIos = '11.3.5';
|
||||
export const reactNativeCommunityCliAndroid = '11.3.5';
|
||||
|
||||
export const reactVersion = '18.2.0';
|
||||
export const reactDomVersion = '18.2.0';
|
||||
@ -24,7 +25,7 @@ export const jestReactNativeVersion = '18.0.0';
|
||||
export const reactNativeSvgTransformerVersion = '1.0.0';
|
||||
export const reactNativeSvgVersion = '13.9.0';
|
||||
|
||||
export const babelRuntimeVersion = '7.21.0';
|
||||
export const babelRuntimeVersion = '7.22.6';
|
||||
|
||||
export const reactNativeAsyncStorageVersion = '1.18.2';
|
||||
export const reactNativeSafeAreaContextVersion = '4.5.3';
|
||||
export const reactNativeAsyncStorageVersion = '1.19.0';
|
||||
export const reactNativeSafeAreaContextVersion = '4.7.1';
|
||||
|
||||
705
pnpm-lock.yaml
generated
705
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user