Skip to content

Latest commit

 

History

History
420 lines (332 loc) · 11.4 KB

README.md

File metadata and controls

420 lines (332 loc) · 11.4 KB

SOA-FE 前端微服务开发指南

基础架构

Build Status

简介

soa   对于网络应用程序,前端越来越大,我们的网络应用程序中 90%是前端代码.

  随着时间的推移,Web 应用也会发生变化,开发技术和框架也是如此, 这需要支持允许不同的前端框架共存、共用、共生, 前端微服务化应运而生.

准备

  1. 获取微服务基础工程

    下载 github 微服务 Master 分支基础工程 ZIP 包,然后初始化 git 和安装依赖.

  • 依赖

    a. angular 版本: 6.1

    b. 使用 ng-cosmos-ui 组件库,water-service处理后端数据

    c. 使用 water-utils 处理国际化和多主题切换

  • 目录说明

  ├── [说明]  README.md
  ├── [ng配置]  angular.json
  ├── [webpack配置]  config
  ├── [微服务部署]  deploy
  ├── [打包输出]  dist
  ├── [测试]  e2e
  ├── [依赖包]  node_modules
  ├── [依赖锁定]  package-lock.json
  ├── [依赖配置]  package.json
  ├── [代码检查]  sonar-project.properties
  ├── [开发目录]  src
  ├── [测试]  test.json
  ├── [ts配置]  tsconfig.json
  ├── [ts检查]  tslint.json
  └── [webpack基础配置]  webpack.config.js
  1. 启动工程
//安装依赖
$ npm i

//启动开发服务
$ npm start

定义微服务

  1. 在根 Module 中定义 需要引入@angular/elements,elements-zone-strategy,示例:
/**
 * soa-demo
 * https://github.com/lamphc/ng-microservice
 */
import { BrowserModule } from "@angular/platform-browser";
import { BrowserAnimationsModule } from "@angular/platform-browser/animations";
import { NgModule, Injector } from "@angular/core";
import { FormsModule } from "@angular/forms";
import { createCustomElement } from "@angular/elements";
import { ElementZoneStrategyFactory } from "elements-zone-strategy";
import { NgZorroAntdModule, NZ_I18N, zh_CN } from "ng-cosmos-ui";
import { CenterModule } from "./center/center.module";
import { AppComponent } from "./app.component";

// 配置 angular i18n
import { registerLocaleData } from "@angular/common";
import zh from "@angular/common/locales/zh";
registerLocaleData(zh);

// 配置 water-utils i18n for soa
import {
  TranslateModule,
  TranslateLoader,
  HttpLoaderFactory
} from "water-utils";
import { HttpClientModule, HttpClient } from "@angular/common/http";

@NgModule({
  declarations: [AppComponent],
  imports: [
    BrowserModule,
    BrowserAnimationsModule,
    FormsModule,
    CenterModule,
    NgZorroAntdModule,
    HttpClientModule,
    TranslateModule.forRoot({
      loader: {
        provide: TranslateLoader,
        useFactory: HttpLoaderFactory,
        deps: [HttpClient]
      }
    })
  ],
  providers: [{ provide: NZ_I18N, useValue: zh_CN }],
  entryComponents: [AppComponent]
})
export class AppModule {
  //定义微服务
  constructor(private injector: Injector) {
    const strategyFactory = new ElementZoneStrategyFactory(
      AppComponent,
      this.injector
    );
    const customCosmos = createCustomElement(AppComponent, {
      injector: this.injector,
      strategyFactory
    });
    customElements.define("soa-demo", customCosmos);
  }

  ngDoBootstrap() {}
}
  1. ElementZoneStrategyFactory 工厂函数返回一个 Angular Component 和 Custom Elements 的桥梁策略类,创建和销毁组件引用,同时它还会在 input 改变时触发脏检查,示例:
...
const strategyFactory = new ElementZoneStrategyFactory(AppComponent, this.injector);
...
  1. createCustomElement 和 customElements.define 分别创建和定义一个自定义元素,其中 customElements.define 第一个参数为最终定义的自定义元素标签名称,示例:
  • ts 代码
...
const customCosmos = createCustomElement(AppComponent, { injector: this.injector, strategyFactory });
customElements.define('soa-demo', customCosmos);
...
  1. 在根组件 app.component.ts 中定义微服务对外提供的接口,目前对外提供 5 个接口,2 个事件,如下:

    接口说明

名称 说明 类型 默认值
urlBase 后台服务基础 url string
typeTheme 主题切换方式(enum TYPETHEME { self, fork }; self:自切换,fork:跟随宿主应用切换) string 'self'
theme 主题配色(颜色值) string @primary-color
lang 语言('zh', 'en') string 'zh'
lessUrl 调试 less string
onThemeChange 主题改变时触发 EventEmitter
onLangChange 语言改变时触发 EventEmitter
  • html 代码
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <title>soa-demo</title>
    <base href="/" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <link rel="icon" type="image/x-icon" href="favicon.ico" />
    <link
      rel="stylesheet"
      type="text/css"
      href="https://jic.talkingdata.com/fa-static-resource/css/ng-cosmos-ui.min.css"
    />
  </head>

  <body>
    <soa-demo></soa-demo>
  </body>
</html>

扩展阅读:可重用网络组件

微服务命名规范和注意事项

  • 元素定义命名规范,标签以 soa-开头,后追加上该微服务英文名称,对应 js 文件以 soa.开头,命名同标签,示例:
  //js命名
  soa.soaname.js
  //tag定义
  <soa-soaname></soa-soaname>
  • 微服务中不能使用路由,有需要用到路由的场景需要分拆服务

开发规范

本地部署和测试

  • 修改对应脚本和部署文件
  1. 修改 package.json 中"copy:bundle"项,示例:
"copy:bundle": "cpr dist/soa-elements/main.js deploy/soa/soa.soaname.js -o",
  1. 修改 deploy 目录 index.html 对应的 js 引用和 tag 调用,示例:
<html>
  <head>
    <meta charset="UTF-8" />
    <base href="/" />
    <title>soa demo for deploy</title>
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <link rel="icon" type="image/x-icon" href="favicon.ico" />
    <link
      rel="stylesheet"
      type="text/css"
      href="https://jic.talkingdata.com/fa-static-resource/css/ng-cosmos-ui.min.css"
    />
    <!-- Gz share dep -->
    <script src="https://jic.talkingdata.com/fa-static-resource/libs/soa.base.js"></script>
    <!-- 这里修改对应js引用 -->
    <!-- Custom Element For SOA -->
    <script src="./soa/soa.demo.js"></script>
  </head>

  <body>
    <!-- 这里修改对应tag调用 -->
    <!-- Calling SOA -->
    <soa-demo
      urlBase="http://5990367be1e4470011c46fa8.mockapi.io"
      typeTheme="self"
      lessUrl="/assets/less/soa.demo.less"
    ></soa-demo>

    <!-- Invoke -->
    <script>
      let soa = document.querySelector("soa-demo");
      soa.lang = "en";
      soa.theme = "blue";
      soa.addEventListener("onThemeChange", e => {
        console.log(`主题切换为:${e.detail}`);
      });
      soa.addEventListener("onLangChange", e => {
        console.log(`语言切换为:${e.detail}`);
      });
    </script>
  </body>
</html>
  • 执行脚本
//部署微服务
$ npm run deploy

//更新微服务
$ npm run build

国际化和主题

首先安装 water-utils(最新工程已经安装集成)

$ npm i water-utils

国际化

  1. 在根 app.module 中引入 water-utils 包,导入 TranslateModule, TranslateLoader, HttpLoaderFactory,同时导入依赖 HttpClientModule, HttpClient
...
import { TranslateModule, TranslateLoader, HttpLoaderFactory } from "water-utils";
import { HttpClientModule, HttpClient } from '@angular/common/http';
...
  1. 在@NgModule 装饰器中,声明模块
@NgModule({
  imports: [
    ...
    HttpClientModule,
    TranslateModule.forRoot({
      loader: {
        provide: TranslateLoader,
        useFactory: HttpLoaderFactory,
        deps: [HttpClient]
      }
    })
  ]
})
  1. 新建 app.translate.ts 文件,配置翻译,目前只配置中文和英文,统一根据微服务命名作为主 key(SOANAME),示例:
/**
 * water-utils 多语言配置
 * zh and en
 * ot
 */
export const en = {
  SOANAME: {
    TITLE: "Welcome to microservices",
    SELECT: "Change language",
    THEME: "Change theme",
    LAR: "large",
    DEF: "default",
    SML: "small"
  }
};

export const zh = {
  SOANAME: {
    TITLE: "欢迎使用微服务",
    SELECT: "选择语言",
    THEME: "切换主题",
    LAR: "大",
    DEF: "中",
    SML: "小"
  }
};
  1. 在根组件 app.component.ts 中引入 TranslateService 和翻译配置文件
import { TranslateService } from "water-utils";
import { en, zh } from "./config/app.translate";
import { en_US, zh_CN, NzI18nService } from "ng-cosmos-ui";
  1. 在根组件中注入翻译服务,并初始化配置
  constructor(public translate: TranslateService, private nzI18nService: NzI18nService ...) {
    //初始化国际化配置
    translate.setTranslation('zh', zh);
    translate.setTranslation('en', en);
    translate.addLangs(['zh', 'en']);
    translate.setDefaultLang('zh');

  }
  1. 调用翻译服务进行语言切换,示例:
this.translate.use(la);
this.nzI18nService.setLocale(la === "en" ? en_US : zh_CN);

主题

1.在工程 src/assets/less 目录下新建 soa.name.less 主题配置文件,引入基础 less 配置文件,添加需要切换主题的样式,调用@primary-color 变量,示例:

@import url("https://jic.talkingdata.com/fa-static-resource/less/soa.base.less");
//自定义配置
.micro {
    background:@primary-color
  }
...
  1. 在根组件中引入 waterTheme 服务和环境变量
import WaterTheme from "water-utils";
import { environment } from "../environments/environment";
  1. 在根组件 ngOnInit 生命周期中初始化 less 配置文件,其中 lessUrl 会根据环境变量引入对应环境的 less 配置文件,示例:
...
  lessUrl: string = environment.production ? "https://jic.talkingdata.com/fa-static-resource/less/soa.demo.less" : "/assets/less/soa.demo.less"

  ngOnInit() {
     WaterTheme.initLess(this.lessUrl);
  }
...
  1. 调用 waterTheme 服务 changeTheme 方法切换主题配色
WaterTheme.changeTheme(color);

云端部署

基于前端微服务架构的部署系统

系统架构

基于 node + koa + mongodb ...

前端部署

使用前端微服务部署系统上传、发布、引用微服务