项目来源地址:
https://github.com/wuxiaohuaer/webpack5-vue-admin
1.什么是微前端
微前端是一个相对宏观的概念。独立的基础,独立开发、独立部署。更适合大型团队进行重型项目。
从微前端官网可以了解到,微前端的概念是从微服务的概念延伸出来的,抛弃了大单体的做法,把整个前端的末端消除成小而简单的块,可以配置、测试和部署,同时仍然组合成出现在客户面前的产品。可以理解,微前端是一种集合了可以独立交付的小型前端应用程序的架构风格。
其次,为什么要使用微前端?
某公司有类似的项目,大家可以分享讨论项。然后我们可以将它组合起来,以便其他项目可以一起使用它。
此时大家都会有疑问。如果你只是将它添加到 npm 中,它就会完成。为什么要用微末这么复杂的东西呢?
我们链接公共组件并将它们发送到 npm 包管理器。确实可以用于公司的其他项目,但是会有两个缺点。
1。程序
很复杂创建三个基础管理应用项目,并从npm包中下载相同的业务子模块。现在,如果要更新业务模块逻辑,需要执行以下操作:
更新npm包版本
更新A管理系统应用的npm包版本
发布部署A管理系统应用
对B和C管理系统应用循环2和3步骤
因为虽然有些独立,但有npm作为中介,如果你想改某个组件,就得点击整个项目。
如果我们使用微服务,我们可以将所有公共组件放在一个容器应用中,专门用于安装组件。当需要更新时,只需要重新部署这个容器应用,其他项目就可以刷新来获取最新的模块。
2。速度慢
如果项目中有n个组件,除了从npm更新之外,构建和部署时还需要进行包装,开发体验会更差。
微服务不需要在本地对这些子模块进行编码,减少了构建量,提高了开发效率。
3。前端微应用设计
业界最流行的微解决方案应该是蚂蚁团队的qiankun:
qiankun.umijs.org/zh/guide
有兴趣可以去官网了解更多
我从来没有开发过大型系统,所以对微服务不是很感兴趣。前段时间研究了webpack5,发现webpack5具有模块联合(mf)功能,这是微前端公共依赖的更好解决方案。
得益于mf的能力,我们可以完全实现去中心化的部署组:每个应用单独部署在自己的服务器上,每个应用可以引用其他应用,并且可以传输给其他应用,即每个应用可以充当主机或显示为远程。对中央应用程序一无所知。
在目前mf的基础上,更加成熟的微架构,是团队最新的微EMP解决方案YY
github.com/efoxTeam/em…
作为一只vue狗,我正在基于最新的vue3.0+webpack5部署一个基础的微服务。
4。改善环境
1。创建文件夹
// 创建文件夹
mkdir hand-vue3-project && cd hand-vue3-project
// 初始化项目
npm init -y
2。放置依赖性
yarn add webpack webpack-cli -D
3。创建文件
// 创建文件夹
mkdir hand-vue3-project && cd hand-vue3-project
// 初始化项目
npm init -y
yarn add webpack webpack-cli -D
在根文件夹中创建src、index.html和webpack.config.js文件夹,并在src文件夹中创建main.js
4。配置 webpack.config.js
// webpack.config.js
const path = require('path')
module.exports = {
mode: 'development', // 环境模式
entry: path.resolve(__dirname, './src/main.js'), // 打包入口
output: {
path: path.resolve(__dirname, 'dist'), // 打包出口
filename: 'js/[name].js' // 打包完的静态资源文件名
}
}
将scripts属性添加到package.json:
"dev": "webpack --config ./webpack.config.js"
运行一个基础包,然后导入 vue 并添加
5。工作环境
在 main.js 中打印
console.log('hello,world!')
运行命令:
yarn dev
现在可以看到dist文件夹里打包了一个js文件
5。进入vue3.0
公司项目不敢用vue3.x,所以只能在demo中展示
设置依赖关系
yarn add vue@next -S
@next -S才能下载到最新的vue版本
yarn add html-webpack-plugin -D
将 index.html 作为模板,打出到 dist 文件夹
yarn add vue-loader@next
解析和转换 .vue 文件,提取出其中的逻辑代码 script、样式代码 style、以及 HTML 模版 template
yarn add @vue/compiler-sfc
Vue 2.x 时代,需要 vue-template-compiler 插件处理 .vue 内容为 ast , Vue 3.x 则变成 @vue/compiler-sfc 。
yarn add vue-style-loader css-loader
加固元件
1,webpack.config.js
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
// 最新的 vue-loader 中,VueLoaderPlugin 插件的位置有所改变
const { VueLoaderPlugin } = require('vue-loader/dist/index')
module.exports = {
mode: 'development',
entry: path.resolve(__dirname, './src/main.js'),
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'js/[name].js'
},
module: {
rules: [
{
test: /\.vue$/,
use: [
'vue-loader'
]
},
{
test: /\.css$/,
use: [
'style-loader',
'css-loader'
]
}
]
},
plugins: [
new HtmlWebpackPlugin({
template: path.resolve(__dirname, './index.html'),
filename: 'index.html',
title: '微前端框架1'
}),
// 添加 VueLoaderPlugin 插件
new VueLoaderPlugin()
]
}
2。 src 下的文件
main.js
import { createApp } from 'vue' // Vue 3.x 引入 vue 的形式
import App from './app.vue' // 引入 APP 页面组建
const app = createApp(App) // 通过 createApp 初始化 app
app.mount('#root') // 将页面挂载到 root 节点
新app.vue
<template>
<div>距离2021年欧洲杯还有?</div>
</template>
<script>
export default {
}
</script>
现在启动yarn dev,dist目录下会放置一个index.html。打开就能看到结果,但是每次收集打开都太难了
<template>
<div>距离2021年欧洲杯还有?</div>
</template>
<script>
export default {
}
</script>
WDS简介
yarn add webpack-dev-server -D
webpack.config.js
devServer: {
contentBase: path.resolve(__dirname, './dist'),
port: 8080,
publicPath: '/'
}
package.json
"dev": "webpack serve --progress --config ./webpack.config.js"
运行纱线开发
6. 使用联邦模块实现微服务
我们将最近的项目称为 A。现在我们需要创建项目A的公共组件并将其导出
1。创建一个新项目
mountDown.vue
<template>
<div>{{ sum }}天</div>
</template>
<script>
import { defineComponent, onMounted, ref, computed } from 'vue'
export default {
setup() {
let sum = computed(() => parseInt((new Date('2021-06-13'.replace(/-/g, '/')).getTime() - new Date()) / (1000*3600*24)));
return {
sum
}
}
}
</script>
2。导出项目
webpack.config.js
const ModuleFederationPlugin = require('webpack/lib/container/ModuleFederationPlugin');
new ModuleFederationPlugin({
name: "A", // 暴露出去的模块名
filename: "remoteEntry.js", // 构建出来的文件名
exposes: {
'./countDown': './src/components/countDown.vue' // 暴露出去。key,要写相对路径
}
})
3。 B
项目简介webpack.config.js
const ModuleFederationPlugin = require('webpack/lib/container/ModuleFederationPlugin');
new ModuleFederationPlugin({
name: "B", // 暴露出去的模块名
filename: "remoteEntry.js", // 构建出来的文件名
remotes: {
A: 'A@http://localhost:8080/remoteEntry.js' // 引用
}
})
app.vue
<template>
<div>距离2021年欧洲杯还有?</div>
<countDown/>
</template>
import { defineAsyncComponent } from 'vue'
const countDown = defineAsyncComponent(() =>
import('A/countDown')
)
export default {
components: { countDown },
setup() {
return {
}
}
}
如果更改了项目A中的代码,项目B也会及时更新,如果不同的应用程序有相同的组件,则无需将相同的代码复制粘贴到每个应用程序的代码中,这就解决了跨应用程序代码共享的问题。
7。基本概念和规划
一些基本概念
• 使用Module Federation 时, 每个应用块都是一个独立的构建,这些构建都将被编译为 容器。
• 被应用的容器,被称为 remote
• 引用者,被称为 host
• 暴露出去被使用的模块,称为remote模块
集装箱分为使用和运输两部分。一个项目可以引用其他项目的组件,并且可以从其他项目公开自己的组件。
规则
经验法则是使用 jsonp。根据模块创建全局变量,根据全局变量获取不同组件的源码。
参考链接
https://codeqd.com/zb_users/upload/2023/09/6921161482663100423
https://codeqd.com/zb_users/upload/2023/09/etzwyg
发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。