Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .changeset/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,6 @@
"fixed": [["@rock-js/*", "rock", "create-rock"]],
"access": "public",
"baseBranch": "main",
"updateInternalDependencies": "patch"
"updateInternalDependencies": "patch",
"ignore": ["expo-config-plugins-test-app", "rock-docs"]
}
9 changes: 9 additions & 0 deletions .changeset/upset-wombats-repair.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
'@rock-js/plugin-brownfield-android': minor
'@rock-js/welcome-screen': minor
'@rock-js/platform-ios': minor
'@rock-js/plugin-metro': minor
'@rock-js/provider-s3': minor
---

upgrade to react-native v0.86.0
8 changes: 8 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,14 @@ pnpm link --global ...
pnpm verdaccio:reset
```

## Running expo-config-plugins-test-app
- Run `pnpm install` and `pnpm build` from the root
- In a new terminal, from the root run `pnpm watch`
- Run `pnpm install` from the app
- Run `pnpm prebuild` command from `apps/expo-config-plugins-test-app`
- Run `pnpm ios` or `pnpm android`
- In a new terminal, run `pnpm start`

## Typechecking, linting and testing

Currently we use TypeScript for typechecking, `eslint` with `prettier` for linting and formatting the code and `jest` for testing.
Expand Down
4 changes: 4 additions & 0 deletions apps/expo-config-plugins-test-app/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -76,3 +76,7 @@ yarn-error.log

# Rock
.rock/

# prebuild native directories
ios/
android/
123 changes: 123 additions & 0 deletions apps/expo-config-plugins-test-app/Gemfile.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
GEM
remote: https://rubygems.org/
specs:
CFPropertyList (3.0.8)
activesupport (7.2.3.1)
base64
benchmark (>= 0.3)
bigdecimal
concurrent-ruby (~> 1.0, >= 1.3.1)
connection_pool (>= 2.2.5)
drb
i18n (>= 1.6, < 2)
logger (>= 1.4.2)
minitest (>= 5.1, < 6)
securerandom (>= 0.3)
tzinfo (~> 2.0, >= 2.0.5)
addressable (2.9.0)
public_suffix (>= 2.0.2, < 8.0)
algoliasearch (1.27.5)
httpclient (~> 2.8, >= 2.8.3)
json (>= 1.5.1)
atomos (0.1.3)
base64 (0.3.0)
benchmark (0.5.0)
bigdecimal (4.1.2)
claide (1.1.0)
cocoapods (1.15.2)
addressable (~> 2.8)
claide (>= 1.0.2, < 2.0)
cocoapods-core (= 1.15.2)
cocoapods-deintegrate (>= 1.0.3, < 2.0)
cocoapods-downloader (>= 2.1, < 3.0)
cocoapods-plugins (>= 1.0.0, < 2.0)
cocoapods-search (>= 1.0.0, < 2.0)
cocoapods-trunk (>= 1.6.0, < 2.0)
cocoapods-try (>= 1.1.0, < 2.0)
colored2 (~> 3.1)
escape (~> 0.0.4)
fourflusher (>= 2.3.0, < 3.0)
gh_inspector (~> 1.0)
molinillo (~> 0.8.0)
nap (~> 1.0)
ruby-macho (>= 2.3.0, < 3.0)
xcodeproj (>= 1.23.0, < 2.0)
cocoapods-core (1.15.2)
activesupport (>= 5.0, < 8)
addressable (~> 2.8)
algoliasearch (~> 1.0)
concurrent-ruby (~> 1.1)
fuzzy_match (~> 2.0.4)
nap (~> 1.0)
netrc (~> 0.11)
public_suffix (~> 4.0)
typhoeus (~> 1.0)
cocoapods-deintegrate (1.0.5)
cocoapods-downloader (2.1)
cocoapods-plugins (1.0.0)
nap
cocoapods-search (1.0.1)
cocoapods-trunk (1.6.0)
nap (>= 0.8, < 2.0)
netrc (~> 0.11)
cocoapods-try (1.2.0)
colored2 (3.1.2)
concurrent-ruby (1.3.3)
connection_pool (3.0.2)
drb (2.2.3)
escape (0.0.4)
ethon (0.18.0)
ffi (>= 1.15.0)
logger
ffi (1.17.4)
fourflusher (2.3.1)
fuzzy_match (2.0.4)
gh_inspector (1.1.3)
httpclient (2.9.0)
mutex_m
i18n (1.15.2)
concurrent-ruby (~> 1.0)
json (2.20.0)
logger (1.7.0)
minitest (5.27.0)
molinillo (0.8.0)
mutex_m (0.3.0)
nanaimo (0.3.0)
nap (1.1.0)
netrc (0.11.0)
nkf (0.3.0)
public_suffix (4.0.7)
rexml (3.4.4)
ruby-macho (2.5.1)
securerandom (0.4.1)
typhoeus (1.6.0)
ethon (>= 0.18.0)
tzinfo (2.0.6)
concurrent-ruby (~> 1.0)
xcodeproj (1.25.1)
CFPropertyList (>= 2.3.3, < 4.0)
atomos (~> 0.1.3)
claide (>= 1.0.2, < 2.0)
colored2 (~> 3.1)
nanaimo (~> 0.3.0)
rexml (>= 3.3.6, < 4.0)

PLATFORMS
ruby

DEPENDENCIES
activesupport (>= 6.1.7.5, != 7.1.0)
benchmark
bigdecimal
cocoapods (>= 1.13, != 1.15.1, != 1.15.0)
concurrent-ruby (< 1.3.4)
logger
mutex_m
nkf
xcodeproj (< 1.26.0)

RUBY VERSION
ruby 3.3.6p108

BUNDLED WITH
2.5.22
16 changes: 14 additions & 2 deletions apps/expo-config-plugins-test-app/metro.config.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
const path = require('path');
const { getDefaultConfig, mergeConfig } = require('@react-native/metro-config');

/**
Expand All @@ -6,6 +7,17 @@ const { getDefaultConfig, mergeConfig } = require('@react-native/metro-config');
*
* @type {import('@react-native/metro-config').MetroConfig}
*/
const config = {};
const projectRoot = __dirname;
const workspaceRoot = path.resolve(projectRoot, '../..');

module.exports = mergeConfig(getDefaultConfig(__dirname), config);
const config = {
watchFolders: [workspaceRoot],
resolver: {
nodeModulesPaths: [
path.resolve(projectRoot, 'node_modules'),
path.resolve(workspaceRoot, 'node_modules'),
],
},
};

module.exports = mergeConfig(getDefaultConfig(projectRoot), config);
30 changes: 16 additions & 14 deletions apps/expo-config-plugins-test-app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,35 +7,37 @@
"lint": "eslint .",
"test": "jest",
"ios": "rock run:ios",
"android": "rock run:android"
"android": "rock run:android",
"prebuild": "rock prebuild && node ./scripts/patch-settings.js"
},
"dependencies": {
"@bottom-tabs/react-navigation": "^1.1.0",
"expo-build-properties": "^1.0.10",
"react": "19.2.0",
"react-native": "0.83.0",
"react": "19.2.7",
"react-native": "0.86.0",
"react-native-bottom-tabs": "^1.1.0"
},
"devDependencies": {
"@rock-js/plugin-expo-config-plugins": "*",
"@babel/core": "^7.25.2",
"@babel/preset-env": "^7.25.3",
"@babel/runtime": "^7.25.0",
"@react-native/babel-preset": "0.83.0",
"@react-native/eslint-config": "0.83.0",
"@react-native/metro-config": "0.83.0",
"@react-native/typescript-config": "0.83.0",
"@rock-js/platform-android": "^0.14.0",
"@rock-js/platform-ios": "^0.14.0",
"@rock-js/plugin-metro": "^0.14.0",
"@rock-js/welcome-screen": "^0.14.0",
"@types/react": "^19.2.0",
"@react-native/babel-preset": "0.86.0",
"@react-native/eslint-config": "0.86.0",
"@react-native/metro-config": "0.86.0",
"@react-native/typescript-config": "0.86.0",
"@rock-js/platform-android": "*",
"@rock-js/platform-ios": "*",
"@rock-js/plugin-metro": "*",
"@rock-js/welcome-screen": "*",
"@types/react": "^19.2.17",
"@types/react-test-renderer": "^19.1.0",
"babel-jest": "^29.6.3",
"eslint": "^8.19.0",
"jest": "^29.6.3",
"prettier": "2.8.8",
"react-test-renderer": "19.2.0",
"rock": "^0.14.0",
"react-test-renderer": "19.2.7",
"rock": "*",
"typescript": "^5.8.3"
},
"engines": {
Expand Down
2 changes: 2 additions & 0 deletions apps/expo-config-plugins-test-app/rock.config.mjs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { platformIOS } from '@rock-js/platform-ios';
import { platformAndroid } from '@rock-js/platform-android';
import { pluginMetro } from '@rock-js/plugin-metro';
import { pluginExpoConfigPlugins } from '@rock-js/plugin-expo-config-plugins';

export default {
plugins: [pluginExpoConfigPlugins()],
bundler: pluginMetro(),
platforms: {
ios: platformIOS(),
Expand Down
125 changes: 125 additions & 0 deletions apps/expo-config-plugins-test-app/scripts/patch-settings.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
const fs = require('node:fs');
const path = require('node:path');

const projectRoot = path.resolve(__dirname, '..');
const settingsGradlePath = path.join(projectRoot, 'android', 'settings.gradle');
const appBuildGradlePath = path.join(
projectRoot,
'android',
'app',
'build.gradle',
);

const pluginManagementLine =
'pluginManagement { includeBuild("../node_modules/@react-native/gradle-plugin") }';
const trailingIncludeLine =
"includeBuild('../node_modules/@react-native/gradle-plugin')";

/**
* Only required to satisfy the updated paths in the generated template.
* This is due to pnpm's package resolution strategy.
*
* React Native generates relative ../node_modules paths here, but that breaks with pnpm
* because packages live under the pnpm store and are exposed via symlinks. We resolve
* the installed react-native package first, then derive the Gradle plugin/codegen paths
* from that real location so Android can find them reliably.
*/
const patchedContent = `pluginManagement {
def reactNativePackageDir = providers.exec {
commandLine("node", "--print", "require('path').dirname(require.resolve('react-native/package.json'))")
}.standardOutput.asText.get().trim()
includeBuild(new File(reactNativePackageDir, "../@react-native/gradle-plugin").canonicalPath)
}
plugins { id("com.facebook.react.settings") }
def reactNativePackageDir = providers.exec {
commandLine("node", "--print", "require('path').dirname(require.resolve('react-native/package.json'))")
}.standardOutput.asText.get().trim()
def reactNativeGradlePluginDir = new File(reactNativePackageDir, "../@react-native/gradle-plugin").canonicalPath
extensions.configure(com.facebook.react.ReactSettingsExtension){ ex -> ex.autolinkLibrariesFromCommand(['npx', 'rock', 'config', '-p', 'android']) }
rootProject.name = 'ExpoConfigPluginsTestApp'
include ':app'
includeBuild(reactNativeGradlePluginDir)
`;

const reactBlockNeedle = `react {
/* Folders */
// The root of your project, i.e. where "package.json" lives. Default is '../..'
// 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 cli.js file which is the React Native CLI entrypoint. Default is ../../node_modules/react-native/cli.js
cliFile = file("../../node_modules/rock/dist/src/bin.js")
`;

const patchedReactBlock = `def reactNativePackageDir = providers.exec {
commandLine("node", "--print", "require('path').dirname(require.resolve('react-native/package.json'))")
}.standardOutput.asText.get().trim()
def reactNativeCodegenDir = new File(reactNativePackageDir, "../@react-native/codegen").canonicalPath

react {
reactNativeDir = file(reactNativePackageDir)
codegenDir = file(reactNativeCodegenDir)

/* Folders */
// The root of your project, i.e. where "package.json" lives. Default is '../..'
// 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 cli.js file which is the React Native CLI entrypoint. Default is ../../node_modules/react-native/cli.js
cliFile = file("../../node_modules/rock/dist/src/bin.js")
`;

if (!fs.existsSync(settingsGradlePath)) {
throw new Error(`Missing android/settings.gradle at ${settingsGradlePath}`);
}
if (!fs.existsSync(appBuildGradlePath)) {
throw new Error(`Missing android/app/build.gradle at ${appBuildGradlePath}`);
}

const original = fs.readFileSync(settingsGradlePath, 'utf8');

if (original === patchedContent) {
console.log('settings.gradle already patched');
process.exit(0);
}

if (
!original.includes(pluginManagementLine) ||
!original.includes(trailingIncludeLine) ||
!original.includes(
"extensions.configure(com.facebook.react.ReactSettingsExtension){ ex -> ex.autolinkLibrariesFromCommand(['npx', 'rock', 'config', '-p', 'android']) }",
) ||
!original.includes("rootProject.name = 'ExpoConfigPluginsTestApp'") ||
!original.includes("include ':app'")
) {
throw new Error(
'android/settings.gradle does not match the expected generated template',
);
}

fs.writeFileSync(settingsGradlePath, patchedContent);
console.log('Patched android/settings.gradle');

const originalAppBuildGradle = fs.readFileSync(appBuildGradlePath, 'utf8');

if (!originalAppBuildGradle.includes('def reactNativeCodegenDir =')) {
if (!originalAppBuildGradle.includes(reactBlockNeedle)) {
throw new Error(
'android/app/build.gradle does not match the expected generated template',
);
}

const patchedAppBuildGradle = originalAppBuildGradle.replace(
reactBlockNeedle,
patchedReactBlock,
);

fs.writeFileSync(appBuildGradlePath, patchedAppBuildGradle);
console.log('Patched android/app/build.gradle');
} else {
console.log('app/build.gradle already patched');
}
6 changes: 5 additions & 1 deletion packages/platform-ios/template/ios/Podfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@ require File.join(File.dirname(`node --print "require.resolve('react-native/pack
# Inspired from https://github.com/expo/expo/blob/main/templates/expo-template-bare-minimum/ios/Podfile
podfile_properties = JSON.parse(File.read(File.join(__dir__, 'Podfile.properties.json'))) rescue {}

ENV['RCT_NEW_ARCH_ENABLED'] ||= '0' if podfile_properties['newArchEnabled'] == 'false'
if podfile_properties['newArchEnabled'] == 'true'
ENV['RCT_NEW_ARCH_ENABLED'] ||= '1'
elsif podfile_properties['newArchEnabled'] == 'false'
ENV['RCT_NEW_ARCH_ENABLED'] ||= '0'
end
ENV['RCT_USE_RN_DEP'] ||= '1' if podfile_properties['ios.buildReactNativeFromSource'] != 'true' && podfile_properties['newArchEnabled'] != 'false'
ENV['RCT_USE_PREBUILT_RNCORE'] ||= '1' if podfile_properties['ios.buildReactNativeFromSource'] != 'true' && podfile_properties['newArchEnabled'] != 'false'

Expand Down
3 changes: 2 additions & 1 deletion packages/platform-ios/template/ios/Podfile.properties.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
{
"expo.jsEngine": "hermes"
"expo.jsEngine": "hermes",
"newArchEnabled": "true"
}
Loading
Loading