乾坤qiankun搭建前端微服务

本教程适合于qiankun新手,手把手教你搭建一个简单的本地前端微服务,附完整代码

一、什么是微前端

微前端是一种多个团队通过独立发布功能的方式来共同构建现代化 web 应用的技术手段及方法策略。

微前端架构核心价值:
  • 技术栈无关:主框架不限制接入应用的技术栈,微应用具备完全自主权
  • 独立开发、独立部署:微应用仓库独立,前后端可独立开发,部署完成后主框架自动完成同步更新
  • 增量升级:在面对各种复杂场景时,我们通常很难对一个已经存在的系统做全量的技术栈升级或重构,而微前端是一种非常好的实施渐进式重构的手段和策略
  • 独立运行时:每个微应用之间状态隔离,运行时状态不共享

二、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 应用一键切换成微前端架构系统。

三、代码演示

1、创建并配置主应用
  • 通过pnpm create vue@latest创建一个Vue3项目为主应用。
  • 安装qiankun:pnpm i qiankun -S
  • 注册微应用并启动
    打开src下的main.ts文件,注册微应用,代码如下,这里注册了两个子应用sub-vue、sub-react
javascript 复制代码
import { registerMicroApps, start } from 'qiankun'
// 注册微应用
registerMicroApps([
  {
    name: 'sub-vue', //子应用的名称
    entry: '//localhost:3001', //子项目启动后的地址
    container: '#container', //加载的容器
    activeRule: '/sub-vue' //匹配的路由
  },
  {
    name: 'sub-react',
    entry: '//localhost:3002',
    container: '#container',
    activeRule: '/sub-react'
  }
])
// 启动 qiankun
start()
2、创建并配置Vue子项目
  • 通过pnpm create vue@latest创建一个Vue3子应用。
  • 通过pnpm i vite-plugin-qiankun安装vite-plugin-qiankun依赖包。
  • 在vite.config.js文件中配置qiankun插件,
javascript 复制代码
import { fileURLToPath, URL } from 'node:url'
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import qiankun from 'vite-plugin-qiankun'

export default defineConfig({
  base: '/sub-vue',
  server: {
    port: 3001,
    cors: true,
    origin: 'http://localhost:3001'
  },
  plugins: [
    vue(),
    qiankun('sub-vue', { //配置qiankun插件
      useDevMode: true
    })
  ],
  resolve: {
    alias: {
      '@': fileURLToPath(new URL('./src', import.meta.url))
    }
  }
})
  • 修改main.ts
javascript 复制代码
import './assets/main.css'
import { createApp } from 'vue'
import { renderWithQiankun, qiankunWindow } from 'vite-plugin-qiankun/dist/helper'

import App from './App.vue'
import router from './router'

let app: any

if (!qiankunWindow.__POWERED_BY_QIANKUN__) {
  app = createApp(App)
  app.use(router)
  app.mount('#app')
} else {
  renderWithQiankun({
    mount(props) {
      app = createApp(App)
      app.use(createPinia())
      app.use(router)
      app.use(ElementPlus)
      app.mount(props.container?.querySelector('#app'))
    },
    bootstrap() {},
    update() {},
    unmount() {
      app?.unmount()
    }
  })
}
3、创建并配置React子项目
  • 在 src 目录新增 public-path.js文件
javascript 复制代码
if (window.__POWERED_BY_QIANKUN__) {
  __webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__
}
  • 修改入口文件src/index.js
javascript 复制代码
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import './public-path';

let root
function render(props) {
  const { container } = props
  const dom = container ? container.querySelector("#root") : document.getElementById('root')
  root = ReactDOM.createRoot(dom)
  root.render(
    <React.StrictMode>
      <App />
    </React.StrictMode>
  );
  reportWebVitals();
}
// 判断能否在qiankun环境下运行
if (!window.__POWERED_BY_QIANKUN__) {
  render({});
}

// 各个声明周期
// bootstrap 只会在微应用初始化的时候调用一次,下次微应用重新进入时会直接调用mount钩子
export async function bootstrap() {
  console.log('[react16] react app bootstraped');
}

// 应用每次进入都会调用mount方法,通常在这里出发渲染方法
export async function mount(props) {
  console.log('[react16] props from main framework', props);
  render(props);
}

// 应用每次切出、卸载会调用unmount方法,通过在这里卸载微应用实例
export async function unmount(props) {
  root.unmount()
}
  • 修改webpack配置
    1)为了不暴露所有的webpack配置,我们使用react-app-rewired工具包来进行修改。
javascript 复制代码
pnpm i react-app-rewired

2)修改package.json

javascript 复制代码
  "scripts": {
    "start": "set PORT=3002 && react-app-rewired start",
    "build": "react-app-rewired build",
    "test": "react-app-rewired test",
    "eject": "react-scripts eject"
  },

3)根目录新增 .rescriptsrc.js

javascript 复制代码
const { name } = require('./package');

module.exports = {
  webpack: (config) => {
    config.output.library = `${name}-[name]`;
    config.output.libraryTarget = 'umd';
    config.output.chunkLoadingGlobal = `webpackJsonp_${name}`;
    config.output.globalObject = 'window';

    return config;
  },
};

至此,所有的配置都已经完成,分别在本地启动主应用和子应用就可以实现一个简单的前端微服务了。

完整的代码可去GitHub上进行下载:源码下载

相关推荐
Apifox5 分钟前
如何在 Apifox 中通过 Runner 运行包含云端数据库连接配置的测试场景
前端·后端·ci/cd
麦麦大数据28 分钟前
neo4j+django+deepseek知识图谱学习系统对接前后端分离前端vue
vue.js·django·知识图谱·neo4j·deepseek·在线学习系统
树上有只程序猿32 分钟前
后端思维之高并发处理方案
前端
喵个咪41 分钟前
开箱即用的GO后台管理系统 Kratos Admin - 定时任务
后端·微服务·消息队列
庸俗今天不摸鱼1 小时前
【万字总结】前端全方位性能优化指南(十)——自适应优化系统、遗传算法调参、Service Worker智能降级方案
前端·性能优化·webassembly
黄毛火烧雪下1 小时前
React Context API 用于在组件树中共享全局状态
前端·javascript·react.js
Apifox1 小时前
如何在 Apifox 中通过 CLI 运行包含云端数据库连接配置的测试场景
前端·后端·程序员
一张假钞1 小时前
Firefox默认在新标签页打开收藏栏链接
前端·firefox
高达可以过山车不行1 小时前
Firefox账号同步书签不一致(火狐浏览器书签同步不一致)
前端·firefox
m0_593758101 小时前
firefox 136.0.4版本离线安装MarkDown插件
前端·firefox