要使用vite构建项目并支持微前端,可以按照以下步骤进行:
第一步:初始化项目
npm init vite-app my-project
第二步:安装依赖
cd my-project
npm install
第三步:按需加载
要支持微前端,需要让每个子应用按需加载,而vite正好支持这一特性。你可以在子应用的entry.js
中,只导入本子应用需要的模块,而不是导入整个应用的所有模块:
import { createApp } from 'vue';
import App from './App.vue';
import router from './router';
import store from './store';
// 只导入本应用需要的模块
import Button from 'vant/lib/button';
import 'vant/lib/button/style';
const app = createApp(App);
// 使用本应用需要的模块
app.use(router)
.use(store)
.use(Button)
.mount('#app');
第四步:启用跨域
微前端的架构需要解决跨域问题。在vite项目中使用http-proxy-middleware
中间件,将需要跨域访问的接口地址转发到对应的服务器上。
import { createApp } from 'vue';
import App from './App.vue';
import router from './router';
import store from './store';
// 只导入本应用需要的模块
import Button from 'vant/lib/button';
import 'vant/lib/button/style';
const app = createApp(App);
// 使用本应用需要的模块
app.use(router)
.use(store)
.use(Button)
.mount('#app');
// 代理接口
const { createProxyMiddleware } = require('http-proxy-middleware');
module.exports = {
server: {
proxy: {
'/api': {
target: 'http://localhost:3000',
ws: true,
changeOrigin: true
}
}
}
};
示例说明
示例一:主应用调用子应用
my-project
├── my-app
├── node_modules
├── index.html
├── main.js
├── package-lock.json
└── package.json
在主应用的index.html
文件中添加子应用的入口,将子应用作为一个iframe嵌入到主应用中,使用postMessage实现主子通讯。
<!-- index.html -->
<template>
<div>
<h1>主应用</h1>
<button @click="loadApp">加载子应用</button>
<iframe :src="childAppUrl" ref="childApp"></iframe>
</div>
</template>
<script>
export default {
data() {
return {
childAppUrl: 'http://localhost:3001',
childApp: null
};
},
methods: {
loadApp() {
this.$refs.childApp.contentWindow.postMessage({
type: 'loadApp'
}, this.childAppUrl);
},
messageHandler(event) {
if (event.origin !== this.childAppUrl) return;
const { type } = event.data;
if (type === 'appLoaded') {
this.childApp = event.source;
}
// ...
}
},
mounted() {
window.addEventListener('message', this.messageHandler);
},
destroyed() {
window.removeEventListener('message', this.messageHandler);
}
};
</script>
在子应用的entry.js
文件中,添加消息监听,用于接收来自主应用的消息。我们假设子应用可以在其他页面进行独立访问,所以需要判断是否需要加载子应用。
const appAddress = 'http://localhost:3001';
let isMasterApp = !window.parent || window === window.parent;
let masterApp = window.parent;
function registerApp() {
console.log('注册子应用');
masterApp.postMessage({
type: 'appLoaded'
}, appAddress);
}
if (!isMasterApp) {
console.log('主应用加载子应用');
window.addEventListener('message', (event) => {
const { type } = event.data;
if (type === 'loadApp') {
registerApp();
}
// ...
});
registerApp();
}
示例二:子应用调用主应用
my-app
├── node_modules
├── public
├── src
├── vite.config.js
├── package-lock.json
└── package.json
在子应用的entry.js
文件中,添加消息监听,用于接收来自主应用的消息。当我们需要子应用调用主应用时,只需要向window.parent.postMessage()
发送一个消息即可。
const appAddress = 'http://localhost:3001';
let isMasterApp = !window.parent || window === window.parent;
let masterApp = window.parent;
if (!isMasterApp) {
console.log('主应用加载子应用');
window.addEventListener('message', (event) => {
const { type } = event.data;
if (type === 'loadApp') {
registerApp();
}
// ...
});
registerApp();
}
// 子应用调用主应用
masterApp.postMessage({
type: 'navigateTo',
payload: {
path: '/home'
}
}, appAddress);
在主应用中添加对应的路由,用于子应用跳转。在index.html
中使用<router-view>
标签来显示对应路由的组件。
// main.js
import { createApp } from 'vue';
import App from './App.vue';
import router from './router';
createApp(App).use(router).mount('#app');
// router.js
import { createRouter, createWebHistory } from 'vue-router';
import Home from './views/Home.vue';
import About from './views/About.vue';
const routes = [
{ path: '/', component: Home },
{ path: '/home', component: Home },
{ path: '/about', component: About }
];
const router = createRouter({
history: createWebHistory(),
routes
});
export default router;
// index.html
<template>
<div>
<h1>主应用</h1>
<router-link to="/">首页</router-link>
<router-link to="/about">关于我们</router-link>
<router-view />
</div>
</template>
<script>
export default {
data() {
return {
childAppUrl: 'http://localhost:3001',
childApp: null
};
},
methods: {
loadApp() {
this.$refs.childApp.contentWindow.postMessage({
type: 'loadApp'
}, this.childAppUrl);
},
navigateTo(path) {
this.$router.push(path);
},
messageHandler(event) {
if (event.origin !== this.childAppUrl) return;
const { type, payload } = event.data;
if (type === 'appLoaded') {
this.childApp = event.source;
}
else if (type === 'navigateTo') {
const { path } = payload;
this.navigateTo(path);
}
}
},
mounted() {
window.addEventListener('message', this.messageHandler);
},
destroyed() {
window.removeEventListener('message', this.messageHandler);
}
};
</script>
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:vite构建项目并支持微前端 - Python技术站