1.基座 – vue3
- index.html文件设置约定的id,如id=”base”
<body>
<div id="base"></div>
<script type="module" src="/src/main.ts"></script>
</body>
复制代码
- 入口文件main.ts引入qiankun框架并进行注册子应用等等
import { createApp } from 'vue'
import App from './App.vue'
import store from './store/index'
import router from './router/index'
import '@/styles/index.less'
import { registerMicroApps, start } from 'qiankun'
const isSubAppHome = function isSubAppHome(path:string):boolean {
if (path === '/') {
return true
}
return path.indexOf('/home') === 0
}
const apps = [
{
name: 'subapp-home', // 应用的名字
entry: 'http://www.xxx.com/child/home', // 默认会加载这个html 解析里面的js 动态的执行 (子应用必须支持跨域)fetch
container: '#container', // 容器名(此项目页面中定义的容器id,用于把对应的子应用放到此容器中,进下一步骤设置id)
activeRule: (location: { pathname: string }) => isSubAppHome(location.pathname), // 激活的路径
props: { a: 1 } // 传递的值(可选)
}
]
registerMicroApps(apps); // 注册应用
start(); //启动
const app = createApp(App)
app.use(store).use(router)
app.mount('#base') // 这里设置上一步的id
复制代码
- 修改App.vue文件,设置子应用挂载的容器
<template>
<div class="main-container">
<Header />
<div class="microservices-container">
<-- 这里设置子应用挂载的容器-->
<div id="container"></div>
</div>
<router-view />
<Footer />
</div>
</template>
复制代码
至此基座就搭建完成
子应用home- vue2
- vue.config.js
const packageName = require('./package.json').name;
module.exports = {
publicPath: '/child/home/',// 这里官方文档没写,但是我没写失败
output: {
library: `${packageName}-[name]`,// 固定配置
libraryTarget: 'umd',// 固定配置
jsonpFunction: `webpackJsonp_${packageName}`, // 固定配置
},
devServer: {
port: 8080,
headers: {
//因为qiankun内部请求都是fetch来请求资源,所以子应用必须允许跨域
'Access-Control-Allow-Origin': '*'
}
}
};
复制代码
publicPath: '/child/home/'
这个没搞明白为啥必须写
- main.js
import Vue from 'vue'
import App from './App.vue'
import router from './router/index.js'
Vue.config.productionTip = false
let instance = null
if (!window.__POWERED_BY_QIANKUN__) { // 默认独立运行
new Vue({
router,
render: h => h(App),
}).$mount('#app')
}
// 父应用加载子应用,子应用必须暴露三个接口:bootstrap、mount、unmount
// 子组件的协议就ok了
export async function bootstrap() {
}
export async function mount(props) {
console.log(props, '====')
new Vue({
router,
render: h => h(App),
}).$mount('#app')
}
export async function unmount() {
instance.$destroy();
}
复制代码
官方文档:”新增 public-path.js
文件,用于修改运行时的 publicPath
“,但我没有设置也能正常访问
打包
打包后的目录结构
基座打包为vite做跟目录,子应用放在child文件夹下面,如子应用打包为home
微前端的部署
nginx 配置
server {
listen 80;
server_name localhost;
location / {
root /root/node/vite; //vite的绝对路径
index index.html index.htm;
try_files $uri $uri/ /index.html;
}
location /child/home { // 基座配置的entry
root /root/node/vite;
index index.html index.htm;
try_files $uri $uri/ /child/home/index.html;
}
location /api {
proxy_pass http:/xxxxxx/api;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
# angular 和 react 的history 配置同上
}
复制代码
个人理解:当访问基座配置的对应activeRule时,乾坤会请求entry,这时在nginx的代理会找到子应用,乾坤会把子应用挂载到container这个基座的id上,这样就看到了
- 子应用用于修改运行时的
publicPath
这个一定要吗,我没写也没报错 - 子应用router的base需要吗
- 子应用打包配置有啥用呢,为啥我要加上publicPath: ‘/child/home/’
附一份上传打包后的文件脚本
'use strict'
const Client = require('ssh2-sftp-client')
const config = {
path: {
// 远程地址
romotePath:'/root/node/vite/',
// 本地地址
localPath: './dist'
},
romote: {
// 服务器 ip 地址
host: 'xxxx.xxx.xxx.xxx',
// 端口号,默认是 22
port: '22',
// 登录的用户名
username: 'root',
// 登录密码
password: 'xxx'
}
}
function main(localPath, romotePath) {
// 实例化
const sftp = new Client()
sftp
.connect(config.romote)
.then(() => {
console.log('----------------------------- 连接成功,上传中... -----------------------------')
return sftp.uploadDir(localPath, romotePath)
})
.then(data => {
console.log('----------------------------- 上传完成,及时清除缓存 ----------------------------')
})
.catch(err => {
console.log('----------------------------- TMD失败了!出事了!快看看怎么回事! -----------------------------')
console.log(err)
})
.finally(() => {
// 断开连接
sftp.end()
})
}
main(
config.path.localPath,
config.path.romotePath
)
复制代码
不要忘记安装ssh2-sftp-client模块
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END