1af2ec015STomasz Sapeta#!/bin/bash 2af2ec015STomasz Sapeta# Copyright (c) Meta Platforms, Inc. and affiliates. 3af2ec015STomasz Sapeta# 4af2ec015STomasz Sapeta# This source code is licensed under the MIT license found in the 5af2ec015STomasz Sapeta# LICENSE file in the root directory of this source tree. 6af2ec015STomasz Sapeta 7af2ec015STomasz Sapeta# Bundle React Native app's code and image assets. 8af2ec015STomasz Sapeta# This script is supposed to be invoked as part of Xcode build process 9af2ec015STomasz Sapeta# and relies on environment variables (including PWD) set by Xcode 10af2ec015STomasz Sapeta 11af2ec015STomasz Sapeta# Print commands before executing them (useful for troubleshooting) 12af2ec015STomasz Sapetaset -x 13af2ec015STomasz SapetaDEST=$CONFIGURATION_BUILD_DIR/$UNLOCALIZED_RESOURCES_FOLDER_PATH 14af2ec015STomasz Sapeta 15af2ec015STomasz Sapeta# Enables iOS devices to get the IP address of the machine running Metro 16af2ec015STomasz Sapetaif [[ ! "$SKIP_BUNDLING_METRO_IP" && "$CONFIGURATION" = *Debug* && ! "$PLATFORM_NAME" == *simulator ]]; then 17af2ec015STomasz Sapeta for num in 0 1 2 3 4 5 6 7 8; do 18af2ec015STomasz Sapeta IP=$(ipconfig getifaddr en${num}) 19af2ec015STomasz Sapeta if [ ! -z "$IP" ]; then 20af2ec015STomasz Sapeta break 21af2ec015STomasz Sapeta fi 22af2ec015STomasz Sapeta done 23af2ec015STomasz Sapeta if [ -z "$IP" ]; then 24af2ec015STomasz Sapeta IP=$(ifconfig | grep 'inet ' | grep -v ' 127.' | grep -v ' 169.254.' |cut -d\ -f2 | awk 'NR==1{print $1}') 25af2ec015STomasz Sapeta fi 26af2ec015STomasz Sapeta 27af2ec015STomasz Sapeta echo "$IP" > "$DEST/ip.txt" 28af2ec015STomasz Sapetafi 29af2ec015STomasz Sapeta 30af2ec015STomasz Sapetaif [[ "$SKIP_BUNDLING" ]]; then 31af2ec015STomasz Sapeta echo "SKIP_BUNDLING enabled; skipping." 32af2ec015STomasz Sapeta exit 0; 33af2ec015STomasz Sapetafi 34af2ec015STomasz Sapeta 35af2ec015STomasz Sapetacase "$CONFIGURATION" in 36af2ec015STomasz Sapeta *Debug*) 37af2ec015STomasz Sapeta if [[ "$PLATFORM_NAME" == *simulator ]]; then 38af2ec015STomasz Sapeta if [[ "$FORCE_BUNDLING" ]]; then 39af2ec015STomasz Sapeta echo "FORCE_BUNDLING enabled; continuing to bundle." 40af2ec015STomasz Sapeta else 41af2ec015STomasz Sapeta echo "Skipping bundling in Debug for the Simulator (since the packager bundles for you). Use the FORCE_BUNDLING flag to change this behavior." 42af2ec015STomasz Sapeta exit 0; 43af2ec015STomasz Sapeta fi 44af2ec015STomasz Sapeta else 45af2ec015STomasz Sapeta echo "Bundling for physical device. Use the SKIP_BUNDLING flag to change this behavior." 46af2ec015STomasz Sapeta fi 47af2ec015STomasz Sapeta 48af2ec015STomasz Sapeta DEV=true 49af2ec015STomasz Sapeta ;; 50af2ec015STomasz Sapeta "") 51af2ec015STomasz Sapeta echo "$0 must be invoked by Xcode" 52af2ec015STomasz Sapeta exit 1 53af2ec015STomasz Sapeta ;; 54af2ec015STomasz Sapeta *) 55af2ec015STomasz Sapeta DEV=false 56af2ec015STomasz Sapeta ;; 57af2ec015STomasz Sapetaesac 58af2ec015STomasz Sapeta 59af2ec015STomasz Sapeta# Path to react-native folder inside node_modules 60af2ec015STomasz SapetaREACT_NATIVE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" 61af2ec015STomasz Sapeta# Most projects have their project root, one level up from their Xcode project dir (the "ios" directory) 62af2ec015STomasz SapetaPROJECT_ROOT=${PROJECT_ROOT:-"$PROJECT_DIR/.."} 63af2ec015STomasz Sapeta 64af2ec015STomasz Sapetacd "$PROJECT_ROOT" || exit 65af2ec015STomasz Sapeta 66af2ec015STomasz Sapeta# Define entry file 67af2ec015STomasz Sapetaif [[ "$ENTRY_FILE" ]]; then 68af2ec015STomasz Sapeta # Use ENTRY_FILE defined by user 69af2ec015STomasz Sapeta : 70af2ec015STomasz Sapetaelif [[ -s "index.ios.js" ]]; then 71af2ec015STomasz Sapeta ENTRY_FILE=${1:-index.ios.js} 72af2ec015STomasz Sapetaelse 73af2ec015STomasz Sapeta ENTRY_FILE=${1:-index.js} 74af2ec015STomasz Sapetafi 75af2ec015STomasz Sapeta 76af2ec015STomasz Sapeta# check and assign NODE_BINARY env 77af2ec015STomasz Sapeta# shellcheck source=/dev/null 78af2ec015STomasz Sapetasource "$REACT_NATIVE_DIR/scripts/node-binary.sh" 79af2ec015STomasz Sapeta 80af2ec015STomasz Sapeta# If hermes-engine is in the Podfile.lock, it means that Hermes is a dependency of the project 81af2ec015STomasz Sapeta# and it is enabled. If not, it means that hermes is disabled. 82af2ec015STomasz SapetaHERMES_ENABLED=$(grep hermes-engine $PODS_PODFILE_DIR_PATH/Podfile.lock) 83af2ec015STomasz Sapeta 84af2ec015STomasz Sapeta# If hermes-engine is not in the Podfile.lock, it means that the app is not using Hermes. 85af2ec015STomasz Sapeta# Setting USE_HERMES is no the only way to set whether the app can use hermes or not: users 86af2ec015STomasz Sapeta# can also modify manually the Podfile. 87af2ec015STomasz Sapetaif [[ -z "$HERMES_ENABLED" ]]; then 88af2ec015STomasz Sapeta USE_HERMES=false 89af2ec015STomasz Sapetafi 90af2ec015STomasz Sapeta 91af2ec015STomasz SapetaHERMES_ENGINE_PATH="$PODS_ROOT/hermes-engine" 92af2ec015STomasz Sapeta[ -z "$HERMES_CLI_PATH" ] && HERMES_CLI_PATH="$HERMES_ENGINE_PATH/destroot/bin/hermesc" 93af2ec015STomasz Sapeta 94af2ec015STomasz Sapeta# Hermes is enabled in new projects by default, so we cannot assume that USE_HERMES=1 is set as an envvar. 95af2ec015STomasz Sapeta# If hermes-engine is found in Pods, we can assume Hermes has not been disabled. 96af2ec015STomasz Sapeta# If hermesc is not available and USE_HERMES is either unset or true, show error. 97af2ec015STomasz Sapetaif [[ ! -z "$HERMES_ENABLED" && -f "$HERMES_ENGINE_PATH" && ! -f "$HERMES_CLI_PATH" ]]; then 98af2ec015STomasz Sapeta echo "error: Hermes is enabled but the hermesc binary could not be found at ${HERMES_CLI_PATH}." \ 99af2ec015STomasz Sapeta "Perhaps you need to run 'bundle exec pod install' or otherwise " \ 100af2ec015STomasz Sapeta "point the HERMES_CLI_PATH variable to your custom location." >&2 101af2ec015STomasz Sapeta exit 2 102af2ec015STomasz Sapetafi 103af2ec015STomasz Sapeta 104af2ec015STomasz Sapeta[ -z "$NODE_ARGS" ] && export NODE_ARGS="" 105af2ec015STomasz Sapeta 106af2ec015STomasz Sapeta[ -z "$CLI_PATH" ] && export CLI_PATH="$REACT_NATIVE_DIR/cli.js" 107af2ec015STomasz Sapeta 108af2ec015STomasz Sapeta[ -z "$BUNDLE_COMMAND" ] && BUNDLE_COMMAND="bundle" 109af2ec015STomasz Sapeta 110af2ec015STomasz Sapeta[ -z "$COMPOSE_SOURCEMAP_PATH" ] && COMPOSE_SOURCEMAP_PATH="$REACT_NATIVE_DIR/scripts/compose-source-maps.js" 111af2ec015STomasz Sapeta 112af2ec015STomasz Sapetaif [[ -z "$BUNDLE_CONFIG" ]]; then 113af2ec015STomasz Sapeta CONFIG_ARG="" 114af2ec015STomasz Sapetaelse 115af2ec015STomasz Sapeta CONFIG_ARG="--config $BUNDLE_CONFIG" 116af2ec015STomasz Sapetafi 117af2ec015STomasz Sapeta 118af2ec015STomasz SapetaBUNDLE_FILE="$CONFIGURATION_BUILD_DIR/main.jsbundle" 119af2ec015STomasz Sapeta 120af2ec015STomasz SapetaEXTRA_ARGS= 121af2ec015STomasz Sapeta 122af2ec015STomasz Sapetacase "$PLATFORM_NAME" in 123af2ec015STomasz Sapeta "macosx") 124af2ec015STomasz Sapeta BUNDLE_PLATFORM="macos" 125af2ec015STomasz Sapeta ;; 126af2ec015STomasz Sapeta *) 127af2ec015STomasz Sapeta BUNDLE_PLATFORM="ios" 128af2ec015STomasz Sapeta ;; 129af2ec015STomasz Sapetaesac 130af2ec015STomasz Sapeta 131af2ec015STomasz Sapetaif [ "${IS_MACCATALYST}" = "YES" ]; then 132af2ec015STomasz Sapeta BUNDLE_PLATFORM="ios" 133af2ec015STomasz Sapetafi 134af2ec015STomasz Sapeta 135af2ec015STomasz SapetaEMIT_SOURCEMAP= 136af2ec015STomasz Sapetaif [[ ! -z "$SOURCEMAP_FILE" ]]; then 137af2ec015STomasz Sapeta EMIT_SOURCEMAP=true 138af2ec015STomasz Sapetafi 139af2ec015STomasz Sapeta 140af2ec015STomasz SapetaPACKAGER_SOURCEMAP_FILE= 141af2ec015STomasz Sapetaif [[ $EMIT_SOURCEMAP == true ]]; then 142af2ec015STomasz Sapeta if [[ $USE_HERMES != false ]]; then 143af2ec015STomasz Sapeta PACKAGER_SOURCEMAP_FILE="$CONFIGURATION_BUILD_DIR/$(basename $SOURCEMAP_FILE)" 144af2ec015STomasz Sapeta else 145af2ec015STomasz Sapeta PACKAGER_SOURCEMAP_FILE="$SOURCEMAP_FILE" 146af2ec015STomasz Sapeta fi 147af2ec015STomasz Sapeta EXTRA_ARGS="$EXTRA_ARGS --sourcemap-output $PACKAGER_SOURCEMAP_FILE" 148af2ec015STomasz Sapetafi 149af2ec015STomasz Sapeta 150af2ec015STomasz Sapeta# Hermes doesn't require JS minification. 151af2ec015STomasz Sapetaif [[ $USE_HERMES != false && $DEV == false ]]; then 152af2ec015STomasz Sapeta EXTRA_ARGS="$EXTRA_ARGS --minify false" 153af2ec015STomasz Sapetafi 154af2ec015STomasz Sapeta 155af2ec015STomasz Sapeta"$NODE_BINARY" $NODE_ARGS "$CLI_PATH" $BUNDLE_COMMAND \ 156af2ec015STomasz Sapeta $CONFIG_ARG \ 157af2ec015STomasz Sapeta --entry-file "$ENTRY_FILE" \ 158af2ec015STomasz Sapeta --platform "$BUNDLE_PLATFORM" \ 159af2ec015STomasz Sapeta --dev $DEV \ 160af2ec015STomasz Sapeta --reset-cache \ 161af2ec015STomasz Sapeta --bundle-output "$BUNDLE_FILE" \ 162af2ec015STomasz Sapeta --assets-dest "$DEST" \ 163af2ec015STomasz Sapeta $EXTRA_ARGS \ 164af2ec015STomasz Sapeta $EXTRA_PACKAGER_ARGS 165af2ec015STomasz Sapeta 166af2ec015STomasz Sapetaif [[ $USE_HERMES == false ]]; then 167af2ec015STomasz Sapeta cp "$BUNDLE_FILE" "$DEST/" 168af2ec015STomasz Sapeta BUNDLE_FILE="$DEST/main.jsbundle" 169af2ec015STomasz Sapetaelse 170af2ec015STomasz Sapeta EXTRA_COMPILER_ARGS= 171af2ec015STomasz Sapeta if [[ $DEV == true ]]; then 172af2ec015STomasz Sapeta EXTRA_COMPILER_ARGS=-Og 173af2ec015STomasz Sapeta else 174af2ec015STomasz Sapeta EXTRA_COMPILER_ARGS=-O 175af2ec015STomasz Sapeta fi 176af2ec015STomasz Sapeta if [[ $EMIT_SOURCEMAP == true ]]; then 177af2ec015STomasz Sapeta EXTRA_COMPILER_ARGS="$EXTRA_COMPILER_ARGS -output-source-map" 178af2ec015STomasz Sapeta fi 179*bdf1985aSTomasz Sapeta "$HERMES_CLI_PATH" -emit-binary -max-diagnostic-width=80 $EXTRA_COMPILER_ARGS -out "$DEST/main.jsbundle" "$BUNDLE_FILE" 180af2ec015STomasz Sapeta if [[ $EMIT_SOURCEMAP == true ]]; then 181af2ec015STomasz Sapeta HBC_SOURCEMAP_FILE="$DEST/main.jsbundle.map" 182af2ec015STomasz Sapeta "$NODE_BINARY" "$COMPOSE_SOURCEMAP_PATH" "$PACKAGER_SOURCEMAP_FILE" "$HBC_SOURCEMAP_FILE" -o "$SOURCEMAP_FILE" 183af2ec015STomasz Sapeta rm "$HBC_SOURCEMAP_FILE" 184af2ec015STomasz Sapeta rm "$PACKAGER_SOURCEMAP_FILE" 185af2ec015STomasz Sapeta fi 186af2ec015STomasz Sapeta BUNDLE_FILE="$DEST/main.jsbundle" 187af2ec015STomasz Sapetafi 188af2ec015STomasz Sapeta 189af2ec015STomasz Sapetaif [[ $DEV != true && ! -f "$BUNDLE_FILE" ]]; then 190af2ec015STomasz Sapeta echo "error: File $BUNDLE_FILE does not exist. This must be a bug with React Native, please report it here: https://github.com/facebook/react-native/issues" >&2 191af2ec015STomasz Sapeta exit 2 192af2ec015STomasz Sapetafi 193