microsoft/rnx-kit

Missing documentation on how to use a pre-built bundle

renchap opened this issue · 8 comments

What happened?

I am trying to port my existing app to rnx-kit, and as recommended in the documentation I would like to first generate my bundle using rnx-bundle, and then have this pre-built bundle used by the native app build system.

There is nothing in the documentation on how to achieve this.

For iOS, this would be removing the "Bundle React Native code and images" build step in XCode.

For Android, I do not know if there is a way to configure react-native-gradle-plugin to not generate the bundle, but use an existing one.

Affected Package

@rnxkit-cli

Version

0.16.9

Which platforms are you seeing this issue on?

  • Android
  • iOS
  • macOS
  • Windows

System Information

info Fetching system and libraries information...
System:
    OS: macOS 13.3.1
    CPU: (10) arm64 Apple M1 Max
    Memory: 67.69 MB / 32.00 GB
    Shell: 5.9 - /bin/zsh
  Binaries:
    Node: 16.15.1 - ~/.nvm/versions/node/v16.15.1/bin/node
    Yarn: Not Found
    npm: 9.5.0 - ~/.nvm/versions/node/v16.15.1/bin/npm
    Watchman: 2023.05.01.00 - /opt/homebrew/bin/watchman
  Managers:
    CocoaPods: 1.12.1 - /var/folders/cn/qgvjcjx97mj8rc2vx37vgkvh0000gn/T/frum_69495_1683799833063/bin/pod
  SDKs:
    iOS SDK:
      Platforms: DriverKit 22.4, iOS 16.4, macOS 13.3, tvOS 16.4, watchOS 9.4
    Android SDK:
      API Levels: 26, 31, 32, 33
      Build Tools: 30.0.2, 30.0.3, 31.0.0, 32.0.0, 32.1.0, 33.0.0, 33.0.2
      System Images: android-24 | Google APIs ARM 64 v8a, android-25 | Google APIs ARM 64 v8a, android-26 | ARM 64 v8a, android-26 | Google APIs ARM 64 v8a, android-28 | Google ARM64-V8a Play ARM 64 v8a, android-32 | Google APIs ARM 64 v8a
      Android NDK: Not Found
  IDEs:
    Android Studio: 2022.1 AI-221.6008.13.2211.9477386
    Xcode: 14.3/14E222b - /usr/bin/xcodebuild
  Languages:
    Java: 20.0.1 - /usr/bin/javac
  npmPackages:
    @react-native-community/cli: Not Found
    react: ^18.2.0 => 18.2.0
    react-native: ^0.71.8 => 0.71.8
    react-native-macos: Not Found
  npmGlobalPackages:
    *react-native*: Not Found

Code of Conduct

  • I agree to follow this project's Code of Conduct

I continued digging into the way the iOS build works, and removing the "Bundle React Native code and images" step is probably not enough.

You need to have your generated bundle copied to the correct location (or maybe just added to the release in XCode?), and you also need to run hermesc on the bundle if configured, and merge the sourcemaps (this is done by the react-native-xcode.sh script).

This makes it much harder to have your bundle generated before the native build, as those steps will probably evolve and need to be adjusted when upstream makes changes.

An alternative can be to set $BUNDLE_COMMAND to rnx-bundle, but then your bundle is still generated by XCode during the iOS build process.

You need to have your generated bundle copied to the correct location (or maybe just added to the release in XCode?), and you also need to run hermesc on the bundle if configured, and merge the sourcemaps (this is done by the react-native-xcode.sh script).

You can add the bundle to the Xcode project yourself. Xcode just needs a path to the bundle. If you output to the same location as the script previously did, then you don't need to adjust anything in Xcode. If you use Hermes, you can run hermesc as a post-process on the bundle, then add this file instead. The sourcemaps should already be merged by this process, so there's not much else you need to do. This is what we've been doing for years internally. We've not had any issues with it afaict.

For Android, I do not know if there is a way to configure react-native-gradle-plugin to not generate the bundle, but use an existing one.

There is an "official" way, but not a particularly safe one. It is being used here: https://github.com/microsoft/react-native-test-app/blob/113e97d8f62e5d7e1e5c602422d83f912ca5c385/android/app/build.gradle#L25-L32

I suppose an alternative would be to set bundleCommand and hermesCommand in app/build.gradle to do nothing, but that sounds like more setup to me.

I'm just trying to do this but the docs are still VERY vague about what you need to do here... It only mentions that we need to disable the auto-generation of bundles but does not mention what we need to do instead. I figured out what we need to do on Android but still figuring out iOS.

I created these small scripts for Android in packages.json:

"bundle:android": "yarn react-native rnx-bundle --platform android && yarn bundle:android:copy",
"bundle:android:copy": "mkdir -p android/app/build/generated/res/createBundleReleaseJsAndAssets && cp -r dist android/app/build/generated/res/createBundleReleaseJsAndAssets",

and this is the relevant part from packages.json regarding rnx-kit config:

"rnx-kit": {
    "bundle": {
      "hermes": true,
      "entryFile": "index.js",
      "targets": [
        "android",
        "ios"
      ],
      "platforms": {
        "android": {
          "bundleOutput": "dist/main.android.bundle",
          "sourcemapOutput": "dist/main.android.bundle.map",
          "assetsDest": "dist/res"
        },
        "ios": {
          "bundleOutput": "dist/main.ios.jsbundle",
          "sourcemapOutput": "dist/main.ios.jsbundle.map",
          "assetsDest": "dist"
        }
      },

if anyone can share how they solved this for iOS that would be appreciated!

tido64 commented

For iOS, you should be able to add the file(s) directly to your Xcode project:

image

Or under Build Phases > Copy Bundle Resources

image

You're right that the docs are very vague. We will update them.

@tido64 and what file should I include if I use hermes? the main.jsbundle or the main.jsbundle.hbc?

tido64 commented

Adding resources to project just tells Xcode to copy them into the final app bundle. Add whatever you use, be it .jsbundle, .hbc or other assets.

Hi everyone, any follow up on how to proceed for the actual final native build of the app (Android/iOS) ? The docs are still as is and as a first time user of this cool tool, I had to keep the classic build as is due to concerns that something might break.

I think it's worth it to update the documentation for the full process, so that new adopters wont be put off.

Thanks.