1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > 基于qiankun微前端实践| 主应用vue 微应用vue react

基于qiankun微前端实践| 主应用vue 微应用vue react

时间:2024-03-28 00:24:08

相关推荐

基于qiankun微前端实践| 主应用vue 微应用vue react

qiankun-demo

介绍qiankun介绍入门案例主应用配置安装qiankun注册微任务registerMicroApps vue微应用配置设置public-path设置history路由 base导出三个生命周期函数修改打包配置文件 vue.config.js 允许跨域和开启umd react微应用配置

介绍

基于qiankun微前端实践,主应用vue,微应用vue、react。线上项目地址:qiankun-demo

qiankun介绍

/zh/guide

特性: 技术栈无关样式隔离: 确保微应用之间样式互相不干扰 shadow domJS 沙箱 :确保微应用之间 全局变量/事件 不冲突 why not iframe

/kuitos/gky7yw/gesexv

iframe提供 浏览器原生的硬隔离方案, 不论是样式隔离、js 隔离这类问题统统都能被完美解决。 但他的最大问题也在于他的隔离性无法被突破,导致应用间上下文无法被共享,随之带来的开发体验、产品体验的问题。url 不同步UI不同步 DOM 结构不共享全局上下文完全隔离 ,内存变量不共享慢 : 每次子应用进入都是一次浏览器上下文重建、资源重新加载的过程

入门案例

主应用配置

安装qiankun
注册微任务registerMicroApps
创建 qiankun-base (vue2 + webpack)//vue-cli -->webpack在主应用 安装qiankun

$ yarn add qiankun # 或者 npm i qiankun -S

修改main.js 入口文件 ,注册微任务

import Vue from "vue";import App from "./App.vue";import router from "./router";import { registerMicroApps, start } from "qiankun";// 1. 导入Vue.config.productionTip = false;new Vue({router,render: (h) => h(App),}).$mount("#app");//2. 注册微应用registerMicroApps([{name: "vueApp",entry: "//localhost:8080",container: "#container",activeRule: "/app-vue",},{name: 'reactApp',entry: 'http://localhost:3000', // 默认会加载这个html 解析里面的js 动态的执行 (子应用必须支持跨域)fetchcontainer: '#container',activeRule: '/app-react',}]);//3. 启动 qiankunstart();

说明:

当微应用信息注册完之后,一旦浏览器的 url 发生变化,便会自动触发 qiankun 的匹配逻辑,所有 activeRule 规则匹配上的微应用就会被插入到指定的 container 中,同时依次调用微应用暴露出的生命周期钩子。

修改App.vue ,在主应用页面放置跳转链接以及 微应用对应的 container

<template><div id="app"><div id="nav"><router-link to="/app-vue">vue</router-link> |<router-link to="/app-react">react</router-link></div><router-view/> <div id="container"></div></div></template><style>#app {font-family: Avenir, Helvetica, Arial, sans-serif;-webkit-font-smoothing: antialiased;-moz-osx-font-smoothing: grayscale;text-align: center;color: #2c3e50;}#nav {padding: 30px;}#nav a {font-weight: bold;color: #2c3e50;}#nav a.router-link-exact-active {color: #42b983;}</style>

vue微应用配置

微应用分为有webpack构建和无webpack构建项目,有webpack的微应用(主要是指 Vue、React、Angular) 需要做的事情有:用webpack构建

新增public-path.js文件,用于修改运行时的publicPath。什么是运行时的 publicPath ?。

注意:运行时的 publicPath 和构建时的 publicPath 是不同的,两者不能等价替代。

微应用建议使用history模式的路由,需要设置路由base,值和它的activeRule是一样的。在入口文件最顶部引入public-path.js,修改并导出三个生命周期函数。修改webpack打包,允许开发环境跨域和umd打包。

主要的修改就是以上四个,可能会根据项目的不同情况而改变。例如,你的项目是index.html和其他的所有文件分开部署的,说明你们已经将构建时的publicPath设置为了完整路径,则不用修改运行时的publicPath(第一步操作可省)。

webpack构建的微应用直接将lifecycles挂载到window上即可。

设置public-path
设置history路由 base
导出三个生命周期函数
修改打包配置文件 vue.config.js 允许跨域和开启umd
使用vue-cli 生成 vue 2.x 项目在src 目录新增public-path.js:

// 运行在qiankun时 修改运行时publicpathif (window.__POWERED_BY_QIANKUN__) {// eslint-disable-next-line__webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;}

安装 vue-router

//vue 2.x --> vue-router 3.xyarn install @3//vue 3.x --> vue-router 4.xyarn install

修改 main.js 入口文件 导出子应用的生命周期:bootstarp 、mount 、 unmount

//1. 导入 public-path.js import "./public-path";import Vue from "vue";import VueRouter from "vue-router";import App from "./App.vue";import routes from "./router";// import store from "./store";Vue.config.productionTip = false;let router = null;let instance = null;function render(props = {}) {//2. 微应用 使用history 模式路由 设置路由base, 值与activeRule 一致const { container } = props;router = new VueRouter({base: window.__POWERED_BY_QIANKUN__ ? '/app-vue/' : '/',mode: "history",routes,});//3. 避免根id #app 与其他的DOM冲突 需要限制查找范围instance = new Vue({router,// store,render: (h) => h(App),}).$mount(container ? container.querySelector("#app") : "#app");}// 独立运行时if (!window.__POWERED_BY_QIANKUN__) {render();}// 4. 导出 三个生命周期函数/*** bootstrap 只会在微应用初始化的时候调用一次,下次微应用重新进入时会直接调用 mount 钩子,不会再重复触发 bootstrap。* 通常我们可以在这里做一些全局变量的初始化,比如不会在 unmount 阶段被销毁的应用级别的缓存等。*/export async function bootstrap() {console.log("[vue] vue app bootstraped");}/*** 应用每次进入都会调用 mount 方法,通常我们在这里触发应用的渲染方法*/export async function mount(props) {console.log("[vue] props from main framework", props);render(props);}/*** 应用每次 切出/卸载 会调用的方法,通常在这里我们会卸载微应用的应用实例*/export async function unmount() {instance.$destroy();instance.$el.innerHTML = "";instance = null;router = null;}/*** 可选生命周期钩子,仅使用 loadMicroApp 方式加载微应用时生效*/export async function update(props) {}

修改打包配置 vue.config.js

// const { name } = require("./package");module.exports = {devServer: {headers: {//1. 允许开发环境跨域 'Access-Control-Allow-Origin': '*',},},configureWebpack: {output: {library: `vueApp-[name]`,libraryTarget: "umd", // 2. 把微应用打包成 umd 库格式jsonpFunction: `webpackJsonp_vueApp`,// chunkLoadingGlobal: `webpackJsonp_${name}`, },},};

app.vue

<template><div id="app"><router-view /></div></template><script>export default {name: "App",ta() {// 变量定义return {};},};</script><style>#app {font-family: Avenir, Helvetica, Arial, sans-serif;-webkit-font-smoothing: antialiased;-moz-osx-font-smoothing: grayscale;text-align: center;color: #2c3e50;margin-top: 60px;}</style>

router/index.js

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: "/about",name: "About",component: () =>import(/* webpackChunkName: "about" */ "../views/About.vue"),},];export default routes;

react微应用配置

安装create-react-app 脚手架

创建react 项目

安装路由react-router-dom

npm install react-router-dom

在src 目录新增 public-path.js

if (window.__POWERED_BY_QIANKUN__) {__webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;}

修改index.js 入口文件

//1. 导入public-pathimport "./public-path"import React from 'react';import ReactDOM from 'react-dom';import {BrowserRouter as Router} from 'react-router-dom'import './index.css';import App from './App';// import reportWebVitals from './reportWebVitals';// if (window.__POWERED_BY_QIANKUN__) {// // eslint-disable-next-line no-undef// __webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;// }function render(props) {const { container } = props;ReactDOM.render(<React.StrictMode>需要用BrowserRouter包裹app设置 history 模式路由的 base<Router basename={window.__POWERED_BY_QIANKUN__ ? '/app-react' : '/'}><App /> </Router></React.StrictMode>,container ? container.querySelector('#root') : document.querySelector('#root'));}if (!window.__POWERED_BY_QIANKUN__) {render({});}// 导出三个生命周期 export async function bootstrap() {console.log('[react16] react app bootstraped');}export async function mount(props) {console.log('[react16] props from main framework', props);render(props);}export async function unmount(props) {const { container } = props;ReactDOM.unmountComponentAtNode(container ? container.querySelector('#root') : document.querySelector('#root'));}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。