一、微前端是什么?——大厨与餐馆的故事
在一个繁忙的城市里,有一家名叫“全能餐厅”的餐馆。餐厅的老板是个了不起的大厨,擅长烹饪各种美食:中餐、西餐、甜点,应有尽有。然而,随着顾客的增加,大厨发现自己无法一人应付所有的菜品。他决定雇佣不同的厨师,每个人专门负责一种菜系。这样,餐厅不仅能提供更多美食,而且每位厨师都能专注于自己的拿手菜,餐厅的效率也提升了。
这就是微前端的核心理念——将一个庞大的前端应用拆分成若干独立的子应用,每个子应用就像是一个专注的厨师,负责自己那一部分的业务。主应用就像是“全能餐厅”的大厨,负责协调和管理这些子应用,确保它们可以顺利地为顾客服务。
二、Qiankun:微前端的魔法师
在微前端的世界里,我们有一个强大的助手——Qiankun。想象一下,Qiankun 就像是一个拥有神奇魔法的厨师助手,它可以帮助你轻松管理这些独立的子应用,让它们像魔法般无缝地融入到主应用中。
Qiankun 的魔法特性:
- 简单易用:Qiankun 的 API 就像是魔法秘籍,只需要几行代码,就能让你的子应用像魔法般被主应用加载进来。
- 沙箱隔离:Qiankun 会把每个子应用放在一个独立的沙盒里,防止它们之间互相干扰。就像是在厨房里,每个厨师都有自己的工作台,互不打扰。
- 生命周期管理:Qiankun 让你可以控制每个子应用的“出生、成长、离开”,你可以精确地控制它们什么时候加载、什么时候卸载,确保一切都井井有条。
三、如何用 Qiankun 搭建第一个微前端应用?
3.1 项目准备——开设“全能餐厅”
首先,我们需要开设我们的“全能餐厅”,也就是主应用,并准备好两个子应用,分别是“中餐厨师”和“西餐厨师”。
1. 创建主应用
我们用 Vue CLI 创建一个主应用,就像开设了一家全能餐厅:
vue create main-app
然后,安装 Qiankun,就像请了一位魔法助手来帮助我们:
npm install qiankun
2. 创建子应用
创建两个子应用,分别是“中餐厨师”和“西餐厨师”。可以选择 Vue 或 React 来创建这两个子应用:
vue create sub-app-vue
npx create-react-app sub-app-react
3.2 主应用中集成 Qiankun——邀请厨师进厨房
在主应用中,我们需要通过 Qiankun 来注册和启动这些子应用。我们把 Qiankun 作为魔法助手,让它来安排这些子应用的“上菜”:
import { registerMicroApps, start } from 'qiankun';
// 注册子应用
registerMicroApps([
{
name: 'sub-app-vue', // 子应用的名字
entry: '//localhost:7100', // 子应用的入口地址
container: '#subapp-container', // 子应用的挂载容器
activeRule: '/vue', // 子应用的激活规则
},
{
name: 'sub-app-react',
entry: '//localhost:7200',
container: '#subapp-container',
activeRule: '/react',
},
]);
// 启动 Qiankun
start();
在主应用的 App.vue
中添加子应用的挂载容器,就像是给厨房准备好专门的工作台:
<template>
<div id="app">
<router-view></router-view>
<div id="subapp-container"></div> <!-- 子应用的挂载容器 -->
</div>
</template>
3.3 子应用配置——每个厨师的工作台
Vue 子应用配置
在 Vue 子应用中,我们需要配置公共路径和生命周期钩子,让它能够被主应用顺利调用:
在 sub-app-vue
中修改 main.js
文件:
import './public-path'; // 引入 public-path 文件
import { createApp } from 'vue';
import App from './App.vue';
import router from './router';
let instance = null;
function render() {
instance = createApp(App);
instance.use(router);
instance.mount('#app');
}
// 微前端生命周期钩子
export async function bootstrap() {
console.log('Vue app bootstraped');
}
export async function mount(props) {
console.log('Vue app mounted');
render();
}
export async function unmount() {
instance.unmount();
instance = null;
}
在 public-path.js
中动态设置资源路径:
if (window.__POWERED_BY_QIANKUN__) {
__webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;
}
React 子应用配置
在 React 子应用中,也需要类似的配置:
在 sub-app-react/src/index.js
中添加:
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
function render() {
ReactDOM.render(<App />, document.getElementById('root'));
}
if (!window.__POWERED_BY_QIANKUN__) {
render();
}
// 微前端生命周期钩子
export async function bootstrap() {
console.log('React app bootstraped');
}
export async function mount() {
render();
}
export async function unmount() {
ReactDOM.unmountComponentAtNode(document.getElementById('root'));
}
四、项目运行——欢迎光临“全能餐厅”
主应用将运行在 http://localhost:8080
,子应用分别运行在 http://localhost:7100
和 http://localhost:7200
。启动所有应用后,访问 /vue
或 /react
路径,子应用将自动加载并显示在主应用中,就像在餐厅里点了一道美味的菜肴。
五、常见踩坑与注意事项——厨师们的常见小误区
- 子应用的路由冲突
想象一下,两个厨师在同一个工作台上切菜,难免会互相干扰。子应用的路由需要与主应用解耦,建议子应用的路由使用hash
模式,避免路由冲突。 - 跨域问题
主应用和子应用部署在不同域名或端口下,可能会遇到跨域问题。需要在子应用的服务器配置 CORS,就像是在餐厅里处理不同餐桌的订餐问题。 - 资源路径问题
子应用加载静态资源时,必须确保资源路径正确。建议使用相对路径或配置public-path.js
来确保资源路径正确,就像确保每个厨师在自己工作台上有足够的工具。 - 样式隔离
主应用与子应用的样式可能会发生冲突。推荐使用shadow DOM
来进行样式隔离,避免样式的相互污染。
六、总结——微前端探险的开始
作为一起探索的小伙伴,希望我的理解没有什么误差,如果有,一定要记得call我一下,以免误人子弟。
在微前端的概念和 Qiankun 的基本使用上,Qiankun 让我们能够轻松管理不同的子应用,让它们像魔法般顺利地融合在主应用中。下一篇文章我们将深入探讨如何管理多个子应用,提升微前端项目的实战技巧。