The specific implementation of Code Splitting in your application can be different and should account for your project's specific needs, requirements and limitations.
In general, we can identify 3 main categories of implementation. All of those approaches are based on the same underlying mechanism: Re.Pack's ScriptManager
and the native module for it.
Because Code Splitting support is based on the native module, you need to be able to compile the native code in your project, meaning you cannot use it with Expo.
It might be possible to use it in an ejected Expo app, but that scenario is not officially supported.
Use Glossary of terms to better understand the content of this documentation.
On a high-level, all functionalities that enable usage of Webpack's Code Splitting, are powered by
Re.Pack's ScriptManager
, which consists of the JavaScript part and the native part.
The ScriptManager
has methods which allows to:
loadScript
prefetchScript
resolveScript
invalidateScripts
In order to provide this functionalities, a resolver has to be added using ScriptManager.shared.addResolver
:
If the storage
is provided, the returned url
from resolve
will be used for cache management.
You can read more about it in Caching and Versioning.
Do not instantiate ScriptManager
yourself - use ScriptManager.shared
to get access to an instance.
Under the hood, the way a script gets loaded can be summarized as follows:
ScriptManager.shared.loadScript(...)
gets called, either:
import(...)
function handled by Webpack, when using Async chunks approachScriptManager.shared.loadScript(...)
is called scriptId
and caller
arguments, which are either provided by:
webpackChunkName
ScriptManager.shared.loadScript(...)
resolves the chunk location using ScriptManager.shared.resolveScript(...)
.storage
was provided and the script was resolved before.Promise
returned by ScriptManager.shared.loadScript(...)
gets resolved.ScriptManager.shared.prefetchScript(...)
follows
the same behavior except for #6, where it only downloads the file and doesn't execute it.
There are generally 3 approaches to Code Splitting with Webpack and Re.Pack. Keep in mind that the actual code you will have to create might be slightly different, depending on your project's requirements, needs and limitations.
Those approaches should be used as a base for your Code Splitting implementation.
It's recommended to read Generic usage first, to understand it on a high-level and get the necessary context.
Async chunks (or asynchronous chunks) are the easiest Code Splitting approach. They are usually
created by using dynamic import(...)
function, which makes them extremely easy to introduce it
into the codebase.
The async chunks are created alongside the main bundle as part of a single Webpack compilation, making it a great choice for a modular applications where all the code is developed in-house.
The usage of async chunks essentially boils down to calling import(...)
in your code, for example:
Async chunks created by dynamic import(...)
function can be nicely integrated using React.lazy
and React.Suspense
:
For each file in the dynamic import(...)
function a new chunk will be created - those chunks will
be remote chunks by default.
You can learn more about local and remote chunks in the dedicated Local vs Remote chunks guide.
To learn more or use async chunks in your project, check out our dedicated Async chunks guide.
To see import(...)
, React.lazy
and React.Suspense
in action, check out
Re.Pack's TesterApp
.
Don't forget to add resolver using ScriptManager.shared.addResolver
!
This approach allows to execute arbitrary code in your React Native application.
It's a similar concept as adding a new <script>
element to a Web page.
Those scripts can be written in-house or externally, bundled using Webpack or a different bundler. This also means that scripts can be created as part of separate Webpack compilations, or separate build pipelines, from separate codebases and repositories.
Scripts should only be used by advanced users with deep Webpack knowledge and experience.
Scripts give a lot of flexibility but it also means the support for them is limited. It's not possible for Re.Pack's contributors to support all potential setups using this approach.
Beware, with dynamic scripts there's no dependency sharing by default. If you want your scripts to reuse existing dependencies from the main bundle, it's up to you to figure out how to do it. A good starting point would be:
Loading a script is as simple as running a single function:
And adding a resolver to the ScriptManager
to resolve your
scripts:
Use Module Federation document for information on adoption of Module Federation in React Native projects with Re.Pack.