微前端(single-spa和qiankun)

一、概念性东西:

2018年single-spa诞生了,single-spa是一个用于前端微服务化的js前端解决方案(本身没有处理样式隔离,js执行隔离),实现了路由劫持和应用加载

2019年qiankun基于single-spa,提供了更加开箱即用的API(single-spa + sandbox + import-html-entry)做到了与技术栈无关、并且接入简单

总结:子应用可以独立构建,运行时动态加载,主子应用完全解耦,与技术栈无关,靠的是协议接入,子应用必须导出bootstrap、mount、unmount方法。

这不是iframe吗?

如果使用iframe,iframe中的子应用切换路由时用户刷新页面就尴尬了。

应用通信:

1、基于URL来进行数据传递,但是传递消息能力弱

2、基于CustomEvent实现通信

3、使用全局变量、Redux进行通信

公共依赖:

1、CDN - externals

2、webpack 联邦模块

二、single-spa实现例子:

1、先创建一个vue项目:vue create child-vue

2、在此项目中添加single-spa-vue:npm i single-spa-vue

      说明:如果是react项目则安装single-spa-react

3、修改main.js文件,导出bootstrap/mount/unmount:

import Vue from 'vue'
import App from './App.vue'
import router from './router'
import singleSpa from 'single-spa-vue';

Vue.config.productionTip = false

const appOptions = {
  el: '#vue', // 挂载到父应用中的id为vue的标签中
  router,
  render: h => h(App)
}
const vueLifeCycle = singleSpa({
  Vue,
  appOptions
})

// 如果是父应用引用我,就会有这个属性
if(window.singleSpaNavigate){
  __webpack_public_path__ = 'http://localhost:10000/'
}
// 如果不是父应用引用我
if(!window.singleSpaNavigate){
  delete appOptions.el;
  new Vue(appOptions).$mount('#app');
}

// 协议接入:我订好了协议,父应用会调用这些方法
export const bootstrap = vueLifeCycle.bootstrap;
export const mount = vueLifeCycle.mount;
export const unmount = vueLifeCycle.unmount;

// 我们需要父应用加载子应用,将子应用加载成一个个的lib给父应用使用
// 子应用需要导出 bootstrap mount unmount
// single-spa single-spa-vue single-spa-react

4、在根目录下添加vue.config.js,将此应用导出一个lib:

 module.exports = {
     configureWebpack: {
         output: {
             library: 'singleVue',
             libraryTarget: 'umd'
         },
         devServer: {
             port: 10000
         }
     }
 }

 // umd格式就是会把导出的内容挂载在window.singleVue.bootstrap/mount/unmount上面

5、修改router下面的index.js,让路由跳转的时候基于它自己,这样就不会和父应用冲突了:

const router = new VueRouter({
  mode: 'history',
  base: '/vue',
  routes
})

6、然后创建父应用:vue create parent-vue

7、在此应用中添加single-spa:npm i single-spa

8、修改App.vue:




9、修改main.js,动态去加载子应用:

import Vue from 'vue'
import App from './App.vue'
import router from './router'
import { registerApplication, start } from 'single-spa';
Vue.config.productionTip = false

async function loadScript(url){
  return new Promise((resolve, reject) => {
    let script = document.createElement('script');
    script.src = url;
    script.onload = resolve;
    script.onerror = reject;
    document.head.appendChild(script);
  })
}

registerApplication('myVueApp', 
  async () => {
    // 加载vue子模块
    console.log('加载')
    await loadScript('http://localhost:10000/js/chunk-vendors.js');
    await loadScript('http://localhost:10000/js/app.js');
    return window.singleVue;
  },
  location => location.pathname.startsWith('/vue') // 用户切换到/vue的路径下,我需要加载刚才定义的子应用
)

start();

new Vue({
  router,
  render: h => h(App)
}).$mount('#app')

三、git地址

自己实现的小demo

你可能感兴趣的:(JS小知识点,html5,html,css)