Skip to main content

How to use with Module Federation

The first thing you will need to do when implementing Portals for Capacitor is choose a web based micro frontend solution. The most common is Module Federation.

Local vs Mobile Configuration

After you have chosen and setup module federation between your apps you will need to configure it for Capacitor. One way to do this is to add an environment variable to your npm build script.

In this case we are setting the variable CAP_BUILD to true. In the example below we are using cross-env to set the environment variable within our npm build script.

package.json
"scripts: {
"build": "cross-env CAP_BUILD=true nx run-many --target=build --all",
...
}

This variable is then accessed within your module federation configuration as a way to identify when to use the Capacitor paths for your remotes. You can see below that we have three different MFEs that we are pulling into our primary Capacitor application (account, checkout, helpinfo).

modulefederation.config.js
const isCapBuild = process.env.CAP_BUILD;

const remotes =
isCapBuild == null
// Configuration for when developing locally
? {
account: 'account@http://localhost:3004/remoteEntry.js',
checkout: 'checkout@http://localhost:3005/remoteEntry.js',
helpinfo: 'helpinfo@http://localhost:3006/remoteEntry.js',
}
// Configuration for when building for capacitor
: {
account: `account@account/remoteEntry.js`,
checkout: `checkout@checkout/remoteEntry.js`,
helpinfo: `helpinfo@helpinfo/remoteEntry.js`,
};

module.exports = {
name: 'shell',
remotes,
...
}

Now when you run npm run build it will generate a build that is built to work with Portals for Capacitor.

Capacitor Configuration

The next step is to configure Capacitor so that it knows where these files exist on the initial application build. You can see that there is configuration for the shell or main application and then config for the MFEs that are separate. the webDir paths are relative your the base directory of the shell application (where this configuration file lives). The names correspond to how you named the directories within the module federation config (account, checkout, helpinfo).

capacitor.config.ts
const capacitorConfig: CapacitorConfig = {
appId: "io.ionic.portals.ecommercewebapp",
appName: "Portals Web App",
webDir: "../shell/build",
bundledWebRuntime: false,
plugins: {
// Portals for Capacitor configuration
Portals: {
shell: {
name: "shell",
webDir: "./build",
},
apps: [
{
name: "account",
webDir: "../account/build",
},
{
name: "checkout",
webDir: "../checkout/build",
},
{
name: "helpinfo",
webDir: "../helpinfo/build",
},
],
},
},
};

After this configuration is complete you should be able to build the shell application and see everything tied together in your native emulator. To test in iOS run npx cap open ios and then build in Xcode.