

lerna+umi+antd+qiankun 搭建微服务过程
source link: https://segmentfault.com/a/1190000040469227
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

公司一个开发迭代两年的项目因后期需要扩展更多的业务板块需要进行拆分,一是要满足后期不断新增板块业务不对现有业务产生影响,再者就是目前存在单项目业务量过大,开发维护难度极大,于是不得不考虑将现有业务板块进行微服务化拆分,以满足后期的需求。
此文是对标题采用技术栈实现过程的技术分享,同时也是对该技术方案的探索和实践,感兴趣的同学请留步!
lerna
一个用于管理带有多个包的 JavaScript 项目的工具。
主要用于微服务生产阶段公共依赖的管理。可以解决的问题:开发阶段多服务同时启动,子项目不用放在同一个 git 项目中,企业中部分 npm 私服包可以更便捷的更新到各个子项目等,将部分公共依赖安装在lerna
根目录可以节省一部分存储空间。
PS:这里需要先新建一个空的项目目录,以下示例均为umi-qiankun-explore
建议将lerna
安装在全局,当然也可以安装在项目局部
npm i lerna -g
lerna init --independent //安装在全局
npx lerna init --independent //安装在局部
主要方法,既可以给某个项目单独安装依赖,也可以给所有子项目安装公共依赖,具体支持的参数见lerna bootstrap
lerna bootstrap <--options>
初始化后的 lerna 项目目录如下
umi-qiankun-explore/ |--packages/ //这里是存放微服务各模块等目录,后面已更改为project,对应需要调整的配置见下方lerna.json▼ |--package.json |--lerna.json
umi-qiankun-explore/lerna.json
{ "packages": ["project/*"], "workspaces": ["project/*"], "version": "0.0.0" }
umi-qiankun-explore/package.json
{ "name": "root", "private": true, "scripts": { "clone:all": "bash ./cli/clone-all.sh", // 这里用来可以根据设备写一个clone所有子项目的脚本 "boots": "lerna bootstrap --hoist", // 安装子项目所有公共的依赖 "start": "lerna run --parallel start " //启动所有子项目 }, "devDependencies": {} }
这里修改目录主要是在命令行下切换目录p
加Tab
会把 package.json 也带出来,就不太方便 😄
使用umi
创建子项目,在project
目录下创建根据微服务实际情况划分的项目模块,以下将采用同一种方式分别创建app-container
,app-device
,app-common
三个项目。
其中app-container
作为主项目,用于微服务的容器,一般只具备页面布局、登录授权、基础数据分发等基础业务功能。 app-common
主要作为项目公共业务模块,一般具备账户信息管理、应用设置等与具体业务无关或无强关联的基础功能。
其他子项目根据项目实际情况进行划分即可。
新建完三个项目目录后,通过官方工具创建项目
yarn create @umijs/umi-app / npx @umijs/create-umi-app
⚠️ 注意:创建完项目后,需要做两件最基础的事情,很重要
- 将各项目 package.json 中的 name 属性改为项目对应的名称
- 各项目原
start
启动命令需要指定一下端口号,形如以下
此示例项目 container 对应 8000,common 对应 8002,device 对应 8001
"start": "PORT=8001 umi dev set"
自此lerna
就派上用场了,在 umi-qiankun-explore/package.json 内新增各个 umi 项目具备的公共依赖
"dependencies": { "@ant-design/pro-layout": "^6.5.0", "@umijs/plugin-qiankun": "^2.27.0", "react": "17.x", "react-dom": "17.x", "redux-thunk": "^2.3.0", "umi": "^3.5.15" }, "devDependencies": { "@types/react": "^17.0.0", "@types/react-dom": "^17.0.0", "@umijs/preset-react": "1.x", "@umijs/test": "^3.5.15", "lint-staged": "^10.0.7", "prettier": "^2.2.0", "typescript": "^4.1.2", "yorkie": "^2.0.0" }
此时使用npm run boots
即可完成各子项目公共依赖的安装,安装完项目依赖后,我们便可以使用npm start
将各个项目同时启动起来,不过此时项目还没有微
起来。完成上述步骤后可以获得的项目目录结构如下:
目录结构(关键部分)
umi-qiankun-explore ├── project │ ├── app-common │ │ ├── mock │ │ ├── src │ │ ├── .umirc.ts │ │ ├── package.json │ │ └── ... │ ├── app-container │ │ ├── config │ │ ├── mock │ │ ├── src │ │ ├── README.md │ │ ├── package-lock.json │ │ ├── package.json │ │ ├── tsconfig.json │ │ ├── typings.d.ts │ │ └── yarn.lock │ ├── app-device │ │ ├── mock │ │ ├── src │ │ ├── .umirc.ts │ │ ├── package.json │ │ └── ... ├── lerna-umi-qiankun 搭建微服务过程.md ├── lerna.json ├── package-lock.json └── package.json
plugin-qiankun
采用 umi 官方推荐方式,将 qiankun 引入各项目
yarn add @umijs/plugin-qiankun -D
主项目 app-container
这里先采用路由绑定的方式引入子项目,MicroApp
组件方式见使用 <MicroApp /> 组件的方式
在.umirc.ts
中新增如下配置
export default defineConfig({ qiankun: { master: { // 注册子应用信息 apps: [ { name: 'app-common', // 公共服务 entry: '//localhost:8002', // 子应用通过钩子函数的参数props可以拿到这里传入的值 props: { token: 'XXXXXXX', }, }, { name: 'app-device', // 设备服务 entry: '//localhost:8001', // 子应用通过钩子函数的参数props可以拿到这里传入的值 props: { token: 'XXXXXXX', }, }, ], jsSandbox: true, // 是否启用 js 沙箱,默认为 false prefetch: true, // 是否启用 prefetch 特性,默认为 true }, }, })
假设我们页面布局主要依靠主项目的前提下,引入子项目路由的方式如下
export default defineConfig({ routes: [ { exact: false, path: '/', component: '@/layouts/index', routes: [ { path: '/home', component: '@/pages/home/index', meta: { title: '首页' }, }, // 公共服务模块 { name: 'app-common', //⚠️注意这里需要与上面qiankun配置的name相对应 path: '/common', microApp: 'app-common', }, // 设备服务模块 { name: 'app-device', path: '/device', microApp: 'app-device', }, ], }, ], })
子项目 app-common
在.umirc.ts
中新增用于支持 qiankun 的配置
import { defineConfig } from 'umi' export default defineConfig({ nodeModulesTransform: { type: 'none', }, routes: [{ path: '/', component: '@/pages/index' }], // 新增配置 qiankun: { slave: {}, }, })
还需要将子项目生命周期导出,[email protected]
版本初始化已经没有app.tsx
文件,所以我们需要手动新建一个,
/src/app.tsx
export const qiankun = { // 应用加载之前 async bootstrap(props: any) { console.log('子应用[app-common] bootstrap', props) }, // 应用 render 之前触发 async mount(props: any) { console.log('子应用[app-common] mount', props) }, // 应用卸载之后触发 async unmount(props: any) { console.log('子应用[app-common] unmount', props) }, }
app-device
与app-common
方法相同,如此便初步完成微服务项目的基础结构了。
以上只是当前技术栈下微服务的第一步,至于 qiankun 的实践应用部分还有很多坑
存在,例如样式隔离、数据共享、数据上移和下移等 qiankun 目前处理的不算全面的问题,还是得根据项目的实际情况进行问题排除和升级改造。
至此已完成整体技术栈的初步实践,当然对于lerna
,umi.js
和qiankun
还有更多的高阶业务场景没有涉及到,主要还是每个项目自身的特点对于这些技术应用的切入点不同,因此此文只做引导后续更复杂的场景还是需要我们去具体问题具体解决
留图表示按照上述所有步骤可以完成微前端的实现,哈哈哈!
感兴趣的同学可以移步 github 去拉一下我的项目 demo,后面会完善更多实际场景的复杂问题。
github
文章不是 cv 来的哈,如果对你有帮助请不要吝啬下方点个赞 👇,在此谢过!😁😁😁
Recommend
-
137
一、 umi(中文名:五米)是我目前的工作重点,正在全力开发中,从写下第一行代码开始算起已有数月。但从闲聊和邮件中发现不少人还不能准备地理解 umi 是啥、能做啥,于是趁着代码写累了,聊聊 umi 的一些情况。 umi 是工具吗?是。但不仅仅是。我给 umi
-
98
一个可插拔的企业级 react 应用框架。 umi 以路由为基础的,以及各种进阶的路由功能,并以此进行功能扩展,比如支持路由级的按需加载。然后配以完善的插件体系,覆盖从源码到构建产物的每个生命周期
-
49
-
8
最近负责的新项目用到了qiankun,写篇文章分享下实战中遇到的一些问题和思考。示例代码: https://github.com/fengxianqi/qiankun-example。在线demo:
-
13
首发于 语雀文档 前言 本人在工作中用到了 umi-request,百度谷歌搜了一遍,感觉都没找到超过 3 篇合适且含代码的文章,因此只能自行实践总结了。 umi-reques...
-
14
🎉 发布 Umi 3.2.0 — 可能是西湖区最好用的 SSR 框架蚂蚁集团 前端工程师经过近一个月、256 次提交、12 个 beta 版本后,我们发布 umi 3.2.0,增加了 服务端渲染...
-
13
React 生态里的 umi.js,很好用吗? V2EX › React React 生态里的 umi.js,很好用吗?
-
6
基于vue3.x+qiankun微前端项目搭建 - SegmentFault 思否一枚前端从业人员,偶尔写一些前端的文章,同时爱好理财,炒股。
-
12
Vite 2.0 + React + TypeScript + Antd 搭建简单脚手架Vite 出来好一段时间了,最开始支持 Vue,而现在已经不受框架限制了。而 Vite 解决的是对于项目每次启动与打包构建等待时间长的问题...
-
7
从零搭建react+ts组件库(封装antd) 为什么会有这样...
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK