首页 > 其他分享 >qiankun方案

qiankun方案

时间:2023-02-17 15:24:55浏览次数:24  
标签:方案 vue js qiankun 子项目 entry css

qiankun 方案

qiankun 是蚂蚁金服开源的一款框架,它是基于 single-spa 的。他在 single-spa 的基础上,实现了开箱即用,除一些必要的修改外,子项目只需要做很少的改动,就能很容易的接入。如果说 single-spa 是自行车的话,qiankun 就是个汽车。

微前端中子项目的入口文件常见的有两种方式:JS entry 和 HTML entry
纯 single-spa 采用的是 JS entry,而 qiankun 既支持 JS entry,又支持 HTML entry。

JS entry 的要求比较苛刻:

  1. 将 css 打包到 js 里面
  2. 去掉 chunk-vendors.js,
  3. 去掉文件名的 hash 值
  4. 将 single-spa 模式的入口文件( app.js )放置到 index.html 目录,其他文件不变,原因是要截取 app.js 的路径作为 publicPath

APP entry 优点 缺点 JS entry 可以配合 systemJs,按需加载公共依赖( vue , vuex , vue-router 等) 需要各种打包配置配合,无法实现预加载 HTML entry 打包配置无需做太多的修改,可以预加载 多一层请求,需要先请求到 HTML 文件,再用正则匹配到其中的 js 和 css

其实 qiankun 还支持 config entry :

{
   entry: {
        scripts: [
          "app.3249afbe.js"
          "chunk-vendors.75fba470.js",
        ],
        styles: [
          "app.3249afbe.css"
          "chunk.75fba470.css",
        ],
        html: http://localhost:5000
    }
}

建议使用 HTML entry ,使用起来和 iframe 一样简单,但是用户体验比 iframe 强很多。qiankun 请求到子项目的 index.html 之后,会先用正则匹配到其中的 js/css 相关标签,然后替换掉,它需要自己加载 js 并运行,然后去掉 html/head/body 等标签,剩下的内容原样插入到子项目的容器中 :

使用 qiankun 的好处:
qiankun 自带 js/css 沙箱功能,singles-spa 可以解决 css 污染,但是需要子项目配合
single-spa 方案只支持 JS entry 的特点,限制了它只能支持 vue 、 react 、 angular 等技术开发的项目,对一些 jQuery 老项目则无能为力。qiankun 则没有限制
qiankun 支持子项目预请求功能。

js 沙箱

js/css 污染是无法避免的,并且是一个可大可小的问题。就像一颗定时炸弹,不知道什么时候会出问题,排查也麻烦。作为一个基础框架,解决这两个污染非常重要,不能仅凭“规范”开发。

js 沙箱的原理是子项目加载之前,对 window 对象做一个快照,子项目卸载时恢复这个快照,如图:

那么如何监测 window 对象的变化呢,直接将 window 对象进行一下深拷贝,然后深度对比各个属性显然可行性不高,qiankun 框架采用的是 ES6 新特性,proxy 代理方法。

但是 proxy 是不兼容 IE11 的,为了兼容,低版本 IE 采用了 diff 方法:浅拷贝 window 对象,然后对比每一个属性。

css 沙箱

qiankun 的 css 沙箱的原理是重写 HTMLHeadElement.prototype.appendChild 事件,记录子项目运行时新增的 style/link 标签,卸载子项目时移除这些标签。

single-spa 方案中用了换肤的思路来解决 css 污染:首先 css-scoped 解决大部分的污染,对于一些全局样式,在子项目给 body/html 加一个唯一的 id/class(正常开发部署用),然后这个全局的样式前面加上这个 id/class,而 single-spa 模式则在 mount 周期给 body/html 加上这个唯一的 id/class,在 unmount 周期去掉,这样就可以保证这个全局 css 只对这个项目生效了。

这两个方案的致命点都在于无法解决多个子项目同时运行时的 css 污染,以及子项目对主项目的 css 污染。

虽然说两个项目同时运行常见并不常见,但是如果想实现 keep-alive ,就需要使用 display: none 将子项目隐藏起来,子项目不需要卸载,这时候就会存在两个子项目同时运行,只不过其中一个对用户不可见。

css 沙箱还有个思路就是将子项目的样式局限到子项目的容器范围内生效,这样只需要给不同的子项目不同的容器就可以了。但是这样也会有新的问题,子项目中 append 到 body 的弹窗,样式就无法生效。所以说样式污染还需要制定规范才行,约定 class 命名前缀。

微前端方案实践

改造已有的项目为 qiankun 子项目,由于是 vue 技术栈,所以就以改造一个 vue 项目为例说明,其他的技术栈原理是一样的。

  1. 在 src 目录新增文件 public-path.js:
if (window.__POWERED_BY_QIANKUN__) {
  __webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;
}
  1. 修改 index.html 中项目初始化的容器,不要使用 #app ,避免与其他的项目冲突,建议换成项目 name 的驼峰写法
  2. 修改入口文件 main.js:
import ./public-path;
import Vue from vue
import App from ./App.vue
import VueRouter from vue-router
import store from ./store;

Vue.use(VueRouter)
Vue.config.productionTip = false

let router = null;
let instance = null;
function render(parent = {}) {
  const router = new VueRouter({
    // histroy模式的路由需要设置base,app-history-vue根据项目名称来定
    base: window.__POWERED_BY_QIANKUN__ ? /app-history-vue : /,
    mode: history,
    // hash模式不需要上面两行
    routes: []
  })
  instance = new Vue({
    router,
    store,
    render: h => h(App),
    data(){
      return {
        parentRouter: parent.router,
        parentVuex: parent.store,
      }
    },
  }).$mount(#appVueHistory);
}
//全局变量来判断环境,独立运行时
if (!window.__POWERED_BY_QIANKUN__) {
  render();
}

export async function bootstrap() {
  console.log(vue app bootstraped);
}
export async function mount(props) {
  console.log(props from main framework, props);
  render(props.data);
}
export async function unmount() {
  instance.$destroy();
  instance = null;
  router = null;
}

主要改动是引入修改 publicPath 的文件和 export 三个生命周期。

注意:
webpack 的 publicPath 值只能在入口文件修改,之所以单独写到一个文件并在入口文件最开始引入,是因为这样做可以让下面所有的代码都能使用这个。 路由文件需要 export 路由数据,而不是实例化的路由对象,路由的钩子函数也需要移到入口文件。 在 mount 生命周期,可以拿到父项目传递过来的数据,router 用于跳转到主项目/其他子项目的路由,store 是父项目的实例化的 Vuex。

  1. 修改打包配置 vue.config.js:
const { name } = require(./package);

module.exports = {
  devServer: {
    headers: {
      Access-Control-Allow-Origin: *,
    },
  },
  // 自定义webpack配置
  configureWebpack: {
    output: {
      library: `${name}-[name]`,
      libraryTarget: umd,// 把子应用打包成 umd 库格式
      jsonpFunction: `webpackJsonp_${name}`,
    },
  },
};

注: 这个 name 默认从 package.json 获取,可以自定义,只要和父项目注册时的 name 保持一致即可。

这个配置主要就两个,一个是允许跨域,另一个是打包成 umd 格式。为什么要打包成 umd 格式呢?是为了让 qiankun 拿到其 export 的生命周期函数。可以看下其打包后的 app.js 就知道了:

root 在浏览器环境就是 window , qiankun 拿这三个生命周期,是根据注册应用时,你给的 name 值,name 不一致则会导致拿不到生命周期函数

标签:方案,vue,js,qiankun,子项目,entry,css
From: https://www.cnblogs.com/wp-leonard/p/17130250.html

相关文章

  • vue基于微前端qiankun的多页签缓存方案实践
    一、多页签是什么?常见的浏览器多页签、编辑器多页签,从产品角度来说,就是为了能够实现用户访问可记录,快速定位工作区等作用;那对于单页应用,可以通过实现多页签,对用户的访问记......
  • 微前端之qiankun 分别引入两种子应用 -- react && vue + vite
    搭建主应用主应用不限技术栈,只需要提供一个容器DOM,然后注册微应用并start即可。1、下载项目//TSnpxcreate-react-appqk-main--templatetypescript//JSnpxc......
  • BigQuery 如何帮助大规模交付业务型企业提供物联网解决方案
    ​(介绍:​​Leverege​​是一家软件公司,它使全球市场领导者能够快速且经济高效地构建企业物联网应用程序,以提供以数据为中心的决策能力、优化运营、改善客户体验、交付客户价......
  • BigQuery 如何帮助大规模交付业务型企业提供物联网解决方案
     【本文由CloudAce整理发布,CloudAce--谷歌云全球战略合作伙伴】(介绍:Leverege是一家软件公司,它使全球市场领导者能够快速且经济高效地构建企业物联网应用程序,以提供以......
  • 浅析35kV变电站综合自动化的改造方案
    罗轩志安科瑞电气股份有限公司上海嘉定201801 摘要:35kV变电站微机综合自动化系统的改造,对于实现电网调度自动化和现场运行管理现代化,提高电网的安全和经济运行水平起到......
  • 浅述综合管廊供配电系统设计方案
    罗轩志安科瑞电气股份有限公司上海嘉定 201801 摘要:城市综合管廊的供配电系统设计多种多样,通过对综合管廊自用负荷的分析及安全运行的因素考虑,并结合综合管廊设计案例,......
  • 常见的个人博客搭建部署方案
    常见的个人博客搭建部署方案1.第三方平台使用现有的博客网站、论坛或社区。如博客园、csdn、开源中国、掘金、思否、知乎、简书、哔哩哔哩、慕课网手记、腾讯云社区、等......
  • 轻量化前端更新方案
    一句话介绍:它是可以一行命令将代码更新到服务器的脚本轻量级更新方案最开始源于掘金的文章,后来从零实现了一个更新脚本,并且已在是生产环境中进行使用很长时间,算是非常稳......
  • 由小见大!不规则造型按钮解决方案
    今天,有个群友在群里提问,使用CSS能否实现下述这个图形:emmm,中间这个酷似三次贝塞尔曲线的造型,使用CSS不太好实现。我的建议是切图实现,然而群友要求一定要用CSS实现。......
  • 一文总结当下常用的大型 transformer 效率优化方案
    前言本文是一篇综述性的博客,探讨总结当下常用的大型transformer效率优化方案。 本文转载自机器之心作者丨LilianWeng欢迎关注公众号CV技术指南,专注于计算机......