前端微服务MicroApp应用及nginx部署
首先放一波官网 https://cangdu.org/micro-app/
1、创建一个文件夹,包含基座项目及子项目
文件目录大概为
micro-demo
— mic-main (vue2为基础的基座)
— mic-vue2 (vue2的子项目)
— mic-vue3 (vue3的子项目)
这三个项目都是hash路由模式
2、配置基座
进入 mic-main 项目
-
安装依赖
npm i @micro-zoe/micro-app --save
-
在main.js引入依赖
import Vue from 'vue' import App from './App.vue' import router from './router' import store from './store' import microApp from '@micro-zoe/micro-app' // 引入依赖 microApp.start() // 调用microApp主函数,开启微服务 Vue.config.productionTip = false new Vue({ router, store, render: h => h(App) }).$mount('#app')
-
在components文件下创建两个vue组件,分别叫vue2Page.vue和vue3Page.vue,配置子项目的路径
// vue2Page.vue配置 <template> <div> <h2>这是子应用vue2的页面</h2> <micro-app name='vue2Page' // 子项目名称,必须全局唯一 :url='url' // 子项目的访问地址 baseroute='/vue2' // 基座应用分配给子应用的路由前缀 ></micro-app> </div> </template> <script> export default { name: 'vue2Page', data () { return { url:'//localhost:3000/vue2/' } } } </script>
// vue3Page.vue配置 <template> <div> <h2>这是子应用vue3的页面</h2> <micro-app name='vue3Page' // 子项目名称,必须全局唯一 :url='url' // 子项目的访问地址 baseroute='/vue3' // 基座应用分配给子应用的路由前缀 ></micro-app> </div> </template> <script> export default { name: 'vue3Page', data () { return { url:'//localhost:4000/vue3/' } } } </script>
-
在router配置这两个组件的路由
import Vue from 'vue' import VueRouter from 'vue-router' import Home from '../views/Home.vue' Vue.use(VueRouter) const routes = [ { path: '/', name: 'Home', component: Home }, { path: '/vue2/*', name: 'vue2', component: () => import('../components/vue2Page') }, { path: '/vue3/*', name: 'vue3', component: () => import('../components/vue3Page') }, ] const router = new VueRouter({ mode: 'hash', routes }) export default router
3、配置vue2子项目
进入 mic-vue2 项目
-
在src下创建一个public-path.js文件,解决打包时候静态资源无法加载问题
if (window.__MICRO_APP_ENVIRONMENT__) { // eslint-disable-next-line __webpack_public_path__ = window.__MICRO_APP_PUBLIC_PATH__ }
-
修改public目录下的index.html,修改最下面的div的id为app1,防止子项目根页面id和基座根页面id重复
<!DOCTYPE html> <html lang=""> <head> <meta charset="utf-8"> ....... <div id="app1"></div> // 修改id </body> </html>
-
修改main.js,让子项目可以单独运行,也可以配置函数mount和unmount进行数据操作
import './public-path' // 引入第1步配置的文件,必须在首行引入 import Vue from 'vue' import App from './App.vue' import router from './router' import store from './store' Vue.config.productionTip = false let app // 应用每次渲染时都会执行 mount 方法,在此处可以执行初始化相关操作(必传) export async function mount (props) { console.log('微应用vue2渲染了') app = new Vue({ router, store, render: h => h(App) }).$mount(props?.container?.querySelector('#app1') || '#app1') } // 卸载应用 export async function unmount () { console.log('微应用vue2卸载了') app.$destroy() app.$el.innerHTML = '' app = null } // 微前端环境下,注册mount和unmount方法 if (window.__MICRO_APP_ENVIRONMENT__) { window[`micro-app-${window.__MICRO_APP_NAME__}`] = { mount, unmount } } else { // 非微前端环境直接渲染 mount() }
-
修改vue.config.js,主要配置项为devServer,port必须和基座中配置的子项目访问地址一致,再开启跨域
const { name } = require('../package.json') module.exports = { transpileDependencies: ['common'], lintOnSave: false, chainWebpack: config => config.resolve.symlinks(false), configureWebpack: { output: { // 把子应用打包成 umd 库格式 library: 'mic-vue2', libraryTarget: 'umd', jsonpFunction: `webpackJsonp_${name}` } }, publicPath: '/vue2', // 配置子路径地址 devServer: { port: 3000, // 此端口号必须和基座中的micro-app中配置的url地址一致 headers: { 'Access-Control-Allow-Origin': '*' // 开启跨域 } } }
4、配置vue3子项目
方法同上,主要是mian.ts配置稍微修改
import './public-path'
import { createApp } from 'vue'
import { createRouter, createWebHistory } from 'vue-router'
import routes from './router'
import App from './App.vue'
let app = null
let router = null
let history = null
// 将渲染操作放入 mount 函数
function mount () {
history = createWebHashHistory(window.__MICRO_APP_BASE_ROUTE__ || '/vue3/')
router = createRouter({
history,
routes,
})
app = createApp(App)
app.use(router)
app.mount('#app2')
console.log('微应用vue3渲染了')
}
// 将卸载操作放入 unmount 函数
function unmount () {
app?.unmount()
history?.destroy()
app = null
router = null
history = null
console.log('微应用vue3卸载了')
}
// 微前端环境下,注册mount和unmount方法
if (window.__MICRO_APP_ENVIRONMENT__) {
window[`micro-app-${window.__MICRO_APP_NAME__}`] = { mount, unmount }
} else {
// 非微前端环境直接渲染
mount()
}
5、打包配置
由于打包上线后,子项目的地址为线上的地址,所以micro-app的url匹配不上,无法加载子项目,需要环境变量配置url
-
进入基座项目mic-main,在根目录下添加两个环境文件.env.development和.env.production
-
// 开发环境 .env.development 配置 VUE_APP_SUB_VUE2=//localhost:3000/vue2/ VUE_APP_SUB_VUE3=//localhost:4000/vue3/
-
// 生产环境 .env.production 配置 VUE_APP_SUB_VUE2=//192.168.12.135:20071/vue2/ VUE_APP_SUB_VUE3=//192.168.12.135:20071/vue3/
-
修改vue2Page.vue和vue3Page.vue中的micro-app的url配置
// vue2Page.vue配置 <template> <div> <h2>这是子应用vue2的页面</h2> <micro-app name='vue2Page' :url='url' baseroute='/vue2' ></micro-app> </div> </template> <script> export default { name: 'vue2Page', data () { return { url:process.env.VUE_APP_SUB_VUE2, // 修改为环境地址 } } } </script>
6、nginx配置
打完包的文件目录为
dist
— main (基座的打包文件)
— subapp
—— sub-vue2 (vue2项目的打包文件)
—— sub-vue3 (vue3项目的打包文件)
nginx.conf配置端口如下
server {
listen 20071;
server_name localhost;
location / {
root html/dist/main;
index index.html;
try_files $uri $uri/ /index.html;
}
location /vue2 {
alias html/dist/subapp/sub-vue2;
index index.html;
try_files $uri $uri/ /index.html;
}
location /vue3 {
alias html/dist/subapp/sub-vue3;
index index.html;
try_files $uri $uri/ /index.html;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}