阅读 320
微前端 qiankun 入门

微前端 qiankun 入门

小知识,大挑战!本文正在参与「程序员必备小知识」创作活动

本文已参与 「掘力星计划」 ,赢取创作大礼包,挑战创作激励金。

【序】微前端是什么?

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

微前端核心

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

微前端解决了什么

微前端架构旨在解决单体应用在一个相对长的时间跨度下,由于参与的人员、团队的增多、变迁,从一个普通应用演变成一个巨石应用后,随之而来的应用不可维护的问题。这类问题在企业级 Web 应用中尤其常见。

一、了解微前端方案之 qiankun

qiankun.umijs.org/zh

qiankun 是什么?

qiankun 是一个基于 single-spa 的微前端实现库,旨在帮助大家能更简单、无痛的构建一个生产可用微前端架构系统。

特点

  1. 简单:任意 js 框架均可使用。微应用接入像使用接入一个 iframe 系统一样简单,但实际不是 iframe。
  2. 完备:几乎包含所有构建微前端系统时所需要的基本能力,如样式隔离、js 沙箱、预加载等等。
  1. 生产可用:已在蚂蚁内外经受过足够大量的线上系统的考验及打磨,健壮性值得信赖。

特性

  • 基于 single-spa
  • 技术栈无关
  • HTML Entry 接入方式
  • 样式隔离
  • JS 沙箱
  • 资源预加载
  • umi 插件系统

安装 qiankun

npm i qiankun -S

二、开始搭建微前端项目

1. 项目环境搭建

  1. 先创建一个 vue2.0 项目作为基座

vue create qiankun-base

  1. 然后创建一个 vue2.0 项目作为子项目1

vue create qiankun-vue

  1. 再创建一个 react 项目作为子项目2

npx create-react-app qiankun-react

  1. 在 qiankun-base 目录下安装 element-ui 作为项目 ui

npm i element-ui -S

2. 配置主应用 qiankun-base

  1. 配置导航栏

引入 element 样式后使用其菜单栏,并配置相应路由。

<!-- app.vue 页面 -->
<template>
  <div>
    <!-- 使用 element 菜单栏 -->
    <el-menu :router="true" mode="horizontal">
      <!-- 基座中可以放自己的路由 -->
      <el-menu-item index="/">Home</el-menu-item>
      <!-- 也可以引用其它子应用 -->
      <el-menu-item index="/vue">vue 应用</el-menu-item>
      <el-menu-item index="/react">react 应用</el-menu-item>
    </el-menu>
    <!-- 页面渲染 -->
    <router-view></router-view>
    <div id="vue"></div>
    <div id="react"></div>
  </div>
</template>
复制代码

页面效果

  1. 引入并配置 qiankun

安装好 qiankun 后再 main.js 中进行配置子应用

// 引入 qiankun
import { registerMicroApps, start } from 'qiankun'
// 配置子应用
const apps = [
  // 子应用1:qiankun-vue
  {
    // 子应用名称
    name: 'vueAPP',
    // 子应用入口;默认会加载这个 html 
    // 并解析里里面的 js 然后动态的执行(子应用必须支持跨域)
    entry: '//localhost:1001',
    // 将子应用挂载到 #vue 元素上
    container: '#vue',
    // 激活规则:访问 /vue 时将子应用挂载到 #vue 上
    activeRule: '/vue'
  },
  // 子应用2:qiankun-react
  {
    // 子应用名称
    name: 'reactAPP',
    // 子应用入口;默认会加载这个 html 
    // 并解析里里面的 js 然后动态的执行(子应用必须支持跨域)
    entry: '//localhost:1002',
    // 将子应用挂载到 #react 元素上
    container: '#react',
    // 激活规则:访问 /react 时将子应用挂载到 #react 上
    activeRule: '/react'
  }
]
// 注册子应用
registerMicroApps(apps)
// 启动 qiankun 微前端
start()
复制代码

3. 配置子应用1 qiankun-vue

这里需要注意,在配置子应用时是不需要再去额外安装任何包了,qiankun 内部已经自动处理好了。我们子需要进行配置就成。

  1. router 配置

  1. main.js 配置
// 存放子应用渲染状态
let instance = null;
// 子应用正常渲染
function render() {
  instance = new Vue({
    router,
    render: (h) => h(App),
  }).$mount("#app"); // 挂载到自己的 html 中,然后基座会拿到这个挂在后的 html,并将其插入到主应用当中
}

// 判断当前应用是否不在 qiankun 中渲染
if (!window.__POWERED_BY_QIANKUN__) {
  // 如果不在 qiankun 中,则直接渲染
  render();
}

// 需要导出 qiankun 内部的三个生命周期钩子,以供主应用在合适的时机调用。
// 第一次进入时;props 包含主应用传递的参数,也包括为子应用创建的节点信息。
export async function bootstrap() {
  console.log("微前端加载完成");
}

// 每次进入子应用时
export async function mount(props) {
  // 每次进入子应用,渲染子应用
  render(props);
}

// 每次退出子应用时
export async function unmount() {
  // 卸载子应用
  instance.$destroy();
}
复制代码
  1. vue.config.js 配置打包环境

新建 vue.config.js 文件进行配置

module.exports = {
    // 配置跨域
    devServer: {
        // 监听端口
        port: 1000,
        // 配置头信息
        headers:{
            // 设置任何网站域名都可以访问此项目
            'Access-Control-Allow-Origin' : '*'
        }
    },
    // 配置打包结果
    configureWebpack:{
        output: {
            library: 'vueApp',
            libraryTarget: 'umd'
        }
    }
}
复制代码
  1. 效果

4. 配置子应用2 qiankun-react

  1. 安装 react-app-rewired

// 得先安装 yarn

npm i yarn -g

// 再安装 react-app-rewired

yarn add react-app-rewired

  1. 安装好后将启动项都改为 react-app-rewired

  1. 新建 config-overrides.js 配置文件
module.exports = {
    webpack:(config) => {
        config.output.library = 'reactApp'
        config.output.libraryTarget = 'umd'
        config.output.publicPath = 'http://localhost:1002'
        return config
    },
    devServer:(configFunction) => {
        return function(proxy, allowedHost){
            const config = configFunction(proxy, allowedHost)
            config.port = '1002'
            config.headers = {
                "Access-Control-Allow-Origin" : '*'
            }
            return config
        }
    }
}
复制代码
  1. 配置 indx.js
import React from "react";
import ReactDOM from "react-dom";
import "./index.css";
import App from "./App";

function render() {
  ReactDOM.render(
    <React.StrictMode>
      <App />
    </React.StrictMode>,
    document.getElementById("root")
  );
}

if (!window.__POWERED_BY_QIANKUN__) {
  render();
}

// 导出三个声明周期
export async function bootstrap() {}

export async function mount() {
  render();
}

export async function unmount() {
  ReactDOM.unmountComponentAtNode(document.getElementById("root"));
}
复制代码
  1. 效果

三、报错合集

1. qiankun:application ‘vueApp‘ died in status NOT_MOUNTED: [qiankun]: Target container with #vue not

vue2 中将最外层的

改为

vue3 中直接将最外层的 div 删除即可

2.'webpack_public_path' is not defined no-undef

不知道为什么会出现这个 BUG,我看其他教程文章都不会出现,不知道有没有人和我一样遇上了这个 BUG。

文章分类
前端
文章标签