Skip to content
Open
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 .github/workflows/check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,8 @@ jobs:
run: npx react-native bundle --entry-file index.js --platform macos --dev false --minify false --bundle-output dist/main.macos.jsbundle --assets-dest dist/res
working-directory: apps/macos-test-app
- name: Build test app
run: xcodebuild archive -workspace MacOSTestApp.xcworkspace -configuration Release -scheme MacOSTestApp-macOS -destination generic/platform="macOS" -archivePath ./build/macos-test-app.xcarchive | xcbeautify
# pipefail so an xcodebuild failure is not masked by xcbeautify's exit code
run: set -o pipefail && xcodebuild archive -workspace MacOSTestApp.xcworkspace -configuration Release -scheme MacOSTestApp-macOS -destination generic/platform="macOS" -archivePath ./build/macos-test-app.xcarchive | xcbeautify
working-directory: apps/macos-test-app/macos
- name: Run test app
run: npx mocha-remote --exit-on-error -- macos/build/macos-test-app.xcarchive/Products/Applications/MacOSTestApp.app/Contents/MacOS/MacOSTestApp
Expand Down
17 changes: 17 additions & 0 deletions apps/test-app/metro.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,23 @@ if (config.projectRoot.endsWith("macos-test-app")) {
// duplicate react-native version and pollution of the package lock.
const path = require("node:path");
config.watchFolders.push(path.resolve(__dirname, "../.."));

// The babel plugin rewrites `require("something.node")` inside the workspace
// packages (e.g. packages/ferric-example/ferric_example.js) into
// `require("react-native-node-api").requireNodeAddon(...)`. Those files live
// outside this app, so Metro resolves the bare `react-native-node-api` (and
// sibling workspace packages) by walking up from the package directory. Under
// npm's hoisted workspaces that specifier happens to sit in the repo-root
// node_modules, but under pnpm's isolated node_modules it does not, so the
// rewritten require fails to resolve. This app installs the workspace packages
// into its own node_modules (via `npm install` of `file:` deps), so add that
// directory as a global module-resolution path to make resolution independent
// of the root package manager's hoisting layout.
config.resolver = config.resolver || {};
config.resolver.nodeModulesPaths = [
...(config.resolver.nodeModulesPaths || []),
path.resolve(__dirname, "node_modules"),
];
}

module.exports = config;
25 changes: 24 additions & 1 deletion scripts/init-macos-test-app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,11 @@ async function patchPackageJson() {

const transferredDependencies = new Set([
"@rnx-kit/metro-config",
// `mocha-remote-server` (pulled in by `mocha-remote-cli`) requires `mocha` at
// runtime. It resolves fine in the workspace apps via hoisting, but this app
// is installed standalone, so `mocha` must be an explicit dependency here or
// the "Run test app" step fails with "Cannot find module 'mocha'".
"mocha",
"mocha-remote-cli",
"mocha-remote-react-native",
]);
Expand Down Expand Up @@ -169,7 +174,25 @@ async function patchPodfile() {
],
[
"react_native_post_install(installer)",
"react_native_post_install(installer, '../node_modules/react-native-macos')",
`react_native_post_install(installer, '../node_modules/react-native-macos')

# Xcode 26.4 ships Apple clang 21, which enforces C++20 'consteval' more
# strictly and rejects fmt 11.0.2's FMT_STRING() usages with "call to
# consteval function ... is not a constant expression" (in fmt itself, Yoga
# and React-logger). React Native 0.81 bundles fmt 11.0.2 and the upstream
# fix (fmt 12.1.0) only reached React Native >= 0.83.9, so force fmt's
# compile-time (consteval) format-string checking off β€” it falls back to
# runtime validation, which compiles cleanly. Patch the vendored fmt headers
# directly (setting FMT_USE_CONSTEVAL to 0) rather than via a build-settings
# define, because the define does not reliably reach every fmt-consuming
# translation unit.
fmt_root = File.join(installer.sandbox.root.to_s, 'fmt')
Dir.glob(File.join(fmt_root, '**', '*.h')).each do |header|
contents = File.read(header)
next unless contents.include?('FMT_USE_CONSTEVAL')
patched = contents.gsub(/#\\s*define\\s+FMT_USE_CONSTEVAL\\s+1\\b/, '#define FMT_USE_CONSTEVAL 0')
File.write(header, patched) if patched != contents
end`,
],
];

Expand Down
Loading