您现在的位置是:主页 > news > 深圳网站建设咨询公司/搭建网站的步骤

深圳网站建设咨询公司/搭建网站的步骤

admin2025/5/3 21:19:06news

简介深圳网站建设咨询公司,搭建网站的步骤,上海港湾基础建设集团网站,win2008iis7配置网站微前端的概念是从后端的微服务中迁移过来的。将 Web 应用由单一的单体应用转变为多个小型前端应用聚合为一的应用。各个前端应用还可以独立运行、独立开发、独立部署qiankun 是阿里巴巴基于 single-spa 实现的微前端库,是一个开放式微前端架构,支持当前三…

深圳网站建设咨询公司,搭建网站的步骤,上海港湾基础建设集团网站,win2008iis7配置网站微前端的概念是从后端的微服务中迁移过来的。将 Web 应用由单一的单体应用转变为多个小型前端应用聚合为一的应用。各个前端应用还可以独立运行、独立开发、独立部署qiankun 是阿里巴巴基于 single-spa 实现的微前端库,是一个开放式微前端架构,支持当前三…

1d0edd7b7c9d020f30663b9e6772bfba.png
微前端的概念是从后端的微服务中迁移过来的。将 Web 应用由单一的单体应用转变为多个小型前端应用聚合为一的应用。各个前端应用还可以独立运行、独立开发、独立部署

qiankun 是阿里巴巴基于 single-spa 实现的微前端库,是一个开放式微前端架构,支持当前三大前端框架甚至 jq 等其他项目无缝接入。

微前端待解决的问题

  • [x] 微前端主应用与子应用如何构建
  • [x] 主应用资源下发给子应用
  • [x] 各应用间动态通信,实时监听,同步数据
  • [x] 微前端线上部署

微前端主应用与子应用如何构建

构建主应用

  1. 通过 vue-cli 构建一个主应用工程,安装微前端依赖 qiankunyarn add qiankunnpm i qiankun
  2. 改造 main.js
// 引入依赖
import Vue from 'vue';
import App from './App.vue';
import store from './store';
import router from './router';
import { i18n } from './plugin';
import {registerMicroApps, // 注册子应用runAfterFirstMounted, // 第一个子应用加载完毕setDefaultMountApp, // 设置默认子应用start, // 微服务启动
} from 'qiankun';// 公共依赖挂载在window上,目的是传递给子应用
window.vue = Vue;// 渲染主应用, #container为主应用根元素
new Vue({i18n,store,router,render: h => h(App)
}).$mount('#container');/*** 路由监听* @param {string} routerPrefix 前缀*/
const genActiveRule = (routerPrefix: string) => {return (location: Location) => location.pathname.startsWith(routerPrefix);
};// 构建子应用, #micro-app为子应用容器
let microApps = [{name: 'qiankun-test1',entry: '//localhost:7001',container: '#micro-app',activeRule: genActiveRule('/test1')},{name: 'vue-test2',entry: '//localhost:7002',container: '#micro-app',activeRule: genActiveRule('/test2')}
];
// 注册子应用
registerMicroApps(microApps, {// 挂载前回调beforeLoad: [app => {console.log('before load', app);}],// 挂载后回调beforeMount: [app => {console.log('before mount', app);}],// 卸载后回调afterUnmount: [app => {console.log('after unload', app);}]
});// 设置默认子应用,参数genActiveRule('/test1')函数内的参数一致
setDefaultMountApp('/test1');// 第一个子应用加载完毕回调
runAfterFirstMounted(() => {});// 启动微服务
start();
App.vue 中,增加一个渲染子应用的容器
<template><div id="root" class="container"><header class="header">header</div><!-- 子应用容器 --><div id="micro-app"></div></div>
</template>
<script lang="ts">
import { Vue, Component } from 'vue-property-decorator';@Component({name: 'Root'
})
export default class Root extends Vue {}
</script>
主应用的 vue.config.js
const port = 7000;
module.exports = {// publicPath: process.env.VUE_APP_ROOT_PATH || '/',devServer: {hot: true,port,disableHostCheck: true,headers: {'Access-Control-Allow-Origin': '*'}}
};

注意 主应用设置 publicPath: '/' 会造成子应用配置的 publicPath 失效,导致无限循环刷新页面。

构建子应用

  1. 通过 vue-cli 构建一个子应用工程
  2. 改造 main.js
import VueRouter from 'vue-router';
import App from './App.vue';
import store from './store';
import routes from './router';
import { i18n } from './plugin';Vue.config.productionTip = false;// 声明变量管理vue及路由实例
let router = null;
let instance = null;
const __qiankun__ = window.__POWERED_BY_QIANKUN__;if (window.__POWERED_BY_QIANKUN__) {// eslint-disable-next-line__webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;
}// 导出子应用生命周期 挂载前
export async function bootstrap(props) {console.log(props)
}// 导出子应用生命周期 挂载后
export async function mount(props) {// 实例化routerrouter = new VueRouter({base:  '/', // 也可写子应用路径mode: 'history',routes // 通过主应用传递的props来获取,可实现动态路由});// 实例化子应用instance = new Vue({i18n,store,router,render: h => h(App)}).$mount('#app');
}// 导出子应用生命周期 卸载后
export async function unmount() {instance.$destroy();instance = null;router = null;
}// 单独开发环境
__qiankun__ || mount();
修改 router.js 中
import { RouteConfig } from 'vue-router';
import Home from '@/views/Home.vue';const routes: Array<RouteConfig> = [{path: '/',name: 'home',component: Home},{path: '/about',name: 'about',component: () => import('@/views/About.vue')}
];export default routes;

注意:这里导出的是路由数组,而不是 rouer 实例

子应用的 vue.config.js
const { name } = require('./package');
const path = require('path');
function resolve(dir) {return path.resolve(__dirname, dir);
}const port = 7001;
const isDev = process.env.NODE_ENV === 'development';module.exports = {publicPath: isDev ? `//localhost:${port}` : '/',// 自定义webpack配置configureWebpack: config => {config.output.library = `${name}-[name]`;config.output.libraryTarget = 'umd';config.output.jsonpFunction = `webpackJsonp_${name}`;// 排除依赖项,不打包vueconfig.externals = {vue: 'vue'};},// 对内部的 webpack 配置(比如修改、增加Loader选项)(链式操作)chainWebpack: config => {// 配置依赖别名config.resolve.alias.set('vue', resolve('src/config/window/vue'));},devServer: {port,hot: true,disableHostCheck: true,// 开发环境需要配置,解决跨越headers: {'Access-Control-Allow-Origin': '*'}}
};
src/config/window/vue.ts, 引入window上的vue并导出
const vue = window.vue;export default vue;

主应用资源下发给子应用

实际项目中,父子应用之间会公用一些方法,组件。可以把公共的方法和组件放在主应用中,下发到子应用以供使用

主应用的 main.js
import CustomComponent from '@/components/custom';
import storage from '@/utils/storage';
import filters from '@/utils/filters';
import * as directives from '@/utils/directives';// 定义传入子应用的数据
const msg = {storage,filters,directives,CustomComponent
};// 注册子应用
registerMicroApps([{name: 'qiankun-test1',entry: '//localhost:7001',container: '#micro-app',activeRule: genActiveRule('/test1'),props: msg}
]);
子应用的 main.js 接受 props
export async function bootstrap({ storage, filters, directives, CustomComponent }) {// 子应用全局挂载storageVue.prototype.$storage = storage;// 注册全局过滤器for (const key in filters) {Vue.filter(key, (...args: Array<unknown>) => {return filters[key](...args);});}// 挂载全局指令Object.keys(directives).forEach(key => {Vue.directive(key, (directives as { [key: string]: DirectiveOptions })[key]);});// 注册主应用下发的组件Vue.use(CustomComponent);
}

各应用间动态通信, 实时监听, 同步数据

qiankun 官方也提供了 api 去解决这个问题,不过使用起来不是很方便,我使用的是 rxjs 去解决应用间通信的需求
  1. 主应用中安装并引入 rxjs,并实例化
import { Subject } from 'rxjs';
const pager = new Subject();// 在主应用注册呼机监听器,监听来自其他应用的广播
pager.subscribe(v => {console.log(v);
});export default pager;
  1. 然后在主应用 main.js 中引入呼机,将呼机下发给子应用
import pager from '@/util/pager';// 注册子应用
registerMicroApps([{name: 'qiankun-test1',entry: '//localhost:7001',container: '#micro-app',activeRule: genActiveRule('/test1'),props: { pager } // 将pager传递给子应用}]
);
  1. 在子应用中注册呼机
export async function bootstrap({ pager }) {// 子应用注册呼机, 监听其他应用的广播pager.subscribe((v) => {console.log(v);});// 将呼机挂载在vue实例Vue.prototype.$pager = pager;
}
  1. 在各应用中使用呼机动态传递信息
// 在某个应用里调用.next方法呼叫其他应用
this.$pager.next({from: 'qiankun-test1',data: 'test1 呼叫其他菜鸡'
});

微前端线上部署

以上做了这么多,能够部署到服务器上才算成功。我这里用的是 nginx
server {listen          7000;server_name     localhost;location / {add_header Access-Control-Allow-Origin *;add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';root /Users/sunweijie/qiankun-app/master/dist/;index index.html index.htm;try_files $uri $uri/ /index.html;}
}server {listen          7001;server_name     localhost;root            /Users/sunweijie/qiankun-app/subapp-rights/dist/;location / {add_header Access-Control-Allow-Origin *;add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';try_files $uri $uri/ /index.html;}
}server {listen          7002;server_name     localhost;root            /Users/sunweijie/qiankun-app/subapp-common/dist/;location / {add_header Access-Control-Allow-Origin *;add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';try_files $uri $uri/ /index.html;}
}
我这里把关键性的几个要点给列举了下,在真正的实践过程中还是会踩到不少坑的,欢迎大家一起来入坑 附上 github 的工程地址:qiankun-container,顺手给楼主点个 star 吧