前言

微前端架构是一种类似于微服务的架构,它将微服务的理念应用于浏览器端,即将 Web 应用由单一的单体应用转变为多个小型前端应用聚合为一的应用。

由此带来的变化是,这些前端应用可以独立运行、独立开发、独立部署。以及,它们应该可以在共享组件的同时进行并行开发——这些组件可以通过 NPM 或者 Git Tag、Git Submodule 来管理。

可以解决的问题:拆分工程,解决打包速度的问题,减少一个工程太多人开发出现的互相冲突的问题,降低项目的复杂度,提高项目可维护性与修改性的问题,无论在管理上还是代码上都大大提高工作效率。

这里只是描述一下微前端,最要还是 systemJS 与 lerna,因为他们在微前端上是核心。

微前端实现的方式

  1. 使用 HTTP 服务器的路由来重定向多个应用
  2. 在不同的框架之上设计通讯、加载机制,诸如 Mooa 和 Single-SPA
  3. 通过组合多个独立应用、组件来构建一个单体应用
  4. iFrame。使用 iFrame 及自定义消息传递机制
  5. 使用 Web Components 构建应用

第一种是目前比较传统的方式,如 A 项目与 B 项目互相跳转,那么我们只要在 URL 上带上个项目需要参数即可,就是很简单的页面跳转方式,也是很通用的方式,就是会页面刷新并且互相之间不能嵌套或复用。

第二种方式,是符合现在单页面应用的方式,而且可以互相复用,但需要基于 webpack 等打包工具。

第三种其实就是一个应用,只是把它分开开发,所以必须使用同一个框架,统一依赖,规范应用的组件及路由,共享通用代码,制定代码规范,比如使用 lerna 管理项目。

第四种 iFrame 其实与第一种差不多,只是它可以嵌套在别的项目里,实现互相嵌套的模式。

第五种 Web Components 是一套不同的技术,允许您创建可重用的定制元素(它们的功能封装在您的代码之外)并且在您的 Web 应用中使用它们,它的引用方式与 iframe 类似,组件拥有自己独立的 Scripts 和 Styles,以及对应的用于单独部署组件的域名,但它不成熟,不过它很有可能是以后微前端的技术方向,因为它很适合,且将来浏览器应该都支持,而不需要构建工具,浏览器支持才是最 nice 的。

systemJS

systemJS 其实就是一个模块化加载器,本意是解决项目在运行时加载模块的问题,因为 webpack 等打包工具都是编译好后再到客户端上,而想在客户端上加载时不可能的。
但 systemJS 无法直接使用 import 加载后使用,只能在 html 里 script 引入。

1
2
3
4
5
6
7
8
9
10
11
12
<script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/6.1.1/system.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/6.1.1/extras/amd.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/6.1.1/extras/named-exports.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/6.1.1/extras/named-register.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/6.1.1/extras/use-default.min.js"></script>
<script>
System.import(
"http://localhost:8000/static/js/main-bundle-11a3188c.js"
).then(() => {
// console.log($);
});
</script>

但可以 npm 安装。

1
npm i systemjs

webpack 打包的,要让 systemjs 可以加载,那么就要设置 libraryTarget 为 umd

1
2
3
4
5
output: {
filename: "static/js/[name]-bundle-[hash:8].js",
library: "app", //类库名称
libraryTarget: "umd" //类库加载方式
}

而微服务里比较流行的是 single-Spa,它其实就是一个顶级的路由,只是它是以项目为维度的,而且它兼容很多目前比较流行的技术的项目的路由,如 react,vue,angular 等等,他可以糅合它们,而且不需要前期考虑是否使用微前端,之后后期需要,就可以使用它进行重新改造,且付出代价也是最小的,可能就是需要修改一个路由的层级,因为一级路由以为项目使用。

资料

基本使用

single-Spa

single-Spa 使用

lerna

lerna 是 GitHub 上面开源的一款 js 代码库管理软件, 用来对一系列相互耦合比较大、又相互独立的 js git 库进行管理。解决各个库之间修改混乱、难以跟踪的问题。lerna 可以优化这种情形下的工作流。

代码库结构

1
2
3
4
5
6
7
my-lerna-repo/
package.json
packages/
package-1/
package.json
package-2/
package.json

由于微前端也是多个项目模块,而且也会互相耦合且独立,所以使用 lerna 管理,在某些场景下,可能会出现意想不到的优势,比如个项目之间的依赖包统一,各项目之间依赖简单,且快速统一更新包等,且只要在外层就可管理到所有的项目。

初始化

1
2
3
4
npm i -g lerna
mkdir lerna-repo
cd ./lerna-repo
lerna init

常用命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
1. 安装
lerna bootstrap
使用这个指令代替 npm install
相当于在每个 package 下面执行 npm install
根据各个 package 下 package.json 里面的 dependencies 和 devDependencies 配置,使用 symlink 在各个 package 的 node_modules 下面建立引用关系

2. 添加依赖
lerna add <pkg> [globs..]

如给 package-1 添加 依赖 vue,scope后要跟package.json里面的名字,而不是文件夹名。如果全部安装,去掉scope即可。

lerna add vue --scope=@abc/package-1

3. 指定源
例如使用yarn管理包 lerna bootstrap --npm-client=yarn
例如使用cnpm发布包 lerna publish --npm-client=cnpm

lerna 的基础使用

lerna 项目中使用