3

I'm setting up a Bazel build for a React-Native Android project. Since I won't be using Android Studio and Gradle I need to call the react-native cli to create the RN bundle. I've tried several combinations of genrule and nodejs_binary rules as well as calls to react-native, npx react-native, and react-native\cli.js. These attempts have ended in one of two errors:

1)

error Unrecognized command "bundle".
debug We couldn't find a package.json in your project. Are you sure you are running it inside a React Native project?

2)

Error: EPERM: operation not permitted, chmod '/private/var/tmp/_bazel_joshnunez/bfd4b860cd0c2d2f0e40baa90bf393fd/sandbox/darwin-sandbox/471/execroot/native_modules/bazel-out/host/bin/external/androi
d_sample/src/rncli.sh.runfiles/npm/node_modules/@react-native-community/cli/build/commands/server/external/xsel'

Here are the bazel rules I'm using (many permutations commented out with #):

nodejs_binary(
    name = "rncli",
    entry_point = "@npm//:node_modules/react-native/local-cli/cli.js",
    node_modules = "@npm//:node_modules"
)

genrule (
  name = "rnAndroidBundle",
  outs = [ "main/assets/index.android.bundle" ],
  cmd = "$(location :rncli) bundle --verbose --entry-file $(location :appEntry) --platform android --bundle-output $@",
  #cmd = "npm run react-native bundle --verbose --entry-file $(location :appEntry) --platform android --bundle-output $@",
  #cmd = "npx react-native bundle --verbose --entry-file $(location :appEntry) --platform android --bundle-output $@",
  #cmd = "$(location @npm//:node_modules/react-native/cli.js) bundle --verbose --entry-file $(location :appEntry) --platform android --bundle-output $@",
  #cmd = "node node_modules/react-native/local-cli/cli.js bundle --verbose --entry-file $(location :appEntry) --platform android --bundle-output $@",
  #cmd = "node $(location @npm//react-native:node_modules/react-native/cli.js) bundle --verbose --entry-file external/android_sample/src/app.tsx --platform android --bundle-output $@",
  #srcs = [ "@npm//react-native" ],
  srcs = [ "appEntry" ],
  #tools = [ "@npm//:node_modules/react-native/cli.js" ]
  tools = [ ":rncli" ]
)

filegroup (
  name = "appEntry",
  srcs = [ "app.tsx" ]
)
Josh Nunez
  • 31
  • 4

1 Answers1

0

did you ever get a working implementation of this? With the new node_rules I'm using a npm_package_bin example that's pretty similar to what you have here. I can get the bundle command to run, but I'm having other issues after this point so can't say for certainty if it will fix your issue.

You could try something along the lines of this implementation:

package(default_visibility = ["//visibility:public"])

load("@build_bazel_rules_nodejs//:index.bzl", "nodejs_binary","npm_package_bin", "copy_to_bin")
load("@bazel_skylib//rules:write_file.bzl", "write_file")
# note that @npm has been provided in the workspace by a yarn-install command

nodejs_binary(
    name = "android_build_bin",
    entry_point = "@npm//:node_modules/react-native/local-cli/cli.js",
    templated_args = ["bundle --platform android" +
        "--config ../../../../cli.config.js"],
    data = [
        "@npm//:node_modules",
        ":cli.config.js",
    ],
)

nodejs_binary(
    name = "ios_build_bin",
    entry_point = "@npm//:node_modules/react-native/local-cli/cli.js",
    templated_args = ["bundle --platform ios" +
        "--config ../../../../cli.config.js"],
    data = [
        "@npm//:node_modules",
        ":cli.config.js",
    ],
)

# bring across source files into the bin folder (note your paths would differ)
copy_to_bin(
    name = "sources",
    srcs = glob(
        include = [
            "src/**",
            "*",
        ],
        exclude = [],
        exclude_directories = 1,
    )
)

write_file(
    name = "write_chdir_script",
    out = "chdir.js",
    content = ["process.chdir(__dirname)"],
)

npm_package_bin(
    name = "android_build",
    outs = [
        "build/android/index.android.bundle",
        "build/android/index.android.bundle.map",
        "build/android/index.android.bundle.meta",
    ],
    args = ["--node_options=--require=./$(execpath chdir.js)"],
    tool = ":android_build_bin",
    data = [":sources", "chdir.js"],
)

npm_package_bin(
    name = "ios_build",
    outs = [
        "build/ios/index.ios.bundle",
        "build/ios/index.ios.bundle.map",
        "build/ios/index.ios.bundle.meta",
    ],
    args = ["--node_options=--require=./$(execpath chdir.js)"],
    tool = ":ios_build_bin",
    data = [":sources", "chdir.js"],
)
Joel Small
  • 187
  • 1
  • 5
  • I never got this to work. Because of issues like this with bazel and RN integration we abandoned this effort in late 2019. – Josh Nunez Jan 19 '21 at 17:51
  • It looks to primarily be an incompatability with symlinks and the bazel rules_nodejs, however I flagged this with the core team here: https://github.com/bazelbuild/rules_nodejs/pull/2411 . It has been marked for investigation – Joel Small Jan 27 '21 at 03:06