基于qiankun搭建ng-alain15微前端项目示例实践

基础环境

实践日期:2023-03-04

ng version

Angular CLI: 15.2.1
Node: 18.14.2
Package Manager: npm 9.5.0
OS: win32 x64

设置npm镜像源

npm config set registry https://registry.npmmirror.com/

安装yarn并设置yarn镜像源,实践版本:yarn@1.22.19

npm i -g yarn

yarn config set registry https://registry.npmmirror.com/
yarn config set sass_binary_site https://npmmirror.com/mirrors/node-sass/
yarn config set canvas_binary_host_mirror https://npmmirror.com/mirrors/canvas/

主应用

创建项目,命名为main,设置样式格式为css,启用路由,设置包管理器为yarn

添加项目模板ng-alain,实践版本:ng-alain@15.1.0,过程中ng-alain的询问全部采用默认选择

安装qiankun,实践版本:qiankun@2.10.2

ng new main --style less --routing --package-manager yarn
cd main
ng add ng-alain
yarn add qiankun

创建微服务容器组件:src/app/routes/qiankun-container/qiankun-container.component.ts

import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';

@Component({
  selector: 'qiankun-container',
  template: '<div id="qiankun-container-{{containerId}}"></div>'
})
export class QiankunContainerComponent implements OnInit {
  containerId = 'default';

  constructor(private route: ActivatedRoute) {}

  ngOnInit(): void {
    this.containerId = this.route.snapshot.data?.['containerId'];
  }
}

设置路由:src/app/routes/routes-routing.module.ts

import { QiankunContainerComponent } from './qiankun-container/qiankun-container.component';

    canActivate: [startPageGuard, SimpleGuard],
    children: [ // 以下是新增内容
      {
        path: 'micro1',
        children: [
          {
            path: '**',
            component: QiankunContainerComponent,
            data: { containerId: 'micro1' },
          },
        ],
      },

设置菜单:src/app/core/startup/startup.service.ts

        children: [
          {
            text: 'Dashboard',
            link: '/dashboard',
            icon: { type: 'icon', value: 'appstore' }
          } // 以下是新增内容
          ,
          {
            text: 'Micro1',
            icon: { type: 'icon', value: 'appstore' },
            children: [
              {
                text: '主导航',
                group: true,
                hideInBreadcrumb: true,
                children: [
                  {
                    text: '仪表盘',
                    icon: 'anticon-dashboard',
                    children: [
                      {
                        text: '默认页',
                        link: '/micro1/dashboard/v1',
                      },
                      {
                        text: '分析页',
                        link: '/micro1/dashboard/analysis',
                      },
                      {
                        text: '监控页',
                        link: '/micro1/dashboard/monitor',
                      },
                      {
                        text: '工作台',
                        link: '/micro1/dashboard/workplace',
                      }
                    ]
                  },
                  {
                    text: '小部件',
                    link: '/micro1/widgets',
                    icon: 'anticon-appstore',
                  }
                ]
              },
              {
                text: 'Alain',
                group: true,
                hideInBreadcrumb: true,
                children: [
                  {
                    text: '样式',
                    icon: 'anticon-info',
                    children: [
                      {
                        text: '字体排印',
                        link: '/micro1/style/typography',
                      },
                      {
                        text: '瀑布流',
                        link: '/micro1/style/gridmasonry',
                      },
                      {
                        text: '色彩',
                        link: '/micro1/style/colors',
                      }
                    ]
                  },
                  {
                    text: 'Delon 类库',
                    icon: 'anticon-bulb',
                    children: [
                      {
                        text: '动态表单',
                        link: '/micro1/delon/form',
                      },
                      {
                        text: '简易表格',
                        link: '/micro1/delon/st',
                      },
                      {
                        text: '工具集',
                        link: '/micro1/delon/util',
                      },
                      {
                        text: '打印',
                        link: '/micro1/delon/print',
                      },
                      {
                        text: '二维码',
                        link: '/micro1/delon/qr',
                      },
                      {
                        text: '基于角色访问控制',
                        link: '/micro1/delon/acl',
                      },
                      {
                        text: '路由守卫',
                        link: '/micro1/delon/guard',
                      },
                      {
                        text: '字典缓存',
                        link: '/micro1/delon/cache',
                      },
                      {
                        text: '下载文件',
                        link: '/micro1/delon/downfile',
                      },
                      {
                        text: 'Excel操作',
                        link: '/micro1/delon/xlsx',
                      },
                      {
                        text: '本地解压缩',
                        link: '/micro1/delon/zip',
                      }
                    ]
                  }
                ]
              },
              {
                text: 'Antd Pro',
                group: true,
                hideInBreadcrumb: true,
                children: [
                  {
                    text: '表单页',
                    link: '/micro1/pro/form',
                    icon: 'anticon-edit',
                    children: [
                      {
                        text: '基础表单',
                        link: '/micro1/pro/form/basic-form',
                      },
                      {
                        text: '分步表单',
                        link: '/micro1/pro/form/step-form',
                      },
                      {
                        text: '高级表单',
                        link: '/micro1/pro/form/advanced-form',
                      }
                    ]
                  },
                  {
                    text: '列表页',
                    icon: 'anticon-appstore',
                    children: [
                      {
                        text: '查询表格',
                        link: '/micro1/pro/list/table-list',
                      },
                      {
                        text: '标准列表',
                        link: '/micro1/pro/list/basic-list',
                      },
                      {
                        text: '卡片列表',
                        link: '/micro1/pro/list/card-list',
                      },
                      {
                        text: '搜索列表',
                        children: [
                          {
                            text: '搜索列表(文章)',
                            link: '/micro1/pro/list/articles',
                          },
                          {
                            text: '搜索列表(项目)',
                            link: '/micro1/pro/list/projects',
                          },
                          {
                            text: '搜索列表(应用)',
                            link: '/micro1/pro/list/applications',
                          }
                        ]
                      }
                    ]
                  },
                  {
                    text: '详情页',
                    icon: 'anticon-profile',
                    children: [
                      {
                        text: '基础详情页',
                        link: '/micro1/pro/profile/basic',
                      },
                      {
                        text: '高级详情页',
                        link: '/micro1/pro/profile/advanced',
                      }
                    ]
                  },
                  {
                    text: '结果页',
                    icon: 'anticon-check-circle',
                    children: [
                      {
                        text: '成功页',
                        link: '/micro1/pro/result/success',
                      },
                      {
                        text: '失败页',
                        link: '/micro1/pro/result/fail',
                      }
                    ]
                  },
                  {
                    text: '异常页',
                    link: '/micro1/',
                    icon: 'anticon-exception',
                    children: [
                      {
                        text: '403',
                        link: '/micro1/exception/403',
                      },
                      {
                        text: '404',
                        link: '/micro1/exception/404',
                      },
                      {
                        text: '500',
                        link: '/micro1/exception/500',
                      }
                    ]
                  },
                  {
                    text: '个人页',
                    icon: 'anticon-user',
                    children: [
                      {
                        text: '个人中心',
                        link: '/micro1/pro/account/center',
                      },
                      {
                        text: '个人设置',
                        link: '/micro1/pro/account/settings',
                      }
                    ]
                  }
                ]
              },
              {
                text: '更多',
                group: true,
                hideInBreadcrumb: true,
                children: [
                  {
                    text: '报表',
                    icon: 'anticon-cloud',
                    children: [
                      {
                        text: '全屏关系图',
                        link: '/micro1/data-v/relation',
                      }
                    ]
                  },
                  {
                    text: '扩展',
                    link: '/micro1/extras',
                    icon: 'anticon-link',
                    children: [
                      {
                        text: '帮助中心',
                        link: '/micro1/extras/helpcenter',
                      },
                      {
                        text: '设置',
                        link: '/micro1/extras/settings',
                      },
                      {
                        text: '门店',
                        link: '/micro1/extras/poi',
                      }
                    ]
                  }
                ]
              }
            ]
          },

注册微应用并启动:src/app/app.component.ts

import { registerMicroApps, start } from 'qiankun';

  constructor(
    el: ElementRef,
    renderer: Renderer2,
    private router: Router,
    private titleSrv: TitleService,
    private modalSrv: NzModalService
  ) { // 以下是新增内容
    registerMicroApps([
      {
        name: 'micro1',
        entry: '/micro1/',
        container: '#qiankun-container-micro1',
        activeRule: 'main/#/micro1'
      }
    ]);
    start();

设置基路径和服务路径:angular.json

{
  "projects": {
    "main": {
      "architect": {
        "build": {
          "builder": "@angular-devkit/build-angular:browser",
          "options": {
            "baseHref": "/main/", // 新增该行
          },
        },
        "serve": {
          "defaultConfiguration": "development",
          "options": {
            "servePath": "main", // 新增该行

设置代理配置:proxy.conf.js

module.exports = { // 以下是新增内容
  '/micro1/': {
    target: 'http://localhost:4201/',
  },

启动应用

yarn start

微应用

克隆项目,实践版本:SHA-1: 6a8a939b580cc717ee779e71222055358e0125a8

git clone --depth=1 https://github.com/ng-alain/ng-alain.git micro1

修改项目名称:angular.json

projects/ng-alain/architect节点里的ng-alain:改为micro1:,批量改时需要包含冒号,共6处

projects节点下的ng-alain改为micro1

cli节点里的ng-alain保持原状

{
  "projects": {
    "ng-alain": { // ng-alain改为micro1
  },
  "cli": {
    "schematicCollections": [
      "ng-alain" // 保持原状

修改包名称:package.json

{
  "name": "ng-alain", // ng-alain改为micro1

修改选择器前缀:angular.json

{
  "projects": {
    "ng-alain": {
      "prefix": "app", // app改为micro1

修改应用根标签

将项目中的app-root改为micro1-root,5个文件中共6处

修改应用根标签是必要的,否则会与主应用根标签(app-root)混淆,导致主应用异常

e2e/src/app.po.ts
src/index.html
src/app/app.component.ts
src/assets/style.compact.css
src/assets/style.dark.css

添加项目模板single-spa-angular,实践版本:single-spa-angular@8.0.1

过程中会出现3个问题,如下回答

安装依赖,以满足single-spa-angular的需要

cd micro1
ng add single-spa-angular

Would you like to proceed? (Y/n) Y
Does your application use Angular routing? (Y/n) Y
What port should your project run on? (4200) 4201

yarn install

移除预加载(preloader)层:src/index.html

微应用在主应用中启动时,会出现预加载层遮罩整个窗口,但是微应用启动完成后,预加载层不消失

预加载组件功能使用类选择器document.querySelector(".preloader")定位预加载层

微应用能定位到主应用的预加载层,却不能定位到自己的预加载层,无法控制其消失

  <micro1-root></micro1-root>
  <!-- 删除或注释掉div.preloader
  <div class="preloader">
    <div class="cs-loader">
      <div class="cs-loader-inner">
        <label> ●</label>
        <label> ●</label>
        <label> ●</label>
        <label> ●</label>
        <label> ●</label>
        <label> ●</label>
      </div>
    </div>
  </div>
  -->

设置路由:src/app/routes/routes-routing.module.ts

不包裹基础布局组件LayoutBasicComponent,主应用负责控制布局

const routes: Routes = [
  {
    path: '',
    component: LayoutBasicComponent, // 删除或注释掉该行

设置基路径、部署路径和服务路径:angular.json

{
  "projects": {
    "main": {
      "architect": {
        "build": {
          "options": {
            "baseHref": "/micro1/", // 新增该行
            "deployUrl": "http://localhost:4201/" // "http://localhost:4201/"改为"/micro1/"
          },
        },
        "serve": {
          "builder": "@angular-builders/custom-webpack:dev-server",
          "options": {
            "servePath": "micro1", // 新增该行

设置基路径:src/app/routes/routes-routing.module.ts

import { APP_BASE_HREF } from '@angular/common';

@NgModule({
  providers: [PreloadOptionalModules, { provide: APP_BASE_HREF, useValue: '/micro1' }], // 设置APP_BASE_HREF

设置基路径:src/environments/environment.ts、environment.prod.ts

  api: {
    baseUrl: './', // './'改为'/micro1/'

设置基路径:src/assets/tmp/app-data.json

    "avatar": "./assets/tmp/img/avatar.jpg", // ./assets/改为/micro1/assets/

设置基路径:src/app/layout/basic/basic.component.ts

将文件中的`./assets/改为`${this.baseUrl}assets/,共2处

export class LayoutBasicComponent {
  baseUrl = environment.api.baseUrl; // 新增该行
  options: LayoutDefaultOptions = {
    logoExpanded: `./assets/logo-full.svg`,
    logoCollapsed: `./assets/logo.svg`

设置基路径:src/app/layout/basic/widgets/task.component.ts

将文件中的'./assets/改为baseUrl + 'assets/,共5处

import { environment } from '@env/environment';

              <nz-avatar [nzSrc]="'./assets/tmp/img/1.png'"></nz-avatar>

              <nz-avatar [nzSrc]="'./assets/tmp/img/2.png'"></nz-avatar>

              <nz-avatar [nzSrc]="'./assets/tmp/img/3.png'"></nz-avatar>

              <nz-avatar [nzSrc]="'./assets/tmp/img/4.png'"></nz-avatar>

              <nz-avatar [nzSrc]="'./assets/tmp/img/5.png'"></nz-avatar>

export class HeaderTaskComponent { // 以下是新增内容
  baseUrl = environment.api.baseUrl;

设置基路径:src/app/layout/passport/passport.component.ts

import { environment } from '@env/environment';

export class LayoutPassportComponent implements OnInit { // 以下是新增内容
  baseUrl = environment.api.baseUrl;

设置基路径:src/app/layout/passport/passport.component.html

将文件中的"./assets/改为"{{baseUrl}}assets/,共1处

        <img class="logo" src="./assets/logo-color.svg" />

设置基路径:src/app/routes/dashboard/v1/v1.component.ts

import { environment } from '@env/environment';

export class DashboardV1Component implements OnInit { // 以下是新增内容
  baseUrl = environment.api.baseUrl;

设置基路径:src/app/routes/dashboard/v1/v1.component.html

将文件中的'./assets/改为baseUrl + 'assets/,共2处

          <nz-avatar [nzSrc]="'./assets/tmp/img/' + item.avatar + '.png'"></nz-avatar>

          <nz-avatar [nzSrc]="'./assets/tmp/img/' + item.avatar + '.png'"></nz-avatar>

设置基路径:src/app/routes/extras/settings/settings.component.ts

import { environment } from '@env/environment';

export class ExtrasSettingsComponent implements OnInit { // 以下是新增内容
  baseUrl = environment.api.baseUrl;

设置基路径:src/app/routes/extras/settings/settings.component.html

将文件中的"./assets/改为"{{baseUrl}}assets/,共1处

          <img src="./assets/tmp/img/avatar.jpg" style="width: 100%" />

设置基路径:src/app/routes/style/gridmasonry/gridmasonry.component.ts

import { environment } from '@env/environment';

export class GridMasonryComponent {
  baseUrl = environment.api.baseUrl;
}

设置基路径:src/app/routes/style/gridmasonry/gridmasonry.component.html

将文件中的"assets/改为"{{baseUrl}}assets/,共10处

    <img src="assets/tmp/img/bg1.jpg" alt="" />

    <img src="assets/tmp/img/bg2.jpg" alt="" />

    <img src="assets/tmp/img/bg3.jpg" alt="" />

    <img src="assets/tmp/img/bg4.jpg" alt="" />

    <img src="assets/tmp/img/bg5.jpg" alt="" />

    <img src="assets/tmp/img/bg6.jpg" alt="" />

    <img src="assets/tmp/img/bg7.jpg" alt="" />

    <img src="assets/tmp/img/bg8.jpg" alt="" />

    <img src="assets/tmp/img/bg9.jpg" alt="" />

    <img src="assets/tmp/img/bg10.jpg" alt="" />

设置基路径:src/app/routes/widgets/widgets/widgets.component.ts

import { environment } from '@env/environment';

export class WidgetsComponent implements OnInit { // 以下是新增内容
  baseUrl = environment.api.baseUrl;

设置基路径:src/app/routes/widgets/widgets/widgets.component.html

将文件中的"./assets/改为"{{baseUrl}}assets/,共3处

将文件中的('./assets/改为('{{baseUrl}}assets/,共1处

将文件中的'./assets/改为baseUrl + 'assets/,共3处

        <img src="./assets/tmp/img/half-float-bg-1.jpg" />

          <img class="p-sm" src="./assets/tmp/img/1.png" />

      <div class="text-center bg-center py-lg text-white" style="background-image: url('./assets/tmp/img/bg9.jpg')">
        <nz-avatar [nzSrc]="'./assets/tmp/img/1.png'"></nz-avatar>

        <img class="img-fluid align-middle" src="./assets/tmp/img/bg1.jpg" alt="" />

          <nz-avatar [nzSrc]="'./assets/tmp/img/' + item.avatar + '.png'"></nz-avatar>

          <nz-avatar [nzSrc]="'./assets/tmp/img/' + item.avatar + '.png'"></nz-avatar>

关闭操作指南:src/app/routes/dashboard/v1/v1.component.ts

    setTimeout(() => this.genOnboarding(), 1000); // 删除或注释掉该行

启动应用

yarn run serve:single-spa:micro1

访问

http://localhost:4200/main/

跳转微应用:http://localhost:4200/main/#/micro1/dashboard/v1

链接

基于qiankun搭建ng-alain15微前端项目示例实践_TodayCoding的博客-CSDN博客

代码

ng-alain15-example · master · TodayCoding / Qiankun study examples · GitCode

相关

基于qiankun搭建angular15微前端项目入门实践_TodayCoding的博客-CSDN博客

基于qiankun搭建angular15 hash URL微前端项目入门实践_TodayCoding的博客-CSDN博客

基于qiankun搭建ng-alain15微前端项目入门实践_TodayCoding的博客-CSDN博客

基于qiankun搭建vue3 webpack ts微前端项目入门实践_TodayCoding的博客-CSDN博客

基于qiankun搭建vue3 webpack ts无懒加载微前端项目入门实践_TodayCoding的博客-CSDN博客

基于qiankun搭建element plus webpack微前端项目入门实践_TodayCoding的博客-CSDN博客

基于qiankun搭建react18微前端项目入门实践_TodayCoding的博客-CSDN博客

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值