微前端乾坤方案
了解乾坤
介绍
qiankun 是一个基于 single-spa 的微前端实现库,旨在帮助大家能更简单、无痛的构建一个生产可用微前端架构系统。
qiankun 的核心设计理念
-
🥄 简单
由于主应用微应用都能做到技术栈无关,qiankun 对于用户而言只是一个类似 jQuery 的库,你需要调用几个 qiankun 的 API 即可完成应用的微前端改造。同时由于 qiankun 的 HTML entry 及沙箱的设计,使得微应用的接入像使用 iframe 一样简单。
-
🍡 解耦/技术栈无关
微前端的核心目标是将巨石应用拆解成若干可以自治的松耦合微应用,而 qiankun 的诸多设计均是秉持这一原则,如 HTML entry、沙箱、应用间通信等。这样才能确保微应用真正具备 独立开发、独立运行 的能力。
特性
- 📦 基于 single-spa 封装,提供了更加开箱即用的 API。
- 📱 技术栈无关,任意技术栈的应用均可 使用/接入,不论是 React/Vue/Angular/JQuery 还是其他等框架。
- 💪 HTML Entry 接入方式,让你接入微应用像使用 iframe 一样简单。
- 🛡 样式隔离,确保微应用之间样式互相不干扰。
- 🧳 JS 沙箱,确保微应用之间 全局变量/事件 不冲突。
- ⚡️ 资源预加载,在浏览器空闲时间预加载未打开的微应用资源,加速微应用打开速度。
- 🔌 umi 插件,提供了 @umijs/plugin-qiankun 供 umi 应用一键切换成微前端架构系统。
qiankun 在 single-spa 的基础上都增加了啥?
以下是 qiankun 提供的特性:
- 实现了子应用的加载,在原有 single-spa 的
JS Entry基础上再提供了HTML Entry - 样式和 JS 隔离
- 更多的生命周期:
beforeMount,afterMount,beforeUnmount,afterUnmount - 子应用预加载
- umi 插件
- 全局状态管理
- 全局错误处理
qiankun 的使用
主应用
0、安装 qiankun
$ yarn add qiankun # 或者 npm i qiankun -S
1、引入
import {
registerMicroApps, start } from 'qiankun';
2-1、注册子应用,并启动
registerMicroApps([
{
name: 'react app', // app name registered
entry: '//localhost:7100',
container: '#yourContainer',
activeRule: '/yourActiveRule',
},
{
name: 'vue app',
entry: {
scripts: ['//localhost:7100/main.js'] },
container: '#yourContainer2',
activeRule: '/yourActiveRule2',
},
]);
// 启动 qiankun
start();
备注
自动注册模式:当微应用信息注册完之后,一旦浏览器的 url 发生变化,便会自动触发 qiankun 的匹配逻辑,所有
activeRule规则匹配上的微应用就会被插入到指定的container中,同时依次调用微应用暴露出的生命周期钩子。
主应用不限技术栈,只需要提供一个容器 DOM,然后注册微应用并start即可。
2-2、手动加载子应用
如果微应用不是直接跟路由关联的时候,你也可以选择手动加载微应用。
import {
loadMicroApp } from 'qiankun';
loadMicroApp({
name: 'app',
entry: '//localhost:7100',
container: '#yourContainer',
});
子应用改造
微应用不需要额外安装任何其他依赖即可接入到 qiankun 主应用。
1、前提
子应用的资源和接口的请求都在主域名发起,所以会有跨域问题,子应用必须做cors 设置。
// webpack
const {
name } = require('./package');
module.exports = {
devServer: (config) => {
// 因为内部请求都是 fetch 来请求资源,所以子应用必须允许跨域
config.headers = {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Credentials': true,
'Access-Control-Allow-Headers': 'X-Requested-With,Content-Type',
'Access-Control-Allow-Methods': 'PUT,POST,GET,DELETE,OPTIONS',
'Content-Type': 'application/json; charset=utf-8',
};
return config;
},
};
2、生命周期改造
微应用需要在应用的入口文件 (通常就是你配置的 webpack 的 entry js) 导出 bootstrap、mount、unmount、update 四个生命周期钩子,以供主应用在适当的时机调用。
具体操作可以参考下面示例
步骤一:在 src 目录新增 public-path.js,用于修改运行时的 publicPath。
if (window.__POWERED_BY_QIANKUN__) {
__webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;
}
备注
什么是运行时的 publicPath ?
运行时的publicPath和构建时的publicPath是不同的,两者不能等价替代。
步骤二:修改入口文件
主要改动:
- 引入
public-path.js export生命周期函数- 将子应用路由的创建、实例的创建渲染挂载到
mount函数上 - 将实例的销毁挂载到
unmount上
- 将子应用路由的创建、实例的创建渲染挂载到
// vue 2
// 入口文件 `main.js` 修改,为了避免根 id `#app` 与其他的 DOM 冲突,需要限制查找范围。
import './public-path';
import Vue from 'vue';
import App from './App.vue';
import VueRouter from 'vue-router';
import routes from './router';
import store from './store';
Vue.config.productionTip = false;
let router = null;
let instance = null;
function render(props = {
}) {
const {
container } = props;
router = new VueRouter({
// histroy模式的路由需要设置base。app-vue 根据项目名称来定
base: window.__POWERED_BY_QIANKUN__ ? '/app-vue/' : '/',
mode: 'history',
// hash模式则不需要设置base
routes,
});
instance = new Vue({
router,
store,
render: (h) => h(App),
}).$mount(container ? container.querySelector('#app') : '#app');
}
// 独立运行时
if (!window.__POWERED_BY_QIANKUN__) {
render();
}
export async function bootstrap() {
console.log('[vue] vue app bootstraped');
}
export async function mount(props) {
console.log('[vue] props from main framework', props);
render(props);
}
export async function unmount() {
instance.$destroy();
instance.$el.innerHTML = '';
instance = null;
router = null;
}
// react 16
// 以 `create react app` 生成的 `react 16` 项目为例,搭配 `react-router-dom` 5.x。
// 入口文件 `index.js` 修改,为了避免根 id `#root` 与其他的 DOM 冲突,需要限制查找范围。
// 这里需要特别注意的是,通过 ReactDOM.render 挂载子应用时,需要保证每次子应用加载都应使用一个新的路由实例。
import './public-path';
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
function render(props) {
const {
container } = props;
ReactDOM.render(<App />, container ? container.querySelector('#root') : document.querySelector('#root'));
}
if (!window.__POWERED_BY_QIANKUN__) {
render({
});
}
export async function bootstrap() {
console.log('[react16] react app bootstraped');
}
export async function mount(props) {
console.log('[react16] props from main framework', props);
render(props);
}
export async function unmount(props) {
const {
container } = props;
ReactDOM.unmountComponentAtNode(container ? container.querySelector('#root') : document.querySelector('#root'));
}
备注
注意点
容器名
- 修改
index.html中项目初始化容器的根 id,不要使用#app或#root,避免与其他的项目冲突,建议换成项目name的驼峰写法微应用建议使用
history路由模式。路由模式为
history时,同时需要设置路由base,值和它的activeRule是一样的:
vue:
router = new VueRouter({ mode: 'history', base: window.__POWERED_BY_QIANKUN__ ? '/app-vue/' : '/', });react:
<BrowserRouter basename={window.__POWERED_BY_QIANKUN__ ? '/app-react' : '/'}>
3、构建工具配置
微应用分为有 webpack 构建和无 webpack 构建项目。
注意
qiankun v2 及以下版本只支持webpack,并不支持vite!!!
下面以 webpack 为构建工具的微应用为例(主要是指 Vue、React)的配置说明
配置点说明
构建工具的配置主要有两个:
- 允许跨域
- 打包成
umd格式
为什么要打包成 umd 格式呢?是为了让 qiankun 拿到其 export 的生命周期函数。我们可以看下其打包后的 app.js 就知道了:

配置示例
微应用的打包工具需要增加如下配置:
react
修改 webpack 配置
安装插件 @rescripts/cli,当然也可以选择其他的插件,例如 react-app-rewired。
npm i -D @rescripts/cli
根目录新增 .rescriptsrc.js:
// webpack
const {
name } = require('./package');
module.exports = {
webpack: (config) => {
config.output.library = `${
name}-[name]`;
config.output.libraryTarget = 'umd';
// webpack 5 需要把 jsonpFunction 替换成 chunkLoadingGlobal
config.output.jsonpFunction = `webpackJsonp_${
name}`;
config.output.globalObject = 'window';
return config;
},
devServer: (_) => {
const config = _;
config.headers = {
'Access-Control-Allow-Origin': '*',
};
config.historyApiFallback = true;
config.hot = false;
config.watchContentBase = false;
config.liveReload = false;
return config;
},
};
修改 package.json:
- "start": "react-scripts start",
+ "start": "rescripts start",
- "build": "react-scripts build",
+ "build": "rescripts build",
- "test": "react-scripts test",
+ "test": "rescripts test",
- "eject": "react-scripts eject"
vue
// vue.config.js
const {
name } = require('./package');
module.exports = {
devServer: {
headers: {
'Access-Control-Allow-Credentials': true,
'Access-Control-Allow-Origin': req.headers.origin || '*',
'Access-Control-Allow-Headers': 'X-Requested-With,Content-Type',
'Access-Control-Allow-Methods': 'PUT,POST,GET,DELETE,OPTIONS',
'Content-Type': 'application/json; charset=utf-8',
},
},
// 自定义webpack配置
configureWebpack: {
output: {
library: `${
name}-[name]`, // 微应用的包名,这里与主应用中注册的微应用名称一致
libraryTarget: 'umd', // 把微应用打包成 umd 库格式,可以在 AMD 或 CommonJS 的 require 访问。
// webpack 5 需要把 jsonpFunction 替换成 chunkLoadingGlobal
jsonpFunction: `webpackJsonp_${
name}`, // webpack 用来异步加载 chunk 的 JSONP 函数。
},
},
};
注意
这个
name默认从package.json获取,可以自定义,只要和父项目注册时的name保持一致即可。qiankun拿这三个生命周期,是根据注册应用时,你给的name值,name不一致则会导致拿不到生命周期函数。
webpack 不同版本的配置
webpack v5:
const packageName = require('./package.json').name;
module.exports = {
output: {
library: `${
packageName}-[name]`,
libraryTarget: 'umd',
chunkLoadingGlobal: `webpackJsonp_${
packageName}`,
},
};
webpack v4:
const packageName = require('./package.json').name;
module.exports = {
output: {
library: `${
packageName}-[name]`,
libraryTarget: 'umd',
// webpack 5 需要把 jsonpFunction 替换成 chunkLoadingGlobal
jsonpFunction: `webpackJsonp_${
packageName}`,
},
};
备注
更多相关配置介绍可以查看 webpack 相关文档
子项目开发的一些注意事项
js 相关
给 body 、 document 等绑定的事件,请在 unmount 周期清除
js 沙箱只劫持了 window.addEventListener,而使用了 document.body.addEventListener 或者 document.body.onClick 添加的事件并不会被沙箱移除,会对其他的页面产生影响,因此请在 unmount 生命周期清除绑定的事件。
css 相关
避免 css 污染
组件内样式的 css-scoped 是必须的。
对于一些插入到 body 的弹窗,无法使用 scoped,请不要直接使用原 class 修改样式,请添加自己的 class,来修改样式。
.el-dialog {
/* 不推荐使用组件原有的class */
}
.my-el-dialog {
/* 推荐使用自定义组件的class */
}
谨慎使用 position:fixed
在父项目中,浮动定位未必准确,应尽量避免使用,确有相对于浏览器窗口定位需求,可以用 position: sticky,但是会有兼容性问题(IE 不支持)。如果定位使用的是 bottom 和 right,则问题不大。
还有个办法,位置可以写成动态绑定 style 的形式:
<div :style="{ top: isQiankun ? '10px' : '0'}"></div>
静态资源 相关
所有的资源(图片/音视频等)都应该放到 src 目录下,不要放在 public 或者 static
资源放 src 目录,会经过 webpack 处理,能统一注入 publicPath。否则在主项目中会 404。
参考:vue-cli3 的官方文档介绍:何时使用-public-文件夹
第三方库 相关
请给 axios 实例添加拦截器,而不是 axios 对象
后续会考虑子项目共享公共插件,这时就需要避免公共插件的污染
// 正确做法:给 axios 实例添加拦截器
const instance = axios.create();
instance.interceptors.request.use(function () {
// ...
});
// 错误用法:直接给 axios 对象添加拦截器
axios.interceptors.request.use(function () {
// ...
});
qiankun 功能介绍
运行模式
乾坤只有一种运行模式:单例模式
在微前端框架中,子应用会随着主应用页面的打开和关闭反复的激活和销毁(单例模式:生命周期模式)。
单例模式
子应用页面如果切走,会调用 unmount 销毁子应用当前实例,子应用页面如果切换回来,会调用 mount 渲染子应用新的实例。
在单例式下,改变 url 子应用的路由会发生跳转到对应路由。
生命周期
微应用需要在应用的入口文件导出 bootstrap、mount、unmount、update 四个生命周期钩子,以供主应用在适当的时机调用。
注意
💡 qiankun 生命周期函数都必须要
export暴露
💡 qiankun 生命周期函数都必须是Promise函数,使用async会返回一个 Promise 对象
/**
* bootstrap 只会在微应用初始化的时候调用一次,下次微应用重新进入时会直接调用 mount 钩子,不会再重复触发 bootstrap。
* 通常我们可以在这里做一些全局变量的初始化,比如不会在 unmount 阶段被销毁的应用级别的缓存等。
*/
export async function bootstrap() {
console.log('app bootstraped');
}
/**
* 应用每次进入都会调用 mount 方法,通常我们在这里触发应用的渲染方法
*/
export async function mount(props) {
// ReactDOM.render(<App />, props.container ? props.container.querySelector('#root') : document.getElementById('root'));
console.log('app mount');
}
/**
* 应用每次 切出/卸载 会调用的方法,通常在这里我们会卸载微应用的应用实例
*/
export async function unmount(props) {
// ReactDOM.unmountComponentAtNode(props.container ? props.container.querySelector('#root') : document.getElementById('root'));
console.log('app unmount');
}
/**
* 可选生命周期钩子,仅使用 loadMicroApp 方式加载微应用时生效
*/
export async function update(props) {
console.log('update props', props);
}
通讯方式
项目之间的不要有太多的数据依赖,毕竟项目还是要独立运行的。通信操作需要判断是否 qiankun 模式,做兼容处理。
props 通信
如果父子应用都是vue项目,通过 props 传递父项目的 Vuex store,可以实现响应式;但假如子项目是不同的技术栈(jQuery/react/angular),这是就不能很好的监听到数据的变化了。
注意
vue 项目之间数据传递还是使用共享父组件的
Vuex比较方便,与其他技术栈的项目之间的通信使用 qiankun 提供的initGlobalState。
通过 vuex/pinia 实现通信
第一步:在主应用中创建一个 store
// src/store/index.ts
const personModule = {
state: {
id: 0,
name: '',
age: 0,
},
mutations: {
setId(state: Object, id: number) {
state.id = id;
},
setName(state: Object, name: string) {
state.name = name;
},
setAge(state: Object, age: number) {
state.age = age;
},
},
actions: {
setId(context: Object, id: number) {
context.commit('setId', id);
},
setName(context: Object, name: string) {
context.commit('setName', name);
},
setAge(context: Object, age: number
2025开年,AI技术打得火热,正在改变前端人的职业命运:
阿里云核心业务全部接入Agent体系;
字节跳动30%前端岗位要求大模型开发能力;
腾讯、京东、百度开放招聘技术岗,80%与AI相关……
大模型正在重构技术开发范式,传统CRUD开发模式正在被AI原生应用取代!
最残忍的是,业务面临转型,领导要求用RAG优化知识库检索,你不会;带AI团队,微调大模型要准备多少数据,你不懂;想转型大模型应用开发工程师等相关岗,没项目实操经验……这不是技术焦虑,而是职业生存危机!
曾经React、Vue等热门的开发框架,已不再是就业的金钥匙。如果认为会调用API就是懂大模型、能进行二次开发,那就大错特错了。制造、医疗、金融等各行业都在加速AI应用落地,未来企业更看重能用AI大模型技术重构业务流的技术人。
如今技术圈降薪裁员频频爆发,传统岗位大批缩水,相反AI相关技术岗疯狂扩招,薪资逆势上涨150%,大厂老板们甚至开出70-100W年薪,挖掘AI大模型人才!

不出1年 “有AI项目开发经验”或将成为前端人投递简历的门槛。
风口之下,与其像“温水煮青蛙”一样坐等被行业淘汰,不如先人一步,掌握AI大模型原理+应用技术+项目实操经验,“顺风”翻盘!
大模型目前在人工智能领域可以说正处于一种“炙手可热”的状态,吸引了很多人的关注和兴趣,也有很多新人小白想要学习入门大模型,那么,如何入门大模型呢?
下面给大家分享一份2025最新版的大模型学习路线,帮助新人小白更系统、更快速的学习大模型!
2025最新版优快云大礼包:《AGI大模型学习资源包》免费分享**
一、2025最新大模型学习路线
一个明确的学习路线可以帮助新人了解从哪里开始,按照什么顺序学习,以及需要掌握哪些知识点。大模型领域涉及的知识点非常广泛,没有明确的学习路线可能会导致新人感到迷茫,不知道应该专注于哪些内容。
我们把学习路线分成L1到L4四个阶段,一步步带你从入门到进阶,从理论到实战。

L1级别:AI大模型时代的华丽登场
L1阶段:我们会去了解大模型的基础知识,以及大模型在各个行业的应用和分析;学习理解大模型的核心原理,关键技术,以及大模型应用场景;通过理论原理结合多个项目实战,从提示工程基础到提示工程进阶,掌握Prompt提示工程。

L2级别:AI大模型RAG应用开发工程
L2阶段是我们的AI大模型RAG应用开发工程,我们会去学习RAG检索增强生成:包括Naive RAG、Advanced-RAG以及RAG性能评估,还有GraphRAG在内的多个RAG热门项目的分析。

L3级别:大模型Agent应用架构进阶实践
L3阶段:大模型Agent应用架构进阶实现,我们会去学习LangChain、 LIamaIndex框架,也会学习到AutoGPT、 MetaGPT等多Agent系统,打造我们自己的Agent智能体;同时还可以学习到包括Coze、Dify在内的可视化工具的使用。

L4级别:大模型微调与私有化部署
L4阶段:大模型的微调和私有化部署,我们会更加深入的探讨Transformer架构,学习大模型的微调技术,利用DeepSpeed、Lamam Factory等工具快速进行模型微调;并通过Ollama、vLLM等推理部署框架,实现模型的快速部署。

整个大模型学习路线L1主要是对大模型的理论基础、生态以及提示词他的一个学习掌握;而L3 L4更多的是通过项目实战来掌握大模型的应用开发,针对以上大模型的学习路线我们也整理了对应的学习视频教程,和配套的学习资料。
二、大模型经典PDF书籍
书籍和学习文档资料是学习大模型过程中必不可少的,我们精选了一系列深入探讨大模型技术的书籍和学习文档,它们由领域内的顶尖专家撰写,内容全面、深入、详尽,为你学习大模型提供坚实的理论基础。(书籍含电子版PDF)

三、大模型视频教程
对于很多自学或者没有基础的同学来说,书籍这些纯文字类的学习教材会觉得比较晦涩难以理解,因此,我们提供了丰富的大模型视频教程,以动态、形象的方式展示技术概念,帮助你更快、更轻松地掌握核心知识。

四、大模型项目实战
学以致用 ,当你的理论知识积累到一定程度,就需要通过项目实战,在实际操作中检验和巩固你所学到的知识,同时为你找工作和职业发展打下坚实的基础。

五、大模型面试题
面试不仅是技术的较量,更需要充分的准备。
在你已经掌握了大模型技术之后,就需要开始准备面试,我们将提供精心整理的大模型面试题库,涵盖当前面试中可能遇到的各种技术问题,让你在面试中游刃有余。

因篇幅有限,仅展示部分资料,需要点击下方链接即可前往获取

840

被折叠的 条评论
为什么被折叠?



