React Native Code-Splitting With Repack
Tags: reactnative, webpack, codesplitting, react
Published: 2021-08-07 12:10:06

When you are developing a React Native application you will most likely be writing a lot of JavaScript code that contains dependencies that usually come from external repositories like NPM. The compilation of these many JavaScript files and dependencies will be processed into a single _bundle_ file that can be read by React Native. In React Native this compilation will be done by default by **[Metro Bundler](https://facebook.github.io/metro/)**.

So basically _Metro Bundler_ works by taking your source code, all external library dependencies as well as static assets that you use and converting them, optimizing them, and packaging them into a single _bundle_ that can be run by `React Native`.

### What is Code-Splitting?

Code-Splitting is a technique that allows developers to create **multiple bundle files** from existing code sources, so the resulting bundle is not just one but consists of many files which are commonly referred to as _chunck_.

By default, all your input files (source code, dependencies, and assets) are combined into one file. With Code-Splitting, the bundle will be divided into several parts called _chunck_. The main _chunck_ (also known as the `entry chunk`) is commonly referred to as the _main bundle_.

#### Why Do You Need Re.pack To Code-Splitting?

As explained above, by default React Native will use `Metro Bundler` to do JavaScript bundling. But unfortunately _Metro Bundler_ cannot perform _Code-Splitting_ technique by default. To be able to perform the _Code-Splitting_ technique, we need a JavaScript bundler other than Metro Bundler.

#### What is Re.pack?

[Re.pack](https://github.com/callstack/repack) is basically a toolkit that allows you to use Webpack and its _Code-Splitting_ functionality and use them on React Native.

### Why Do We Need Code-Splitting in React Native?

Single bundles aren't a bad thing, but as your app grows your bundle size will grow as well. Especially if you use a lot of third-party libraries you need to be very careful about the code that will be included in the application bundle so that you don't accidentally make your bundle so large that it takes a long time for React Native to load your application.

#### Increasing App Startup Time

If you have performance issues in the application startup area _Code-Splitting_ is a technique worth trying when you have those problems.

Moving code from a single bundle to multiple chunks of _chunck_ if properly configured can make your React Native app to only load the required code snippets and delay loading of other code on startup. This really helps improve the startup performance of your application.

#### Modular Applications

Apps that expose different functionality or different UI based on user details are examples of apps that would benefit greatly from Code-Splitting.

Let's take an example of an e-learning application like _Ruangguru_. With Code-Splitting, you will be able to separate student and teacher functionality in separate bundle files, so that the application only loads one of the bundles, this can improve startup performance by loading only code that is relevant to the user's needs.

Two other groups of apps where Code-Splitting plays a big role are super apps (like Gojek) as well as apps with mini app stores (like WeChat/Line). Instead of having multiple apps on the App Store and Google Play, you can combine them into one while streamlining development and simplifying management.

### How to Use Re.pack for Code-Splitting in React Native

How to use Re.pack? The first step to using Re.pack is to install the required dependencies:

```bash
npm i -D webpack terser-webpack-plugin babel-loader @callstack/repack
# or
yarn add -D webpack terser-webpack-plugin babel-loader @callstack/repack
```

After that, Create react-native.config.js (if this file is not in your project) and copy the content below:

```js
module.exports = {
  commands: require('@callstack/repack/commands'),
};
```

Then configure XCode and Gradle to use the webpack-bundle command. By making this change you will replace the default `Metro Bundler` to `Re.pack`

- XCode: Add `export BUNDLE_COMMAND=webpack-bundle` to the **_Bundle React Native code and images_** phase of **_Build Phases_** in your XCode project configuration.
  ```bash
  export NODE_BINARY=node
  export BUNDLE_COMMAND=webpack-bundle
  ../node_modules/react-native/scripts/react-native-xcode.sh
  ```
- Gradle: Add `bundleCommand: "webpack-bundle"` into `project.ext.react` in `android/app/build.gradle` file, so it looks similar to:

  ```groovy
  project.ext.react = [
      enableHermes: false,  // clean and rebuild if changing
      bundleCommand: "webpack-bundle",
      bundleInDebug: false
  ]
  ```

All configurations have been completed. Now you can use repack in your React Native application.

To run the development server you can use the command

```bash
npx react-native webpack-start
```

### What are the disadvantages of Repack compared to Facebook Metro Bundler ?

Of course there are some drawbacks when we use _Code-Splitting_ with _Re.pack_ instead of _Metro Bundler_. One of the biggest drawbacks is that we **can't use _Codepush_** anymore to do _Hot Push_ code in _Production Env_.

Besides that at the time this article was written if you use _Hermes_ with _Re.pack_ then it can only convert _Main Bundle_ to _Hermes Bytecode_, chunck files outside of _Main Bundle_ will not be transformed into _Hermes Bytecode_.