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