参考:https://www.bilibili.com/video/BV17V411r71A
搭建一个简单的 singleSpa demo (全程CV即可)
一、 创建主项目
这里我使用的vue,也可替换成react、angular
我这里创建的是master,可以是其他
> vue create parent-vue
1. 修改parent-vue中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)
});
}
// singleSpa 缺陷 不够灵活 不能动态加载js文件
// 样式不隔离 没有js沙箱的机制
registerApplication(
"myVueApp",
async () => {
console.log("加载模块");
await loadScript("http://localhost:10000/about.js");
await loadScript("http://localhost:10000/app.js")
return window.singleVue; // bootstrap mount unmount
},
// 用户切换到/vue的路径下,我需要加载刚才定义的子应用
(location) => location.pathname.startsWith("/vue")
);
start();
new Vue({
router,
render: (h) => h(App),
}).$mount("#app");
改完后,引用 single-spa
yarn add single-spa
registerApplication 注册应用
第一个参数,随便起,就是给子应用取个名字。
第二个参数,调人家加载的方法,必须得是promice方法。
第三个参数,什么时候激活子应用。上述代码即location的路径以‘/vue’开头时激活子应用。
第四个参数,可以传自定义属性,可以是方法,也可以是属性。用于实现父子同信。(非必传)
(会传给子组件的bootstap、mount 和 unmount)
第三个参数匹配成功后会执行第二个参数挂载的方法。并且方法返回值必须得有三个方法,分别是:bootstap、mount 和 unmount
2. 修改App.vue
<template>
<div id="app">
<router-link to="/vue">加载vue应用</router-link>
<!-- 子应用加载的位置 -->
<div id="vue"></div>
</div>
</template>
<style></style>
3. 修改router.js
export default new Router({
mode: 'history',
base:'/vue',
...
二、 创建子项目
这里我使用的vue,也可替换成react、angular
我这里创建的是master,可以是其他
> vue create child-vue
1. 修改child-vue中main.js
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import singleSpaVue from "single-spa-vue"
Vue.config.productionTip = false
// 替换 new Vue
const appOptions = {
el:"#vue",//挂载到父应用id为vue的标签中
router,
render:h=>h(App)
}
// vueLifeCycle 返回生命周期
const vueLifeCycle = singleSpaVue({
Vue,
appOptions
})
// 如果父应用引用,则
// 使子应用router的publicPath都相对于子应用本身,而不是父应用
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;
改完后,引用 single-spa-vue
yarn add single-spa-vue
如果是react可以引用 single-spa-react
yarn add single-spa-react
我们需要夫应用加载子应用,将子应用打包成一个个的lib去给父应用使用。
子应用就需要暴露三个接口。分别是
bootstap、mount 和 unmount。
singleSpaVue可以直接生成bootstap、mount 和 unmount。
2. 新建vue.config.js
module.exports={
configureWebpack:{
output:{
library:'singleVue',
libraryTarget:'umd'
},
devServer:{
port:10000
}
}
}
umd会把bootstap、mount 和 unmount都包到singleVue里挂在再window下,即
window.singleVue.bootstap / mount / unmount
三、 启项目
主程序与子程序都起下服务: npm run serve
访问: localhost:8080
如果有更漂亮的写法欢迎来讨论,让我们一起有条不紊的持续进步。
喜欢的话不妨点个小小的赞与关注,您的赞与关注将是我源源不断的前进动力。