微前端 使用笔记
微前端 工具ngx-planet
项目流程
1、创建主项目
ng new main
2、创建子项目
cd main
ng generate application first-app
ng generate application second-app
3、安装@worktile/planet (主应用,子应用都要)
npm i @worktile/planet --save
npm i @angular/cdk --save
主应用和子应用的appModule.ts中引用
import { NgxPlanetModule } from '@worktile/planet';@NgModule({imports: [CommonModule,NgxPlanetModule]
})
class AppModule {}
4、更改打包插件 【@angular-devkit/build-angular 更改为@angular-builders/custom-webpack】
因为主应用和子应用都是通过Webpack打包的,打包的版本依赖会有冲突,需要通过@angular-builders/custom-webpack插件设置扩展的Webpack配置runtimeChunk, 期望 Webpack 5 对于微前端支持的更好。
"devDependencies": {"@angular-builders/custom-webpack": "^9.1.0","@angular-devkit/build-angular": "~0.900.0-rc.3",......"webpack-assets-manifest": "^3.1.1"}
更改配置(angular.json):
//子应用
"architect": {"build": {"builder": "@angular-builders/custom-webpack:browser","options": {"customWebpackConfig": {"path": "./extra-webpack.config.js","mergeStrategies": {"externals": "prepend"}},"outputPath": "dist/first-project",...}}"serve": {"builder": "@angular-builders/custom-webpack:dev-server","options": {"browserTarget": "first-project:build","port": 4201,"vendorChunk": false},}
//主应用
"architect": {"build": {"builder": "@angular-builders/custom-webpack:browser","options": {"customWebpackConfig": {"path": "./extra-webpack.config.js","mergeStrategies": {"externals": "replace"}},"baseHref": "/","outputPath": "dist/main-project",........},"serve": {"builder": "@angular-builders/custom-webpack:dev-server","options": {"browserTarget": "main-project:build","proxyConfig": "proxy.conf.js","port": 4200},"configurations": {.....}
}
把extra-webpack.config.js文件复制进主应用目录下和子应用目录下
//extra-webpack.config.js
const WebpackAssetsManifest = require('webpack-assets-manifest');module.exports = {optimization: {runtimeChunk: false},plugins: [new WebpackAssetsManifest()]
};
5、代码更改
新增proxy.conf.js
const PROXY_CONFIG = {};PROXY_CONFIG['/static/firstProject'] = {target: 'http://localhost:4201',secure: false,changeOrigin: true
};module.exports = PROXY_CONFIG;
修改app.component.ts
import { Component } from '@angular/core';
import {Planet,SwitchModes} from '@worktile/planet'@Component({selector: 'app-root',templateUrl: '应用1 加载中...
',styleUrls: ['./app.component.less']
})
export class AppComponent {title = 'main-project';get loadingDone() {return this.planet.loadingDone;}constructor(private planet: Planet) { }ngOnInit() {this.planet.setOptions({switchMode: SwitchModes.coexist,errorHandler: error => {console.error(`Failed to load resource, error:`, error);}});this.planet.registerApps([{name: 'first-project',hostParent: '#app-host-container',hostClass: 'thy-layout',routerPathPrefix: '/firstProject',selector: 'first-root',preload: true,loadSerial: true,scripts: ['/static/firstProject/main.js'],}]);// start monitor route changes// get apps to active by current path// load static resources which contains javascript and css// bootstrap angular sub app module and show itthis.planet.start();}
}
app-routing.module.ts
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { EmptyComponent } from '@worktile/planet';
import { AboutComponent } from './routes/about/about.component'
import { SettingsComponent } from './routes/settings/settings.component'const routes: Routes = [{path: '',redirectTo: 'about',pathMatch: 'full'},{path: 'about',component: AboutComponent},{path: 'settings',component: SettingsComponent},{path: 'firstProject', //子应用路由component: EmptyComponent,children: [{path: '**',component: EmptyComponent}]},
];@NgModule({imports: [RouterModule.forRoot(routes)],exports: [RouterModule]
})
export class AppRoutingModule { }
主应用更改后目录结构

- 子应用
更改main.ts
import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';import { AppModule } from './app/app.module';
import { environment } from './environments/environment';import { PlanetPortalApplication, defineApplication } from '@worktile/planet';if (environment.production) {enableProdMode();
}
//独立运行
platformBrowserDynamic().bootstrapModule(AppModule).catch(err => console.error(err));//主从程序
// defineApplication('first-project', (portalApp: PlanetPortalApplication) => {
// console.log("222")
// return platformBrowserDynamic([
// {
// provide: PlanetPortalApplication,
// useValue: portalApp
// }
// ])
// .bootstrapModule(AppModule)
// .then(appModule => {
// return appModule;
// })
// .catch(error => {
// console.error(error);
// return null;
// });
// });
修改app-routing.module.ts
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { EmptyComponent } from '@worktile/planet';
import { AppComponent } from './app.component';
import { RootComponent } from './routes/root/root.component';
import { DashboardComponent } from './routes/dashboard/dashboard.component'
import { ProjectsComponent } from './routes/projects/projects.component'const routes: Routes = [{path: '',redirectTo: 'firstProject',pathMatch: 'full'},{path: 'firstProject',component: RootComponent,children: [{path: '',redirectTo: 'dashboard',pathMatch: 'full'},{path: 'dashboard',component: DashboardComponent},{path: 'projects',component: ProjectsComponent}]},{path: '**',component: EmptyComponent}
];@NgModule({imports: [RouterModule.forRoot(routes)],exports: [RouterModule]
})
export class AppRoutingModule { }
子应用更改后目录结构

6、package.json 更改
- 子应用
{"name": "first-project","version": "0.0.0","scripts": {"ng": "ng","start": "ng serve -o --port=4201 --base-href=/static/firstProject/ --deploy-url=/static/firstProject/","build": "ng build","test": "ng test","lint": "ng lint","e2e": "ng e2e"},"private": true,"dependencies": {"@angular/animations"........}
}
- 主应用
{"name": "main-project","version": "0.0.0","scripts": {"ng": "ng","start": "ng serve","build": "ng build","test": "ng test","lint": "ng lint","e2e": "ng e2e"},"private": true,"dependencies": {"@angular/animations": "~9.0.0-rc.3",........}
}
问题汇总
“An accessor cannot be declared in an ambient context.”
解决方法:tsconfig.json中新增"skipLibCheck": true
"compilerOptions": {"skipLibCheck": true
}

ERROR in ./src/styles.less (./node_modules/css-loader/dist/cjs.js??ref–14-1!./node_modules/postcss-loader/src??embedded!./node_modules/less-loader/dist/cjs.js??ref–14-3!./src/styles.less)

解决问题:
//styles.less
@import '~@delon/theme/system/index';
@import '~@delon/abc/index';
@import '~@delon/chart/index';
@import '~@delon/theme/layout/default/index';
@import '~@delon/theme/layout/fullscreen/index';@import './styles/index';
@import './styles/theme';

本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
