我知道你可以在一个角度工作区内有多个角度应用程序,作为加载到shell角度应用程序中的遥控器,但你可以有多个不在同一工作区的角度应用程序吗?我们在不同的存储库中有应用程序,所以它们不在同一个工作区中。
---主机应用程序webpack.config.js--
const { shareAll, withModuleFederationPlugin } = require('@angular-architects/module-federation/webpack');
module.exports = withModuleFederationPlugin({
remotes: {
"appOne": "http://localhost:4201/remoteEntry.js",
"appTwo": "http://localhost:4202/remoteEntry.js",
},
shared: {
...shareAll({ singleton: true, strictVersion: true, requiredVersion: 'auto' }),
},
});
---主机应用程序主.ts-
import { loadRemoteEntry } from '@angular-architects/module-federation';
import('./bootstrap')
.catch(err => console.error(err));
Promise.all([
loadRemoteEntry('http://localhost:4201', 'appOne'),
loadRemoteEntry('http://localhost:4202', 'appTwo'),
])
.catch((err) => console.error('Error loading remote entries', err))
.then(() => import('./bootstrap'))
.catch((err) => console.error(err));
---主机应用程序例程模块.ts(仅限路由(---
export const APP_ROUTES: Routes = [
{
path: '',
component: HomeComponent,
pathMatch: 'full'
},
{
path: 'app-one',
loadChildren: () => loadRemoteModule({
remoteName: 'appOne',
exposedModule: './appOne',
}).then((m) => m.AppOneModule)
},
{
path: 'app-two',
loadChildren: () => loadRemoteModule({
remoteName: 'appTwo',
exposedModule: './appTwo',
}).then((m) => m.AppTwoModule)
}
];
---远程应用程序ONE webpack.config.js--
const { shareAll, withModuleFederationPlugin } = require('@angular-architects/module-federation/webpack');
module.exports = withModuleFederationPlugin({
name: 'appOne',
exposes: {
'./appOne': './projects/app-one/src/app/app-one/app-one.module.ts',
},
shared: {
...shareAll({ singleton: true, strictVersion: true, requiredVersion: 'auto' }),
},
});
---远程应用程序ONE应用程序模块.ts-
import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core';
import { AppOneComponent } from './app-one.component';
import { AppOneRoutingModule } from './app-one-routing-module';
@NgModule({
declarations: [AppOneComponent],
imports: [CommonModule, AppOneRoutingModule]
})
export class AppOneModule {}
---远程APP ONE应用程序-路由模块.ts-
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { AppOneComponent } from './app-one.component';
const routes: Routes = [{ path: '', component: AppOneComponent }];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule],
})
export class AppOneRoutingModule {}
激活所有角度项目(shell和remotes(中的模块联盟
要做到这一点,您可以使用原理图@angular architects/module federation和以下命令:
ng add @angular-architects/module-federation
这将在差异文件中生成必要的配置:
- src/bootstrap.ts (bootstrap of AppModule)
- src/main.ts (import bootstrap)
- webpack.config.js (skeleton to use module federation)
- webpack.prod.config.js (skeleton to use module federation)
外壳
shell应用程序将使用路由器延迟加载远程模块(remote1,remote2(
export const APP_ROUTES: Routes = [
{
path: '',
component: HomeComponent,
pathMatch: 'full'
},
{
path: 'remote1',
loadChildren: () => loadRemoteModule({
remoteName: 'remote1App',
exposeModule: './Remote1',
}).then((m) => Remote1Module)
},
];
因此,Remote1Module模块不是shell项目的一部分。
您的main.ts file
将看起来像:
Promise.all([
loadRemoteEntry('https://url_remote1', 'remote1App'),
loadRemoteEntry('https://url_remote2', 'remote2App'),
])
.catch((err) => console.error('Error loading remote entries', err))
.then(() => import('./bootstrap'))
.catch((err) => console.error(err));
因此,在这里,您正尝试使用他的url和名称加载远程应用程序。名称必须是要在路由(remoteName: 'remote1App'
(中使用的名称的引用。
Microfrontend项目(Aka远程(
假设我们在remote1项目中,该项目有一个名为Remote1Module的模块。该模块包含我们希望在Shell应用程序中公开的功能。为了实现这一点,我们需要在remote1项目的webpack中公开Remote1Module。
module.export = {
...
plugins: [
new ModuleFederationPlugin({
name: 'remote1',
filename: 'remoteEntry.js',
exposes: {
'./remote1App': './src/app/remote1.module.ts'
}
}),
shared: share({
...
})
]
}
此配置以公共名称remote1App公开Remote1Module。您还可以使用共享部分与Shell应用程序共享一些软件包。
试用
你可以先运行你的远程应用程序,然后再运行你的shell,但这个顺序是不必要的。我建议只是为了避免错误
加载远程条目时出错。。。
ng serve remote1App
ng serve shell
曼弗雷德·斯泰尔的所有学分(https://www.angulararchitects.io/en/aktuelles/the-microfrontend-revolution-part-2-module-federation-with-angular/)
如果您不使用单回购方法,则需要在所有角度项目中设置模块联合