微前端与Monorepo的架构设计

前言

  • 本文主要介绍如何使 Monorepo 与微前端结合使用,篇幅较长,请结合目录酌情阅读。
  • 微前端/Monorepo方案都存在很多争议,争论无意义,选择适合自己团队的方案即可。
  • 技术实战以 Micro App + pnpm 技术栈,讲解了从零搭建到项目部署的一个完整微前端项目。

了解 Monorepo 与微前端

当想使用一项新的技术时,大量的重构工作会让你不得不放弃使用新技术的想法时,这时选择微前端方案,可以大幅降低接入旧项目的成本,使用新技术开发新的功能或重构部分旧的功能模块。

Monorepo 可以协助微前端项目,因为它可以提供一个集中式的代码库和版本控制系统,使得多个微前端应用可以共享代码和资源,并且可以更容易地进行协作和集成。通过 Monorepo,可以更容易地管理共享的组件、库和工具,以及更方便地进行测试、构建和部署。

本文将通过 pnpm monorepo + Micro-App 为例,为大家提供一种架构思路。

阅读本章节可以对 Monorepo 与微前端有一个初步的认识,并通过技术选型对比,选择更加适合你的组合方案。如果你已经对它们有一定的了解,可以跳过本章节。

1.解决哪些痛点?

  • 代码管理复杂:在传统的多仓库项目中,每个仓库都有自己的版本控制和依赖管理,这样会导致代码管理复杂,难以维护。
  • 部署困难:多仓库项目需要分别进行部署,这样容易出现版本不一致的问题,而且部署时需要耗费大量时间和人力。
  • 模块重复:在多仓库项目中,不同的仓库可能会有相同的模块,这样会浪费时间和资源。
  • 开发效率低下:在多仓库项目中,开发人员需要频繁地切换仓库,这样会降低开发效率。
  • 维护成本高:多仓库项目中,每个仓库都需要单独维护,这样会导致维护成本高。

2.实际应用场景

微前端我个人认为非常适合后台管理系统开发,尤其是在项目中往往拥有多个业务系统,每个系统都有自己的开发团队和技术栈,而这些系统之间需要进行数据共享和交互,微前端技术可以让这些系统更加灵活地集成在一起。

另外,在电商、金融等领域也可以应用微前端技术,例如电商平台通常会包含多个子系统,如商品管理、订单管理、支付管理等,这些子系统可以通过微前端技术进行集成,提高系统的整体性能和用户体验。

3.Monorepo 技术选型

介绍两种 monorepo 技术选型方向:

类型 方案 描述
构建型 TurborepoRushNx 主要解决构建效率低的问题,项目代码仓库越来越庞大,工作流(int、构建、单元测试、集成测试)也会越来越慢,专门针对这样的场景进行极致的性能优化。
轻量型 Lerna、Yarn、pnpm 渐进式方案,初期建议选择,主要为了解决依赖管理、版本管理等问题。

不论是构建型还是轻量型,他们都可以搭配使用,例如 Nx + Lerna + pnpm,他们可以各司其职。

本文更偏向业务开发方向,推荐使用更轻量得 pnpm 来实现 Monorepo 项目,如果有对版本控制有需求,可以配合 changesets 实现。

4.微前端技术选型

  • Single-spa(不推荐): 最早的微前端框架,这里提一下它的缺点,无通信机制,不支持 Javascript 沙箱,样式冲突,无法预加载。
  • Qiankun: 基于 single-spa,弥补了上述不足,现在主流的微前端方案。
  • Micro App: 基于 Web Component 原生组件进行渲染的微前端框架。
  • 无界:基于 WebComponent 容器 + iframe 沙箱的微前端框架。
  • EMP: 基于 Webpack5 Module Federation 搭建的微前端方案,共享模块粒度自由掌控,小到一个单独组件,大到一个完整应用。既实现了组件级别的复用,又实现了微服务的基本功能,总体来说功能很强大,但需要统一使用 webpack5。

我最终选择了 Micro App 微前端框架,它提供了JS沙箱、样式隔离、元素隔离、预加载、资源地址补全、插件系统、数据通信等一系列的完善功能,最主要的是它的接入成本极低,容易上手。

image.png

无界没有深入使用,用法和 Micro App 比较像,都很容易入手,但是 js 沙箱和 css 沙箱实现方式有区别,这点还是根据需求选择。

技术实战

技术实战的方案选择 pnpm + Micro App 来实现 monorepo 微前端项目,下面我们来一步步实现。

使用 pnpm 实现 monorepo

首先了解一下 monorepo 的组织结构如下:

├── packages
|   ├── pkg1
|   |   ├── package.json
|   ├── pkg2
|   |   ├── package.json
├── package.json
├── pnpm-workspace.yaml

在 monorepo 中,所有的包都放在 packages 目录下,每个包都有自己的 package.json 文件,而根目录的 package.json 用来管理整个项目的依赖。

安装 pnpm

pnpm 是一个非常轻量的 monorepo 管理工具,它的安装非常简单,只需要执行以下命令即可:

npm install -g pnpm
初始化 monorepo 项目

在项目根目录下执行以下命令,初始化 monorepo 项目:

pnpm init

创建 pnpm-workspace.yaml 文件,用来配置 monorepo 项目:

packages:
  - 'packages/*'

创建 packages/ 目录,所有的微前端应用(基座和子应用)和共享模块都放在这个目录下。如果你的应用和共享模块都很多,也可以再加入 apps 目录区别管理应用和模块。

安装 Micro-App

Micro-App 微前端项目中,可以存在多个基座应用,每个基座应用可以包含多个子应用。建议在全局依赖中安装 Micro-App,这样所有的基座应用都可以使用它,可以保持基座应用的统一性。子应用无需安装 Micro-App,后续会介绍如何在子应用中使用 Micro-App。

在项目根目录下执行以下命令,安装 Micro-App:

pnpm add micro-app -w

-w 表示安装到 workspace 根目录下。

搭建基座应用

这里我们使用 vite 来搭建基座应用,vite 是一款基于原生 ES Module 的轻量级前端构建工具,它的出现是为了解决 Webpack 构建速度慢的问题,它的构建速度非常快,可以达到秒级别的构建速度,非常适合用来搭建基座应用。

在项目根目录下执行以下命令,安装 vite:

pnpm add vite -D

这里我们使用 vite 创建一个 vue3 基座应用:

pnpm create vite --template vue packages/base

这里会提示输入项目名称,这里我们输入 base,会在 packages 目录下创建 base 目录,base 目录就是基座应用。

搭建子应用

通常来讲,微前端对技术不应有要求,但 Micro-App 子应用对 vite 的支持不是很好,所以我们选择使用 vue-cli 来搭建子应用。

Micro-App 可以使用 vite 开发子应用,但需要一些配置,可以等待 1.0 版本的更新。了解更多

这里我们使用 @vue/cli 初始化一个 vue2 子应用,详细的 vue-cli 使用可以参考 Vue CLI

当然你可以使用其他技术栈来搭建子应用,比如 React、Angular、Svelte 等,这里不做详细说明。

history 路由

需要注意的是子应用的路由配置,如果使用可以接受 hash 路由,可以略过。

创建路由文件 router/index.ts,配置路由:

import { createRouter, createWebHistory } from 'vue-router'
import routes from './router'

const router = createRouter({
  //  __MICRO_APP_BASE_ROUTE__ 为micro-app传入的基础路由
  history: createWebHistory(window.__MICRO_APP_BASE_ROUTE__ || process.env.BASE_URL),
  routes,
})

在 src 目录下创建 public-path.js, 并在 main.js 中引入:

if (window.__MICRO_APP_ENVIRONMENT__) {
  __webpack_public_path__ = window.__MICRO_APP_PUBLIC_PATH__
}
子应用跨域

如果是开发环境,可以在 webpack-dev-server 中设置 headers 支持跨域。

devServer: {
   
   
  headers: {
   
   
    'Access-Control-Allow-Origin': '*',
  },
},复制代码Error复制成功

如果是线上环境,可以通过配置 nginx 支持跨域,后文会有专门对 nginx 配置做详细讲解。

统一的应用配置文件

在 monorepo 中,我们需要统一的应用配置文件,这样可以方便我们管理所有的应用。根目录下创建 config.json 文件,用来配置应用:

这里我们可以列举几个关键的配置项:

  • name:应用名称
  • port:应用端口

例如:

"base": {
  "name": "基座",
  "packageName": "@package/core",
  "port": 4000
}

其他属性可以根据

评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值