Reputation: 11
I have created an application with:
npx create-nx-workspace@latest angular -monorepo --preset=angular-monorepo
adding a host and a remote application with the Nx extension available in VS Code.
Both are working as expected: running the host will automatically run the remote (at localhost:4204
) and in the Nx workspace accessing the host on localhost:4203
and routing to localhost:4203/remote1
will display the remote content in the host.
Host configurations:
app.routes.ts
import { authGuard } from './auth.guard';
import { NxWelcomeComponent } from './nx-welcome.component';
import { Route } from '@angular/router';
export const appRoutes: Route[] = [
{
path: 'remote1',
loadChildren: () => import('remote1/Routes').then((m) => m.remoteRoutes),
canActivate: [authGuard],
},
{
path: '',
component: NxWelcomeComponent,
},
];
module-federation.config.ts
import { ModuleFederationConfig } from '@nx/webpack';
const config: ModuleFederationConfig = {
name: 'host',
remotes: ['remote1'],
};
export default config;
Host app:
app.component.html
<ul class="remote-menu">
<li><a routerLink="/">Home</a></li>
<li><a routerLink="remote1">Remote1</a></li>
</ul>
<router-outlet></router-outlet>
Remote1 configurations:
app.routes.ts
import { Route } from '@angular/router';
export const appRoutes: Route[] = [
{
path: '',
loadChildren: () =>
import('./remote-entry/entry.routes').then((m) => m.remoteRoutes),
},
];
module-federation.config.ts
import { ModuleFederationConfig } from '@nx/webpack';
const config: ModuleFederationConfig = {
name: 'remote1',
exposes: {
'./Routes': 'apps/remote1/src/app/remote-entry/entry.routes.ts',
'./RemoteComponent' : 'apps/remote1/src/app/remote-entry/entry.component.ts'
},
};
export default config;
These are my Nx workspace remote and host app. I need to access remote1 in my Angular application created with ng new host
. I added module federation with:
ng add @angular-architects/module-federation --project host --port 4200
webpack.config.js
const ModuleFederationPlugin = require("webpack/lib/container/ModuleFederationPlugin");
const mf = require("@angular-architects/module-federation/webpack");
const path = require("path");
const share = mf.share;
const sharedMappings = new mf.SharedMappings();
sharedMappings.register(
path.join(__dirname, 'tsconfig.json'),
[/* mapped paths to share */]);
module.exports = {
output: {
uniqueName: "hostApp",
publicPath: "auto",
scriptType: "text/javascript"
},
optimization: {
runtimeChunk: false
},
resolve: {
alias: {
...sharedMappings.getAliases(),
}
},
experiments: {
outputModule: true
},
plugins: [
new ModuleFederationPlugin({
// library: { type: "Routes" },
// For remotes (please adjust)
// name: "hostApp",
// filename: "remoteEntry.js",
// exposes: {
// './Component': './/src/app/app.component.ts',
// },
// For hosts (please adjust)
remotes: {
"remote1": "remote1@http://localhost:4204/remoteEntry.mjs",
},
// shared: share({
// "@angular/core": { singleton: true, strictVersion: true, requiredVersion: 'auto' },
// "@angular/common": { singleton: true, strictVersion: true, requiredVersion: 'auto' },
// "@angular/common/http": { singleton: true, strictVersion: true, requiredVersion: 'auto' },
// "@angular/router": { singleton: true, strictVersion: true, requiredVersion: 'auto' },
// ...sharedMappings.getDescriptors()
// })
}),
sharedMappings.getPlugin()
],
};
app.routes.ts
import { loadRemoteModule } from '@angular-architects/module-federation';
import { Routes, RouterModule } from '@angular/router';
import { AppComponent } from './app.component';
export const routes: Routes = [
{ path: "",component: AppComponent},
{path: "remote1", loadChildren: () =>{
return loadRemoteModule({
remoteEntry : "http://localhost:4204/remoteEntry.mjs",
remoteName : "remote1",
exposedModule: "remote1/RemoteComponent"
}).then(m => m.RemoteComponentModule).catch(err => console.log(err))
}
},
];
app.component.html
<ul class="remote-menu">
<li><a routerLink="/">Home</a></li>
<li><a routerLink="/remote1">Remote1</a></li>
</ul>
Home Works
<router-outlet></router-outlet>
When I tried running only remote1 with nx serve remote1
on localhost:4204
and running the Angular application with ng serve
on localhost:4200
I got these 2 errors and remote1 was not printed:
Error Typerror: container is undefined
For the first one I tried to add the
scriptType: 'text/javascript'
but that section is not available on the remote app created with Nx.
Upvotes: 0
Views: 188
Reputation: 11
Error Typerror: container is undefined
This error was coming in the console because the components from the remote was actually not actually taken correctly, what I have changed to get the remote nx mfe on native angular module federation I have changed some files in the host app
main.ts file
declare module 'remote/RemoteComponent';
declare module 'remote/Routes';
import('./bootstrap')
.catch(err => console.error(err));
app.route.ts
{
path: 'remote',
loadChildren: () =>
import('remote2/RemoteComponent')
.then(() => import('remote/Routes')
.then((m) => m.remoteRoutes).catch(err => console.log(err)))
}
The remoteComponent was taken via the route.
Upvotes: 0