qiankun 主项目和子项目都是 vue2,部署在同一台服务器上,nginx 配置

server/2024/12/21 22:37:16/

1、主项目配置

        1.1 micro.vue 组件

<template><div id="container-sub-app"></div>
</template><script>
import { loadMicroApp } from 'qiankun';
import actions from '@/utils/actions.js';export default {name: 'microApp',mixins: [actions],data() {return {microApp: null};},mounted() {const getMicroInfo = this.getMicroInfo();this.microApp = loadMicroApp(getMicroInfo, {singular: true});},beforeDestroy() {console.log('beforeDestroy...');this.microApp.unmount();},methods: {// 手动加载微应用getMicroInfo() {const appIdentifying = this.$route.path.split('/')[1];let data = {};const href = window.location.host;for (let i = 0; i < document.subApps.length; i++) {const element = document.subApps[i];if (element.activeRule.includes(appIdentifying)) {if (typeof element.entry !== 'string') {data = {...element,entry: element.entry[href]? element.entry[href]: Object.values(element.entry)[0]};} else {data = { ...element };}data.props = {token: {userInfo: {userName: '小明',userId: '123',date: new Date().toLocaleString()}}};data.activeRule = [appIdentifying];break;}}return data;}}
};
</script>

   1.2 index.html 引入配置

<!DOCTYPE html>
<html><head><meta charset="utf-8" /><meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" /><metaname="viewport"content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"/><link rel="icon" href="<%= BASE_URL %>favicon.ico" /><script src="<%= BASE_URL %>register-apps.js"></script><title><%= webpackConfig.name %></title></head><body><noscript><strong>We're sorry but <%= webpackConfig.name %> doesn't work properly withoutJavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div><!-- built files will be auto injected --></body>
</html>

        1.3 register-apps.js 配置

document.subApps = [{name: 'besFront',//entry: '//localhost:8086/bes-front/',// 本地调试entry: '/bes-front/',// 部署到服务器container: '#container-sub-app',activeRule: '/bes-front'}
];

        1.4 路由配置

import Vue from 'vue';
import Router from 'vue-router';Vue.use(Router);import Layout from '@/layout';
import MicroApp from '@/components/microApp';export const constantRoutes = [{path: '/login',component: () => import('@/views/login/index'),hidden: true},{path: '/404',component: () => import('@/views/404'),hidden: true},{path: '/dashboard',component: Layout,redirect: '/dashboard/index',children: [{path: 'index',name: 'Dashboard',component: () => import('@/views/dashboard/index'),meta: { title: 'Dashboard', icon: 'dashboard' }}]},{path: '/',component: Layout,children: [{path: 'bes-front',component: MicroApp// 重点,用于加载子项目}]}// 404 page must be placed at the end !!!// { path: '*', redirect: '/404', hidden: true }
];const createRouter = () =>new Router({mode: 'history', // require service supportbase: '',scrollBehavior: () => ({ y: 0 }),routes: constantRoutes});const router = createRouter();// Detail see: https://github.com/vuejs/vue-router/issues/1234#issuecomment-357941465
export function resetRouter() {const newRouter = createRouter();router.matcher = newRouter.matcher; // reset router
}export default router;

2、子项目配置

        2.1 main.js 配置

// 动态设置 publicPath
import './public-path';
import Vue from 'vue';
import App from './App.vue';
import router from './router';
import store from './store';
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';Vue.config.productionTip = false;
Vue.use(ElementUI);let instance = null;
function render(props = {}) {console.log('子应用 render props::', props, 'instance====', instance);// sessionStorage.setItem('userInfo', JSON.stringify(props.token.userInfo));const { container } = props;instance = new Vue({router,store,render: (h) => h(App)}).$mount(container ? container.querySelector('#app') : '#app');
}// 独立运行时
/* eslint-disable */
if (!window.__POWERED_BY_QIANKUN__) {render();
}export async function bootstrap() {console.log('子应用 bootstrap ===========================');
}let initialState = null;
export async function mount(props) {console.log('子应用 mount props ===============', props);sessionStorage.setItem('userInfo', JSON.stringify(props.token.userInfo));props.onGlobalStateChange((state, prev) => {// state: 变更后的状态; prev 变更前的状态console.log('子应用获取共享数据 state::', state, 'prev::', prev);// 接收主应用中的共享数据 并将其设置为全局变量Vue.prototype.$initialState = state;});props.setGlobalState({initialState:'子应用中修改主应用中的全局变量,实现住应用子应用间数据的双向双向通信'});render(props);
}
export async function unmount() {console.log('子应用 unmount==========');instance.$destroy();instance.$el.innerHTML = '';instance = null;
}

        2.2  public-path 文件

if (window.__POWERED_BY_QIANKUN__) {/* eslint-disable @typescript-eslint/camelcase */__webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;
}

        2.3 vue.config.js 配置

'use strict';
const path = require('path');
const defaultSettings = require('./src/settings.js');
const proxyTable = require('./proxyTable');function resolve(dir) {return path.join(__dirname, dir);
}const name = defaultSettings.title || 'vue Admin Template'; // page title// If your port is set to 80,// use administrator privileges to execute the command line.
// For example, Mac: sudo npm run
// You can change the port by the following methods:
// port = 9528 npm run dev OR npm run dev --port = 9528
const port = process.env.port || process.env.npm_config_port || 9528; // dev port// All configuration item explanations can be find in https://cli.vuejs.org/config/
module.exports = {/*** You will need to set publicPath if you plan to deploy your site under a sub path,* for example GitHub Pages. If you plan to deploy your site to https://foo.github.io/bar/,* then publicPath should be set to "/bar/".* In most cases please use '/' !!!* Detail: https://cli.vuejs.org/config/#publicpath*/publicPath: '/bes-front/',outputDir: 'dist',assetsDir: 'static',lintOnSave: process.env.NODE_ENV === 'development',productionSourceMap: false,devServer: {headers:{"Access-Control-Allow-Origin": "*",},port: port,open: true,proxy: proxyTable,overlay: {warnings: false,errors: true}},configureWebpack: {// provide the app's title in webpack's name field, so that// it can be accessed in index.html to inject the correct title.name: name,output:{library: `besFront`,// 主应用libraryTarget: "umd",// 把微应用打包成 umd 库格式jsonpFunction: `webpackJsonp_besFront`,// webpack5 需要把 jsonpFunction 替换成 chunkLoadingGlobal},resolve: {alias: {'@': resolve('src')}}},chainWebpack(config) {// it can improve the speed of the first screen, it is recommended to turn on preloadconfig.plugin('preload').tap(() => [{rel: 'preload',// to ignore runtime.js// https://github.com/vuejs/vue-cli/blob/dev/packages/%40vue/cli-service/lib/config/app.js#L171fileBlacklist: [/\.map$/, /hot-update\.js$/, /runtime\..*\.js$/],include: 'initial'}]);// when there are many pages, it will cause too many meaningless requestsconfig.plugins.delete('prefetch');// set svg-sprite-loaderconfig.module.rule('svg').exclude.add(resolve('src/icons')).end();config.module.rule('icons').test(/\.svg$/).include.add(resolve('src/icons')).end().use('svg-sprite-loader').loader('svg-sprite-loader').options({symbolId: 'icon-[name]'}).end();config.when(process.env.NODE_ENV !== 'development', (config) => {config.plugin('ScriptExtHtmlWebpackPlugin').after('html').use('script-ext-html-webpack-plugin', [{// `runtime` must same as runtimeChunk name. default is `runtime`inline: /runtime\..*\.js$/}]).end();config.optimization.splitChunks({chunks: 'all',cacheGroups: {libs: {name: 'chunk-libs',test: /[\\/]node_modules[\\/]/,priority: 10,chunks: 'initial' // only package third parties that are initially dependent},elementUI: {name: 'chunk-elementUI', // split elementUI into a single packagepriority: 20, // the weight needs to be larger than libs and app or it will be packaged into libs or apptest: /[\\/]node_modules[\\/]_?element-ui(.*)/ // in order to adapt to cnpm},commons: {name: 'chunk-commons',test: resolve('src/components'), // can customize your rulesminChunks: 3, //  minimum common numberpriority: 5,reuseExistingChunk: true}}});// https:// webpack.js.org/configuration/optimization/#optimizationruntimechunkconfig.optimization.runtimeChunk('single');});}
};

3、主项目和子项目部署在同一台服务器上,其中主应用路由使用history模式,子应用路由使用hash模式,nginx 的配置如下:

locatoin / {root /opt/parent;index index.html index.htm;try_files $uri $uri/ /index.html;
}location /bes-front/ {root /opt/parent;index index.html index.htm;try_files $uri $uri. /index.html;
}

注:使用的下面这种部署方式,主应用代码放在parent目录下,子应用代码放在parent目录下面,其他,子应用的目录应该代码中的名称保持一致,在本示例当中,子应用使用的是bes-front

官网参考链接: 入门教程 - qiankun

4、总结

在部署主应用和子应用时,遇到主应用转发到子应用时,静态资源无法访问的问题,重点是查看子应用publicPath这个配置,这个是静态文件的访问前缀,如果部署到服务器上,子应用的静态资源无法访问到,可以看一下服务器访问的静态资源的前缀是否和代码中配置的一致。


http://www.ppmy.cn/server/131581.html

相关文章

决策树和集成学习的概念以及部分推导

一、决策树 1、概述 决策树是一种树形结构&#xff0c;树中每个内部节点表示一个特征上的判断&#xff0c;每个分支代表一个判断结果的输出&#xff0c;每个叶子节点代表一种分类结果 决策树的建立过程&#xff1a; 特征选择&#xff1a;选择有较强分类能力的特征决策树生成…

Facebook直播分析与问题解决策略

Facebook直播&#xff08;Facebook Live&#xff09;是一种通过Facebook平台进行的实时视频流媒体功能&#xff0c;使用户能够与朋友、关注者或公众分享实时内容。自从推出以来&#xff0c;Facebook直播逐渐成为企业营销、个人表达和社交互动的重要工具。本文将分析Facebook直播…

ChatGPT背景下,高职人工智能技术应用专业的人才培养

一、引言 ChatGPT&#xff0c;即聊天生成预训练变换器&#xff0c;由美国OpenAI公司开发&#xff0c;自2022年11月首次亮相以来&#xff0c;已成为人工智能领域的一个标志性成就。这款聊天机器人利用先进的人工智能技术&#xff0c;处理自然语言&#xff0c;能够精准把握用户的…

jmeter实现SSL双向验证

前提: 预先了解:SSL单向/双向认证详解握手请求以及tomcat配置https请求的请到以下网址了解Java nginx https 双向认证 der,cer文件一般是二进制格式的,只放证书,不含私钥 crt 文件可能是二进制的,也可能是文本格式的,应该以文本格式居多,功能同der/cer pem文件一般是…

如何成为 Rust 核心贡献者?Rust 开发的核​​心是什么?Rust 重要技术专家揭秘

10 月 17 - 18日&#xff0c;由 GOSIM 开源创新汇主办、CSDN 承办的 GOSIM CHINA 2024 将在北京盛大启幕。作为 GOSIM 开源年度大会的第三届盛会&#xff0c;本次活动邀请了 60 多位国际开源专家&#xff0c;汇聚了来自全球百余家顶尖科技企业、知名高校及开源社区的技术大咖、…

python从0快速上手(二)IDE选择

在这个代码横飞的世界里&#xff0c;选择一个合适的Python IDE就好比是选择一把顺手的武器。今天&#xff0c;就让我来带你一探究竟&#xff0c;看看市面上有哪些让人眼花缭乱的Python IDE&#xff0c;并一较高下。 1. PyCharm PyCharm&#xff0c;由大名鼎鼎的JetBrains出品…

Linux编辑器-vim的配置及其使用

vim是一种多模式的编辑器&#xff1a; 1.命令模式&#xff08;默认模式&#xff09;&#xff1a;用户所有的输入都会当作命令&#xff0c;不会当作文本输入。 2.插入模式&#xff1a;写代码&#xff0c; 按「 i 」切换进入插入模式「 insert mode 」&#xff0c;按 “i” 进入…

信息学交互题的写法和注意事项总结

信息学交互题的写法和注意事项总结&#xff1a; 1. 题目分析 交互题要求选手与“裁判”进行多次输入输出的交互&#xff0c;通常以多轮交互实现问题的解决。题目的核心在于&#xff1a;如何通过“询问”或“操作”逐步推导出答案或实现目标。 2. 写法要点 输入输出模式&…