IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 游戏开发 -> Angular基于ngx-planet架构实现微前端 -> 正文阅读

[游戏开发]Angular基于ngx-planet架构实现微前端

系列文章目录?

提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加
例如:第一章 Python 机器学习入门之pandas的使用


提示:本文比较适用有[angular]基础的小白,大佬的话可以忽略应该提供不了什么参考价值;本文适用于angular 7以上的版本,为angular 提供一种较为简单但又可以应用于实际开发微前端实现方案。第一次写发布文章希望对大家有帮助


目录

系列文章目录?

前言

一、什么是portal、什么是子应用

二、使用步骤

1.配置portal?

1-1.主应用(portal)安装版本对应的依赖包?

1-2.主应用(portal)app.module.ts 引入NgxPlanetModule

?1-3主应用(portal)使用Planet服务

2.配置子应用

2-1.子应用安装angular版本对应的依赖包?

2-2.创建一个custom-webpack用的配置文件extra-webpack.config.js

2-3.子应用用添加一个路由输出用的组件(TenAppRouterOutLetComponent)以及关联配置:

2-4.子应用angular.json配置:

2-5?package.json

?2-6.子应用通过defineApplication定义如何启动子应用的AppModule, 同时可以设置PlanetPortalApplication服务为主应用的全局服务

2-7 启动测试

?3.portal 注册子应用

?3-1.portal?app.component.ts 注册子应用

3-3.app-routing.module.ts 添加路由

4.总结?

5.报错处里 及注意事项

报错?An accessor cannot be declared in an ambient context.


前言

为了解决部门前端因随着功能的叠加导致前端工程的越发膨大;可维护性逐渐降低(例如到部署到k8s、run pipeline 时间越来越长,本地任意的改动dev-server重新呈现都越来越费时,不同团队都放置一个git仓库越发的乱,分支数倍增,升级难...)可谓是牵一发何止动全身的问题;最终实现将前端应用分解成一些更小、更简单的能够独立开发、测试、部署的小块,这些小块可以有独立的依赖,独立的样式,可以单独的升级,而在用户看来仍然是内聚的单个产品。

注:本文只教你如何快速基于ngx-planet快速搭建出Angular微前端,(不介绍 git cicd的配置,k8s的配置,sonarqube 配置.... 即自动化(自动部署)流程不做任何介绍);其他的(例如:样式分离,样式按需应用)有空再补充。




一、什么是portal、什么是子应用

portal :是所有子应用的入口,一般提供子应用的挂载,子应用的基底(公共)数据和(公共)serve。longin(即登录)、主页一般也放在实现。

子应用:就是功能模块,例如新开的专案。




二、使用步骤




1.配置portal?

angular8 新创建的项目v8-portal-web为例.

1-1.主应用(portal)安装版本对应的依赖包?

@angular/cdk

@worktile/planet

 npm install @angular/cdk@8 --save --force
npm install @worktile/planet@^1.2.4 --save --force

1-2.主应用(portal)app.module.ts 引入NgxPlanetModule

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { NgxPlanetModule } from '@worktile/planet';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    NgxPlanetModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

?1-3主应用(portal)使用Planet服务

import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { Planet, SwitchModes } from '@worktile/planet';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent implements OnInit {
  get loadingDone() {
    return this.planet.loadingDone;
  }
  constructor(private planet: Planet,
    private router: Router) {
  }

  ngOnInit() {
    this.planet.setOptions({
      switchMode: SwitchModes.default,
      errorHandler: error => {
        console.error(`Failed to load resource, error:`, error);
      }
    });

    // common Dataa
    this.planet.setPortalAppData({
      foundationSvc: {}
    });

    // 注册子应用
    this.planet.registerApps([
    ]);

    // 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 it
    this.planet.start();
  }

  gotoDomePage(event: any) {
    this.router.navigate([`/admin/dome-page`]);
  }
}




2.配置子应用

angular10?新创建的项目ten-web为例.

2-1.子应用安装angular版本对应的依赖包?

@angular/cdk

@worktile/planet

@angular-builders/custom-webpack

 npm install @angular/cdk@10 --save --force
npm install @worktile/planet@^10 --save --force
npm install @angular-builders/custom-webpack@10 --save-dev 

其他可选依赖

webpack-assets-manifest:?"^4.0.6"

concurrently

2-2.创建一个custom-webpack用的配置文件extra-webpack.config.js

const WebpackAssetsManifest = require('webpack-assets-manifest');
// const PrefixWrap = require('@worktile/planet-postcss-prefixwrap');

module.exports = {
    optimization: {
        runtimeChunk: false
    },
    plugins: [new WebpackAssetsManifest()],
    // module: {
    //     rules: [
    //         {
    //             test: /\.scss$/,
    //             use: [
    //                 {
    //                     loader: 'postcss-loader',
    //                     options: {
    //                         plugins: [
    //                             PrefixWrap('.ten-web', {
    //                                 hasAttribute: 'planet-inline',
    //                                 prefixRootTags: true
    //                             })
    //                         ]
    //                     }
    //                 },
    //                 'sass-loader'
    //             ]
    //         }
    //     ]
    // }
};

2-3.子应用用添加一个路由输出用的组件(TenAppRouterOutLetComponent)以及关联配置:

import { Component } from '@angular/core';

@Component({
  selector: 'ten-app-router-outlet',
  template: '<router-outlet></router-outlet>'
})
export class TenAppRouterOutLetComponent {
}

子应用ten-app.module.ts?:

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { TenAppRoutingModule } from './ten-app-routing.module';
import { TenAppComponent } from './ten-app.component';
import { TenAppRouterOutLetComponent } from './ten-app-router-outlet-component';
import { ProjectsModule } from 'src/projects/projects.module';

@NgModule({
  declarations: [
    TenAppComponent, // root 组件
    TenAppRouterOutLetComponent // 子应用输出组件
  ],
  imports: [
    BrowserModule,
    TenAppRoutingModule,
    ProjectsModule
  ],
  providers: [],
  bootstrap: [TenAppComponent]
})
export class TenAppModule { }

子应用ten-app-routing.module.ts:配置router

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { DomePageComponent } from 'src/projects/dome-page/dome-page.component';
import { TenAppRouterOutLetComponent } from './ten-app-router-outlet-component';

const routes: Routes = [
  {
    path: 'ten',
    component: TenAppRouterOutLetComponent,
    children: [
      {
        path: 'dome-page',
        component: DomePageComponent,
      }
    ]
  }

];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class TenAppRoutingModule { }

2-4.子应用angular.json配置:

      "architect": {
        "build": {
          "builder": "@angular-builders/custom-webpack:browser",
          "options": {
            "customWebpackConfig": {
              "path": "src/extra-webpack.config.js",
              "mergeStrategies": {
                "module.rules": "prepend"
              },
              "replaceDuplicatePlugins": true
            },
            "vendorChunk": false,
       ...
        "serve": {
          "builder": "@angular-builders/custom-webpack:dev-server",
          "options": {
            "browserTarget": "ten-web:build",
            "port": 3002,
            "vendorChunk": false
          },

2-5?package.json

serve:ten-web: // 执行该指令 用于单独启动该子应用

start: // 在启动子应用的同时也会启动portal 的start? (portal要放置跟子应用同一个文件夹下才起作用)

    "serve:ten-web": "ng serve ten-web --deploy-url=/ten-web/",
    "start": "concurrently \"npm run start --prefix=../v8-portal-web\" \"npm run serve:ten-web\"",
    "build": "ng build ten-web --prod --deploy-url=/ten-web/",

?2-6.子应用通过defineApplication定义如何启动子应用的AppModule, 同时可以设置PlanetPortalApplication服务为主应用的全局服务

import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { defineApplication, PlanetPortalApplication } from '@worktile/planet';

import { TenAppModule } from './ten-app/ten-app.module';
import { environment } from './environments/environment';

if (environment.production) {
  enableProdMode();
}

// platformBrowserDynamic().bootstrapModule(TenAppModule)
//   .catch(err => console.error(err));

defineApplication('ten-web', (portalApp: PlanetPortalApplication) => {
  return platformBrowserDynamic([
    {
      provide: PlanetPortalApplication,
      useValue: portalApp
    }
  ])
    .bootstrapModule(TenAppModule)
    .then(appModule => {
      return appModule;
    })
    .catch(error => {
      console.error(error);
      return null;
    });
});

2-7 启动测试

?

?

?3.portal 注册子应用

?3-1.portal?app.component.ts 注册子应用

this.planet.registerApps([
      {
        name: 'ten-web',
        hostParent: '#app-root-portal',
        hostClass: 'thy-layout',
        routerPathPrefix: '/ten',
        selector: 'ten-app-root',
        preload: false,
        manifest: 'ten_proxy/ten-web/manifest.json',
        scripts: [
          'ten_proxy/ten-web/main.js',
        ],
        styles: [
          // 'ten_proxy/ten-web/styles.css',
          'ten_proxy/ten-web/ten-styles.css'
        ]
      }
    ]);

?3-2.使用方向代理?proxy.conf.js

const PROXY_CONFIG = {};

PROXY_CONFIG["/admin-web"] = {
  target: "http://localhost:3001",
  secure: false,
  changeOrigin: true,
  pathRewrite: { // 对请求路径进行重定向以匹配到正确的请求地址
    "^/admin-web": "/admin-web",
  },
};

// ten-web 的方向代理
PROXY_CONFIG["/ten_proxy"] = {
  target: "http://localhost:3002",
  secure: false,
  changeOrigin: true,
  pathRewrite: { // 对请求路径进行重定向以匹配到正确的请求地址
    "^/ten_proxy": "",
  },
};

module.exports = PROXY_CONFIG;

?portal?angular.json:
?

  "serve": {
          "builder": "@angular-devkit/build-angular:dev-server",
          "options": {
            "browserTarget": "v8-portal-web:build",
            "proxyConfig": "proxy.conf.js"
          },
          "configurations": {
            "production": {
              "browserTarget": "v8-portal-web:build:production"
            }
          }
        },

3-3.app-routing.module.ts 添加路由


const routes: Routes = [
  {
    path: 'admin',
    component: EmptyComponent,
    children: [
      {
        path: '**',
        component: EmptyComponent
      }
    ]
  },
  {
    path: 'ten',
    component: EmptyComponent,
    children: [
      {
        path: '**',
        component: EmptyComponent
      }
    ]
  },
...

4.总结?

?案例代码Git?仓储地址::angualr-ngx-planet-self · GitLab

以上就是angular 最全也最简单的实现方案

5.报错处里 及注意事项

报错?An accessor cannot be declared in an ambient context.

一般出现在angular8或更低的版本TypeScript 某个版本的缺陷?

tsconfig.app.json? ?"skipLibCheck": true

{
  "extends": "./tsconfig.json",
  "compilerOptions": {
    "outDir": "./out-tsc/app",
    "types": [],
    "skipLibCheck": true
  },
  "files": [
    "src/main.ts",
    "src/polyfills.ts"
  ],
  "include": [
    "src/**/*.ts"
  ],
  "exclude": [
    "src/test.ts",
    "src/**/*.spec.ts"
  ]
}

style报错:

?

注意事项:

  • 主要各个路径要配置要对应实际路径
  • 更多内容可以参考?ngx-planet? (去做按需调整)

  游戏开发 最新文章
6、英飞凌-AURIX-TC3XX: PWM实验之使用 GT
泛型自动装箱
CubeMax添加Rtthread操作系统 组件STM32F10
python多线程编程:如何优雅地关闭线程
数据类型隐式转换导致的阻塞
WebAPi实现多文件上传,并附带参数
from origin ‘null‘ has been blocked by
UE4 蓝图调用C++函数(附带项目工程)
Unity学习笔记(一)结构体的简单理解与应用
【Memory As a Programming Concept in C a
上一篇文章      下一篇文章      查看所有文章
加:2021-09-13 09:34:32  更:2021-09-13 09:35:49 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/17 16:17:55-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码