directly call community-cli-plugin in react-native-xcode.sh (#44721)

Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/44721

For iOS builds of `react-native`, the [react-native-xcode.sh](https://www.internalfb.com/code/fbsource/[7ad79aae3e8bf565d53f087ac7f7b7622b19acec]/xplat/js/react-native-github/packages/react-native/scripts/react-native-xcode.sh) script is executed as one of the build phases.  This phase bundles the JS application (dev or production).

I've updated this to use the new `bundle.js` script instead of calling the `react-native/cli.js`.  This is identical except with how the config is captured:

{F1669960016}

This is similar to our approach with the Gradle plugin, giving Framework authors more control.

**Other:** formatting changes for the Privacy Manifest that Xcode keeps updating.

Changelog: [Internal]

Reviewed By: cipolleschi

Differential Revision: D57915368

fbshipit-source-id: f52ea4b3cb94212ac97a3d7edeb68747418fe0a9
This commit is contained in:
Blake Friedman 2024-06-05 09:08:16 -07:00 committed by Facebook GitHub Bot
parent 7ae0e46530
commit eba1828a83
8 changed files with 151 additions and 67 deletions

View File

@ -2,6 +2,8 @@
**/staticBundle.js
docs/generatedComponentApiDocs.js
packages/react-native/flow/
packages/react-native/sdks/
packages/react-native/ReactAndroid/hermes-engine/build/
packages/react-native/Libraries/Renderer/*
packages/react-native/Libraries/vendor/**/*
node_modules/

View File

@ -0,0 +1,22 @@
{
"platforms": {
"ios": {},
"android": {}
},
"project": {
"ios": {
"sourceDir": "HELLOWORLD_PATH/ios",
"xcodeProject": {
"name": "HelloWorld.xcworkspace",
"isWorkspace": true
}
},
"android": {
"sourceDir": "HELLOWORLD_PATH/android",
"appName": "app",
"packageName": "com.helloworld",
"applicationId": "com.helloworld",
"mainActivity": ".MainActivity"
}
}
}

View File

@ -12,6 +12,7 @@
13B07FBC1A68108700A75B9A /* AppDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.mm */; };
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; };
13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; };
6EA01F72FAC10D00AECACF94 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 0EC7AB76F90EED035707BA4E /* PrivacyInfo.xcprivacy */; };
7699B88040F8A987B510C191 /* libPods-HelloWorld-HelloWorldTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 19F6CBCC0A4E27FBF8BF4A61 /* libPods-HelloWorld-HelloWorldTests.a */; };
81AB9BB82411601600AC10FF /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */; };
/* End PBXBuildFile section */
@ -30,6 +31,7 @@
00E356EE1AD99517003FC87E /* HelloWorldTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = HelloWorldTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
00E356F11AD99517003FC87E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
00E356F21AD99517003FC87E /* HelloWorldTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = HelloWorldTests.m; sourceTree = "<group>"; };
0EC7AB76F90EED035707BA4E /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xml; name = PrivacyInfo.xcprivacy; path = HelloWorld/PrivacyInfo.xcprivacy; sourceTree = "<group>"; };
13B07F961A680F5B00A75B9A /* HelloWorld.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = HelloWorld.app; sourceTree = BUILT_PRODUCTS_DIR; };
13B07FAF1A68108700A75B9A /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = HelloWorld/AppDelegate.h; sourceTree = "<group>"; };
13B07FB01A68108700A75B9A /* AppDelegate.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = AppDelegate.mm; path = HelloWorld/AppDelegate.mm; sourceTree = "<group>"; };
@ -94,6 +96,7 @@
81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */,
13B07FB71A68108700A75B9A /* main.m */,
13B07FB81A68108700A75B9A /* PrivacyInfo.xcprivacy */,
0EC7AB76F90EED035707BA4E /* PrivacyInfo.xcprivacy */,
);
name = HelloWorld;
sourceTree = "<group>";
@ -183,7 +186,6 @@
13B07F8C1A680F5B00A75B9A /* Frameworks */,
13B07F8E1A680F5B00A75B9A /* Resources */,
00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */,
00EEFC60759A1932668264C0 /* [CP] Embed Pods Frameworks */,
E235C05ADACE081382539298 /* [CP] Copy Pods Resources */,
);
buildRules = (
@ -245,6 +247,7 @@
files = (
81AB9BB82411601600AC10FF /* LaunchScreen.storyboard in Resources */,
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */,
6EA01F72FAC10D00AECACF94 /* PrivacyInfo.xcprivacy in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -259,13 +262,14 @@
inputPaths = (
"$(SRCROOT)/.xcode.env.local",
"$(SRCROOT)/.xcode.env",
"$(SRCROOT)/../.react-native.config",
);
name = "Bundle React Native code and images";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "set -e\n\nWITH_ENVIRONMENT=\"$REACT_NATIVE_PATH/scripts/xcode/with-environment.sh\"\nREACT_NATIVE_XCODE=\"$REACT_NATIVE_PATH/scripts/react-native-xcode.sh\"\n\n/bin/sh -c \"$WITH_ENVIRONMENT $REACT_NATIVE_XCODE\"\n";
shellScript = "set -e\n\nexport CONFIG_JSON=$(sed -e \"s|HELLOWORLD_PATH|$(realpath \"${SRCROOT}/../\")|g\" \"${SRCROOT}/../.react-native.config\")\n\nWITH_ENVIRONMENT=\"$REACT_NATIVE_PATH/scripts/xcode/with-environment.sh\"\nREACT_NATIVE_XCODE=\"$REACT_NATIVE_PATH/scripts/react-native-xcode.sh\"\n\n/bin/sh -c \"$WITH_ENVIRONMENT $REACT_NATIVE_XCODE\"\n";
};
00EEFC60759A1932668264C0 /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
@ -328,23 +332,6 @@
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
C59DA0FBD6956966B86A3779 /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-HelloWorld-HelloWorldTests/Pods-HelloWorld-HelloWorldTests-frameworks-${CONFIGURATION}-input-files.xcfilelist",
);
name = "[CP] Embed Pods Frameworks";
outputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-HelloWorld-HelloWorldTests/Pods-HelloWorld-HelloWorldTests-frameworks-${CONFIGURATION}-output-files.xcfilelist",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-HelloWorld-HelloWorldTests/Pods-HelloWorld-HelloWorldTests-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
E235C05ADACE081382539298 /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
@ -433,6 +420,7 @@
);
PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)";
PRODUCT_NAME = "$(TARGET_NAME)";
REACT_NATIVE_PATH = "${PODS_ROOT}/../../../react-native";
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/HelloWorld.app/HelloWorld";
};
name = Debug;
@ -457,6 +445,7 @@
);
PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)";
PRODUCT_NAME = "$(TARGET_NAME)";
REACT_NATIVE_PATH = "${PODS_ROOT}/../../../react-native";
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/HelloWorld.app/HelloWorld";
};
name = Release;
@ -482,6 +471,7 @@
);
PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)";
PRODUCT_NAME = HelloWorld;
REACT_NATIVE_PATH = "${PODS_ROOT}/../../../react-native";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
VERSIONING_SYSTEM = "apple-generic";
@ -508,6 +498,7 @@
);
PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)";
PRODUCT_NAME = HelloWorld;
REACT_NATIVE_PATH = "${PODS_ROOT}/../../../react-native";
SWIFT_VERSION = 5.0;
VERSIONING_SYSTEM = "apple-generic";
};
@ -582,13 +573,8 @@
"-DFOLLY_CFG_NO_COROUTINES=1",
"-DFOLLY_HAVE_CLOCK_GETTIME=1",
);
OTHER_LDFLAGS = (
"$(inherited)",
" ",
);
REACT_NATIVE_PATH = "${PODS_ROOT}/../../../react-native";
OTHER_LDFLAGS = "$(inherited) ";
SDKROOT = iphoneos;
USE_HERMES = true;
};
name = Debug;
};
@ -653,13 +639,8 @@
"-DFOLLY_CFG_NO_COROUTINES=1",
"-DFOLLY_HAVE_CLOCK_GETTIME=1",
);
OTHER_LDFLAGS = (
"$(inherited)",
" ",
);
REACT_NATIVE_PATH = "${PODS_ROOT}/../../../react-native";
OTHER_LDFLAGS = "$(inherited) ";
SDKROOT = iphoneos;
USE_HERMES = true;
VALIDATE_PRODUCT = YES;
};
name = Release;

View File

@ -2,37 +2,36 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSPrivacyCollectedDataTypes</key>
<array>
</array>
<key>NSPrivacyAccessedAPITypes</key>
<array>
<dict>
<key>NSPrivacyAccessedAPIType</key>
<string>NSPrivacyAccessedAPICategoryFileTimestamp</string>
<key>NSPrivacyAccessedAPITypeReasons</key>
<array>
<string>C617.1</string>
</array>
</dict>
<dict>
<key>NSPrivacyAccessedAPIType</key>
<string>NSPrivacyAccessedAPICategoryUserDefaults</string>
<key>NSPrivacyAccessedAPITypeReasons</key>
<array>
<string>CA92.1</string>
</array>
</dict>
<dict>
<key>NSPrivacyAccessedAPIType</key>
<string>NSPrivacyAccessedAPICategorySystemBootTime</string>
<key>NSPrivacyAccessedAPITypeReasons</key>
<array>
<string>35F9.1</string>
</array>
</dict>
</array>
<key>NSPrivacyTracking</key>
<false/>
<key>NSPrivacyAccessedAPITypes</key>
<array>
<dict>
<key>NSPrivacyAccessedAPIType</key>
<string>NSPrivacyAccessedAPICategoryFileTimestamp</string>
<key>NSPrivacyAccessedAPITypeReasons</key>
<array>
<string>C617.1</string>
</array>
</dict>
<dict>
<key>NSPrivacyAccessedAPIType</key>
<string>NSPrivacyAccessedAPICategoryUserDefaults</string>
<key>NSPrivacyAccessedAPITypeReasons</key>
<array>
<string>CA92.1</string>
</array>
</dict>
<dict>
<key>NSPrivacyAccessedAPIType</key>
<string>NSPrivacyAccessedAPICategorySystemBootTime</string>
<key>NSPrivacyAccessedAPITypeReasons</key>
<array>
<string>35F9.1</string>
</array>
</dict>
</array>
<key>NSPrivacyCollectedDataTypes</key>
<array/>
<key>NSPrivacyTracking</key>
<false/>
</dict>
</plist>

View File

@ -13,7 +13,7 @@ target 'HelloWorld' do
config = use_native_modules!
use_react_native!(
:path => config[:reactNativePath],
:path => "../../react-native",
# An absolute path to your application root.
:app_path => "#{Pod::Config.instance.installation_root}/.."
)

View File

@ -56,6 +56,7 @@
"rn-get-polyfills.js",
"scripts/compose-source-maps.js",
"scripts/find-node-for-xcode.sh",
"scripts/bundle.js",
"scripts/generate-codegen-artifacts.js",
"scripts/generate-provider-cli.js",
"scripts/generate-specs-cli.js",

70
packages/react-native/scripts/bundle.js vendored Normal file
View File

@ -0,0 +1,70 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @format
* @oncall react_native
*/
'use strict';
const {bundleCommand: bc} = require('@react-native/community-cli-plugin');
const {execSync} = require('child_process');
const program = require('commander');
const {existsSync, readFileSync} = require('fs');
const path = require('path');
program.version(
JSON.parse(
readFileSync(path.resolve(__dirname, '..', 'package.json'), 'utf8'),
).version,
);
program
.name(bc.name)
.description(bc.description ?? '')
.option(
'--config-cmd <string>',
'Command to generate a JSON project config',
'npx react-native config',
)
.option('--load-config <string>', 'JSON project config')
.action(async function handleAction(options, ...args) {
let config = null;
if (options.loadConfig != null) {
const rawText = existsSync(options.loadConfig)
? readFileSync(options.loadConfig, 'utf8')
: options.loadConfig;
config = JSON.parse(rawText);
} else if (options.configCmd != null) {
config = JSON.parse(
execSync(options.configCmd.trim(), {encoding: 'utf8'}),
);
}
if (config == null) {
throw new Error('No config provided');
}
await bc.func(args, config, options);
});
if (bc.options != null) {
for (const o of bc.options) {
program.option(
o.name,
o.description ?? '',
o.parse ?? (value => value),
o.default,
);
}
}
if (require.main === module) {
program.parse(process.argv);
}
module.exports = program;

View File

@ -90,8 +90,6 @@ fi
[ -z "$NODE_ARGS" ] && export NODE_ARGS=""
[ -z "$CLI_PATH" ] && export CLI_PATH="$REACT_NATIVE_DIR/cli.js"
[ -z "$BUNDLE_COMMAND" ] && BUNDLE_COMMAND="bundle"
[ -z "$COMPOSE_SOURCEMAP_PATH" ] && COMPOSE_SOURCEMAP_PATH="$REACT_NATIVE_DIR/scripts/compose-source-maps.js"
@ -139,8 +137,19 @@ if [[ $USE_HERMES != false && $DEV == false ]]; then
EXTRA_ARGS+=("--minify" "false")
fi
"$NODE_BINARY" $NODE_ARGS "$CLI_PATH" $BUNDLE_COMMAND \
# Allow opting out of using npx react-native config
if [[ -n "$CONFIG_JSON" ]]; then
EXTRA_ARGS+=("--load-config" "$CONFIG_JSON")
elif [[ -n "$CONFIG_CMD" ]]; then
EXTRA_ARGS+=("--config-cmd" "$CONFIG_APP")
else
EXTRA_ARGS+=("--config-cmd" "$NODE_BINARY $NODE_ARGS $REACT_NATIVE_DIR/cli.js config")
fi
# shellcheck disable=SC2086
"$NODE_BINARY" $NODE_ARGS "$REACT_NATIVE_DIR/scripts/bundle.js" \
$CONFIG_ARG \
--config-cmd "$CONFIG" \
--entry-file "$ENTRY_FILE" \
--platform "$BUNDLE_PLATFORM" \
--dev $DEV \