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