微前端之实现方式和项目分析、实践主子应用启动配置、vue2、vue3、react15、react16 子应用的配置
一、微前端之实现方式和项目分析
- 微前端实现方式对比,如下所示:
Iframe
,Iframe
的优势是技术成熟,支持页面嵌入,天然支持运行沙箱隔离、独立运行。Iframe
的劣势是页面之间可以是不同的域名,需要对应的设计一套应用通讯机制,如何监听、传参格式等内容,应用加载、渲染、缓存等体系的实现web component
,web component
的优势是支持自定义元素、支持shadow down
,并可通过关联进行控制,支持模版template
和插槽slot
,引入自定义组件内容。web component
的劣势是接入微前端需要重写当前项目,生态系统不完善,技术过新容易出现兼容性问题,整体架构设计复杂,组件与组件之间拆分过细时,容易造成通讯和控制繁琐- 自研框架,自研框架的优势是高度定制化,满足需要做兼容的一切场景,独立的通信机制和沙箱运行环境,可解决应用之间相互影响的问题,支持不同技术栈子应用,可无缝实现页面无刷新渲染。自研框架的劣势是技术实现难度较高,需要设计一套定制的通信机制,首次加载会出现资源过大的情况
- 选择自研框架,路由分发式,主应用控制路由匹配和子应用加载,共享依赖加载,子应用做功能,并接入主应用实现主子控制和联动
- 微前端项目分析,如下所示:
- 主应用,注册子应用,加载、渲染子应用,路由匹配,
activeWhen、rules
由框架判断,获取数据,公共依赖,通过数据做鉴权处理,通信,父子通信、子父的通信 - 子应用的功能,渲染,监听通信,主应用传递过来的数据
- 微前端框架,子应用的注册,有开始的内容,应用加载完成,路由更新判断,匹配对应的子应用,加载子应用的内容,完成所有依赖项的执行,将子应用渲染在固定的容器内,公共事件的管理,异常的捕获和报错,全局的状态管理的内容,沙箱的隔离,通信机制
- 服务端的功能,提供数据服务
- 发布平台,主子应用的打包和发布
- 主应用,统一调度和管理子应用,
vue2
新能源页面,vue3
首页、选车,react15
资讯、视频、视频详情,react16
新车、排行、登录。同时,主应用会获取数据从服务端内容,注册应用到发布平台上,主应用也会注册子应用的列表 - 在注册子应用的列表后,就会首次加载和路由更新。在首次加载后,公共事件管理和通信,异常捕获,全局状态管理。首次加载和路由更新后,判断子应用是否匹配当前的路由。如果是,加载子应用,如果有上一个子应用则卸载,执行、解析子应用,渲染,结束。如果不是,则结束
二、微前端之实践主子应用启动配置、vue2、vue3、react15、react16 子应用的配置
- 在微前端中,一个主应用对应多个子应用,可以在
package.json
修改start
主应用的启动方式,在一个文件中启动多个子应用,比如在build
下的run.js
中。通过定义一个子应用的服务列表filePath
,然后cd
子应用的目录npm start
启动项目,代码如下:
package.json
"scripts": {"start": "node ./build/run.js"
},
build
下的run.js
const childProcess = require('child_process')
const path = require('path')const filePath = {vue2: path.join(__dirname, '../vue2'),vue3: path.join(__dirname, '../vue3'),react15: path.join(__dirname, '../react15'),react16: path.join(__dirname, '../react16'),main: path.join(__dirname, '../main')
}function runChild () {Object.values(filePath).forEach(item => {childProcess.spawn(`cd${item}&& npm start`, { stdio: "inherit", shell: true })})
}
runChild()
- 在
vue2
项目中,配置vue.config.js
文件,port
是启动的端口号,outputDir
是打包的目录,assetsDir
是打包的静态资源,filenameHashing
是打包出来的文件会带有hash
信息,publicPath
是访问路径。在devServer
中,contentBase
是当前内容打包到dist
目录中,hot
是判断是否热更新,disableHostCheck
是判断是否关闭用于DNS
重绑定的HTTP
请求的HOST
检查,关闭后可以接受来自任何HOST
的请求,port
是端口号,headers
是本地服务的跨域内容。在configureWebpack
中,自定义webpack
配置,alias
是设置别名。在output
中,libraryTarget
是把子应用打包成umd
库格式commonjs
浏览器,node
环境可运行。library
是配置成子应用的名称,通过window.vue2
获取到打包后的vue2
子应用的内容,获取到打包的内容,代码如下:
const path = require('path');function resolve(dir) {return path.join(__dirname, dir);
}const packageName = 'vue2';
const port = 9004; module.exports = {outputDir: 'dist',assetsDir: 'static', filenameHashing: true, publicPath: 'http://localhost:9004',devServer: {contentBase: path.join(__dirname, 'dist'), hot: false, disableHostCheck: true, port, headers: {'Access-Control-Allow-Origin': '*', },},configureWebpack: {resolve: {alias: {'@': resolve('src'), },},output: {library: `${packageName}`, libraryTarget: 'umd',// filename: 'vue2.js',// library: 'vue2',// jsonpFunction: `webpackJsonp_${name}`,},},
};
- 在
vue2
项目中,入口文件main.js
中,通过window.__MICRO_WEB__
判断当前环境是否是微前端环境。如果不是,则直接执行render
渲染。如果是,则对外暴露微前端的生命周期,获取到生命周期的状态,在mount
中render
。对于微前端的生命周期,bootstrap
是开始加载结构,加载前可处理参数,mount
是加载、渲染成功,unmount
是卸载,代码如下:
import Vue from 'vue'
import App from './App.vue'
import router from './router'
Vue.config.productionTip = falselet instance = null;
const render = () => {new Vue({router,render: h => h(App)}).$mount('#app-vue')
}if (!window.__MICRO_WEB__) {render()
}export async function bootstrap() {console.log('bootstrap');
}export async function mount() {render()
}export async function unmount(ctx) {const { container } = ctxif (container) {document.querySelector(container).innerHTML = ''}
}
- 在
vue3
项目中,配置vue.config.js
文件,和vue2
中的配置类似,port
端口号是不同的,filename
是设置为vue3.js
,打包的文件名称,对应的是子应用的名称。library
是设置为vue3
,在当前的全局下,拿到微前端的内容,libraryTarget
是设置为umd
,把子应用打包成umd
库格式,代码如下:
const path = require('path');const packageName = 'vue3'function resolve(dir) {return path.join(__dirname, dir);
}const port = 9005; module.exports = {outputDir: 'dist',assetsDir: 'static',filenameHashing: true,publicPath: 'http://localhost:9005',devServer: {contentBase: path.join(__dirname, 'dist'), hot: true,disableHostCheck: true,port,headers: {'Access-Control-Allow-Origin': '*',},},configureWebpack: {resolve: {alias: {'@': resolve('src'),},},output: {filename: 'vue3.js', library: `${packageName}`, libraryTarget: 'umd', jsonpFunction: `webpackJsonp_${packageName}`,// library: 'vue3'},},
};
- 在
vue3
项目中,入口文件main.js
,和vue2
中的配置类似,instance
是创建一个引用,在unmount
中清空vue3
当前根元素下的所有内容,代码如下:
import { createApp } from 'vue';
import App from './App.vue';
import router from './router';
import { setMain } from './utils/global'let instance = null; function render() {instance = createApp(App);instance.use(router).mount('#app');
}if (!window.__MICRO_WEB__) {render();
}
export async function bootstrap() {console.log('vue3.0 app bootstrap');
}export async function mount(app) {setMain(app)render();
}export async function unmount(ctx) {instance.unmount();instance = null;const { container } = ctxif (container) {document.querySelector(container).innerHTML = ''}
}
- 在
react15
项目中,在package.json
中,start
依赖的是cross-env
,需要修改webpack.config.js
文件。html-webpack-plugin
是将react15
子应用打包成所有以html
格式为出口的内容,mini-css-extract-plugin
是将所有的css
进行单独的文件提取,以及后面的引入,在output
和devServer
中,大部分与之前的vue2、vue3
项目类似,headers
是配置允许跨域,代码如下:
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')module.exports = {entry: {path: ['./index.js']},module: {rules: [{test: /\.js(|x)$/,use: {loader: 'babel-loader',options: {presets: ['@babel/preset-env', '@babel/preset-react']}}},{test: /\.(c|sc)ss$/,use: [MiniCssExtractPlugin.loader, 'css-loader', 'sass-loader']},{test: /\.(png|svg|jpg|gif)$/,use: {loader: 'url-loader',}}]},optimization: {splitChunks: false,minimize: false},plugins: [new HtmlWebpackPlugin({template: './public/index.html'}),new MiniCssExtractPlugin({filename: '[name].css'})],output: {path: path.resolve(__dirname, 'dist'),filename: 'react15.js',library: 'react15',libraryTarget: 'umd',umdNamedDefine: true,publicPath: 'http://localhost:9002/'},devServer: {headers: { 'Access-Control-Allow-Origin': '*' },contentBase: path.join(__dirname, 'dist'),compress: true,port: 9002,historyApiFallback: true,hot: true,}
}
- 在
react15
项目中,在入口文件index.js
中,与之前类似,通过window.__MICRO_WEB__
区分微前端环境。如果不是,则直接执行render
方法。如果是,暴露三个生命周期的方法,由微前端框架按照执行时机去执行对应的生命周期函数,代码如下:
import React from 'react'
import ReactDOM from 'react-dom'
import BasicMap from './src/router/index.jsx';
import "./index.scss"const render = () => {ReactDOM.render((<BasicMap />), document.getElementById('app-react'))
}if (!window.__MICRO_WEB__) {render()
}export const bootstrap = () => {console.log('bootstrap')
}export const mount = () => {render()
}export const unmount = () => {console.log('卸载')
}
- 在
react16
项目中,webpack.config.js
文件中,和之前类似,代码如下:
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')module.exports = {entry: { path: ['regenerator-runtime/runtime', './index.js'] },output: {path: path.resolve(__dirname, 'dist'),filename: 'react16.js',library: 'react16',libraryTarget: 'umd',umdNamedDefine: true,publicPath: 'http://localhost:9003'},module: {rules: [{test: /\.js(|x)$/,use: {loader: 'babel-loader',options: {presets: ['@babel/preset-env', '@babel/preset-react']}}},{test: /\.(cs|scs)s$/,use: [MiniCssExtractPlugin.loader, 'css-loader', 'sass-loader']},]},optimization: {splitChunks: false,minimize: false},plugins: [new HtmlWebpackPlugin({template: './public/index.html'}),new MiniCssExtractPlugin({filename: '[name].css'})],devServer: {headers: { 'Access-Control-Allow-Origin': '*' },contentBase: path.join(__dirname, 'dist'),compress: true,port: 9003,historyApiFallback: true,hot: true}
}
- 在
react16
项目中,入口文件index.js
中,和之前类似,代码如下:
import React from 'react'
import "./index.scss"
import ReactDOM from 'react-dom'
import BasicMap from './src/router';const render = () => {ReactDOM.render(<BasicMap />, document.getElementById('app-react'))
}if (!window.__MICRO_WEB__) {render()
}export const bootstrap = () => {console.log('bootstrap')
}export const mount = () => {render()
}export const unmount = () => {console.log('卸载')
}
微前端之实现方式和项目分析、实践主子应用启动配置、vue2、vue3、react15、react16 子应用的配置相关推荐
- 微前端在小米 CRM 系统的实践
作者 | 木子朗 https://www.lishuaishuai.com/architecture/1344.html 大型组织的组织结构.软件架构在不断地发生变化.移动优先(Mobile Firs ...
- 前端dashboard框架_微前端在网易七鱼的实践
一.前言 网易七鱼是提供围绕客户服务与智能营销的 SaaS 平台.在七鱼业务中,有在线系统.呼叫系统.机器人.工单系统.数据大屏等业务线,它们分布在两个业务端,管理端和客服端.这两个端的功能框架类似, ...
- 微前端在网易七鱼的实践
一.前言 网易七鱼是提供围绕客户服务与智能营销的 SaaS 平台.在七鱼业务中,有在线系统.呼叫系统.机器人.工单系统.数据大屏等业务线,它们分布在两个业务端,管理端和客服端.这两个端的功能框架类似, ...
- postmessage 游戏窗口内无效_前端的微前端在交通项目内的应用实践
项目背景 业务的快速发展,越来越多的接入渠道(百度.快应用等等),人员增加,开发成本与管理成本都上升,效率反而越来越低,团队的人员重复造轮子,毫无挑战,当然市面上也有多端解决方案,但是不太适用目前的业 ...
- 微前端应用及基于qiankun的微前端实践
示例代码仓库: yl-qiankun-base:https://gitee.com/dongche/yl-qiankun-base.git yl-qiankun-child-vue:https://g ...
- 浅谈微前端在滴滴车服中的应用实践
导读:如果盘点2019年最火的前端技术,那么微前端肯定占有一席之地.但是大部分人对于微前端这个架构新贵的了解还是处于懵懵懂懂的状态,本文将会详细介绍微前端的前生今世,带大家了解微前端架构是如何一步步从 ...
- 【微前端】591- 微前端在小米 CRM 系统的实践
前言 微前端跟Serverless,当前前端热门话题. @木子朗,小米 前端工程师,目前专注于前端架构.前端工程化,热衷于打造高质量.高性能.用户体验一流的产品.个人网站:https://www.li ...
- qiankun 微前端_微前端方案 qiankun(实践及总结)
❝ 作者:沉末_ 链接:https://juejin.im/post/5ed73b73e51d4578724e3fa4 ❞ 什么是微前端? 我们先来看两个实际的场景: 1. 复用别的的项目页面 通常, ...
- 爱奇艺号微前端架构实践
前言 近来,微前端的概念非常火爆,那么什么是微前端架构?微前端架构是一种架构风格类似于微服务的架构,它将微服务的理念应用于浏览器端,即将 Web 应用由单一的单体应用转变为多个小型前端应用聚合为一的应 ...
最新文章
- 《learning ROS for robotics programming》
- 进程隐藏与进程保护(SSDT Hook 实现)(三)
- 谷歌maps菜单语言设置_Google Maps:拯救未来之路— UX案例研究
- WPF快速指导2:模板
- 姐告诉你什么是C++,你懂的。
- es6中class类的全方面理解
- 人眼分辨 PPI_扒一扒,PPI、LPI、DPI分辨率三兄弟~
- python批量创建实例_Django批量创建Model实例
- 3分钟学会python_3分钟学会,学会用Python正确读取大文件
- 软件类配置(七)【ubuntu16.04安装netbeans、opencv并配置开发环境。】
- 理解Virtual方法。
- java基础总结05-面向对象
- Windows server 2003 ××× 配置实例(Site to Site)
- ghost还原提示an internal
- servlet+jsp项目改成springboot+jsp+maven
- svn管理ad元件库_AD元器件库服务器管理指南
- 武汉大学计算机科学与技术培养方案,武汉大学计算机学院培养方案(2018版)
- 人机交互-10-交互设计模型
- 2020年中国干旱灾害受灾面积、饮水困难人口数量及造成经济作物损失分析[图]
- 计算机和我的关系 论文参考文献,近几年计算机学生参考文献 计算机学生期刊参考文献哪里找...
热门文章
- 多语言在线客服系统源码-自动识别中英环境-私有化部署完美支持跨境电商网站...
- C语言——购房从银行贷了一笔款d,准备每月还款额为p,月利率为r......
- pyqt股票行情软件性能优化 差点又让python背了锅
- java全景图片生成_如何制作全景图片?
- 2020年6月最新iOS面试题总结(答案篇)
- yaml语法 关于key为中文时的问题
- Java Swing入门基础
- UIColor延伸:判断两个颜色是否相等
- echart象形图-三角锥形/山峰形/三角形--柱子渐变色,x轴换行显示,加单位显示
- Romberg积分法MATLAB实现(附代码、实例、详解)