乾坤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上进行下载:源码下载

相关推荐
桂月二二28 分钟前
探索前端开发中的 Web Vitals —— 提升用户体验的关键技术
前端·ux
沈梦研1 小时前
【Vscode】Vscode不能执行vue脚本的原因及解决方法
ide·vue.js·vscode
hunter2062062 小时前
ubuntu向一个pc主机通过web发送数据,pc端通过工具直接查看收到的数据
linux·前端·ubuntu
qzhqbb2 小时前
web服务器 网站部署的架构
服务器·前端·架构
刻刻帝的海角2 小时前
CSS 颜色
前端·css
轻口味2 小时前
Vue.js 组件之间的通信模式
vue.js
浪浪山小白兔3 小时前
HTML5 新表单属性详解
前端·html·html5
weixin_SAG3 小时前
第3天:阿里巴巴微服务解决方案概览
微服务·云原生·架构
lee5763 小时前
npm run dev 时直接打开Chrome浏览器
前端·chrome·npm
2401_897579653 小时前
AI赋能Flutter开发:ScriptEcho助你高效构建跨端应用
前端·人工智能·flutter