Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
168 changes: 97 additions & 71 deletions website/src/5.x/docs/guides/remote-assets.md
Original file line number Diff line number Diff line change
@@ -1,57 +1,59 @@
# Remote assets

RePack provides you with a way to extract and serve your assets externally, such as on a CDN,
Re.Pack provides you with a way to extract and serve your assets externally, such as on a CDN,
instead of bundling them directly into your application. When working with ModuleFederation
this is the recommended approach to handling the assets in federated modules, as inlining
the assets causes your bundle size to increase dramatically.

## Usage

To convert assets to remote assets you have to configure `remote` option to the [Assets loader](../loaders/assets-loader):

```js
/* ... */
:::tip title="Use remote assets only in production"
During development, it's best to disable remote assets and load them locally. When you're ready to move to production, you can use `enabled: true` and then upload the assets to the CDN of your choosing.
:::

export default (env) => {
/* ... */
## Usage

return {
/* ... */

module: {
rules: [
/* ... */

{
test: Repack.getAssetExtensionsRegExp(
Repack.ASSET_EXTENSIONS.filter((ext) => ext !== 'svg')
),
use: {
loader: '@callstack/repack/assets-loader',
options: {
platform,
devServerEnabled: Boolean(devServer),
scalableAssetExtensions: Repack.SCALABLE_ASSETS,
remote: {
enabled: true,
publicPath: 'http://localhost:9999',
},
To convert assets to remote assets you have to configure `remote` option in the [Assets loader](/api/loaders/assets-loader):

```js title="rspack.config.cjs"
const Repack = require("@callstack/repack");

module.exports = {
module: {
rules: [
{
test: Repack.getAssetExtensionsRegExp(),
use: {
loader: "@callstack/repack/assets-loader",
options: {
remote: {
enabled: true,
publicPath: "http://localhost:9999",
},
},
},
],
},

/* ... */
};
},
],
},
};
```

This will cause all assets processed by this Assets Loader to be converted to remote ones.
You can also use the remote assets configuration with [getAssetsTransformRules](/api/utils/get-assets-transform-rules) helper function:

:::info
For development, it's best to set `enabled: false` and load the assets locally. This will allow you to work with the assets more efficiently. However, when you're ready to move to production, you can switch the flag to `enabled: true` and include the converted assets in the production bundle.
:::
```js title="rspack.config.cjs"
const Repack = require("@callstack/repack");

module.exports = {
module: {
rules: [
...Repack.getAssetsTransformRules({
remote: {
enabled: true,
publicPath: "http://localhost:9999",
},
}),
],
},
};
```

Remote assets are imported in the same way as local assets:

Expand All @@ -65,7 +67,7 @@ import image from './image.png';
In both cases shown above, the the value of `source` prop will resolve to an object of shape:

```ts
type source = {
type Source = {
uri: string;
width: number;
height: number;
Expand All @@ -77,29 +79,31 @@ type source = {

The `uri` prop will have a value of an URL that's constructed by joining `publicPath`, 'assets' and local path to the asset together. If `publicPath` is set to https://example.com and the local path to the asset is logo.png, then the resulting `uri` value would be: `https://example.com/assets/images/logo.png`.

:::info
:::info title="Scaled assets are fully supported"

Scaled assets are fully supported. The asset will resolve to proper scale in runtime by constructing a relevant URL with scale suffix at the end of it.
The asset will resolve to proper scale in runtime by constructing a relevant URL with scale suffix at the end of it.

:::

When you create a production bundle, a directory called `remote-assets` will be included in your project's build directory. This directory contains all of the remote assets that are needed for your application.

By default, the remote-assets directory will be located at `build/generated/<platform>/remote-assets`. However, if you want the remote assets to appear in the `OutputPlugin` directory, which is part of the `RepackPlugin`, you will need to configure an additional property called `auxiliaryAssetsPath`:

```ts
new Repack.RepackPlugin({
context,
mode,
platform,
devServer,
output: {
bundleFilename,
sourceMapFilename,
assetsPath,
auxiliaryAssetsPath: path.join('build/output', platform, 'remote'),
},
});
```js title="rspack.config.cjs"
const Repack = require("@callstack/repack");

module.exports = (env) => {
const { platform } = env;

return {
plugins: [
new Repack.RepackPlugin({
output: {
auxiliaryAssetsPath: path.join("build/output", platform, "remote"),
},
}),
],
};
```

The final step is to upload your remote assets to your CDN, which is located at `publicPath`, and then host them from that location, which will make them available to users of your app.
Expand All @@ -109,22 +113,44 @@ The final step is to upload your remote assets to your CDN, which is located at
The `assetPath` option offers finer control over how remote asset paths are constructed. This feature allows you to define a custom function for modifying paths, which can be helpful if you need to apply custom naming conventions or add extra directory layers.
Specified pattern will be applied to both the generated folder path and URL. If `assetPath` is not provided, the [default behaviour](#default-behaviour) will be used.

Example:
```ts
remote: {
enabled: true,
publicPath: 'http://localhost:9999',
assetPath: ({
resourceFilename,
resourceDirname,
resourceExtensionType,
}) => {
const customHash = getCustomHash();
return `my-remote-assets/${resourceFilename}-${customHash}.${resourceExtensionType}`;
},
Consider the following example:

```js title="rspack.config.cjs"
const Repack = require("@callstack/repack");

function getCustomAssetPath({
resourceFilename,
resourceDirname,
resourceExtensionType,
}) {
const customHash = getCustomHash();
return `my-remote-assets/${resourceFilename}-${customHash}.${resourceExtensionType}`;
}

module.exports = {
module: {
rules: [
{
test: Repack.getAssetExtensionsRegExp(),
use: {
loader: "@callstack/repack/assets-loader",
options: {
remote: {
enabled: true,
publicPath: "http://localhost:9999",
assetPath: getCustomAssetPath,
},
},
},
},
],
},
};
```
would result in the following:

- generated asset path: `<buildFolder>/remote-assets/assets/my-remote-assets/logo-customhash.png`
- generated URL: `http://localhost:9999/my-remote-assets/logo-customhash.png`
The configuration above would generate the following paths:

| Property | Value |
| ---------- | ------------------------------------------------------------------------- |
| asset path | `<buildFolder>/remote-assets/assets/my-remote-assets/logo-customhash.png` |
| asset URL | `http://localhost:9999/my-remote-assets/logo-customhash.png` |