vite-plugin-federation
1.vite-plugin-federation
为vite
提供 ( webpack5 也有 muodule federation 功能类似 ),用于支持多个独立构建的应用可以将自己的部分能力作为组件提供出来,组成一个应用程序。他们之间不存在相互依赖,可以进行独立的开发和部署,与webpack-module-federation 特性相似,module federation是希望动态引用其他应用的模块,这里的模块与通常意义上的应用级微前端相比,要小.
2.比如我们通常要公共使用的头部导航,侧边栏等。各个应用独立构建、打包、部署,按需引用、组合成一个新的应用。通常各个引用之间是通过统一入口文件中,对外暴露模块及其相关信息,通过异步引用的的手段,加载共享出来的模块,供自己使用
3, 去中心化 微前端概念
example
home项目
/home/goodslist.vue
<script setup lang="ts">
import { ref, reactive } from 'vue'
interface goodsInfo {
name: String
price: Number
shape: Number
desc: string
}
const title = ref('商品列表')
const goodsList: [goodsInfo] = reactive([
{
name: '西红柿',
price: 9.9,
shape: 10,
desc: '只要9.9',
},
])
function selected(data: Object) {
console.log(data)
}
</script>
<template>
<div>
<h1>{{ title }}</h1>
<div class="goodslist">
<div
class="item"
v-for="(item, index) in goodsList"
:key="index"
@click="selected(item)"
>
<div class="img">1</div>
<div class="info">
<div class="title">{{ item.name }}</div>
<div class="desc">
<div class="title">{{ item.price }}</div>
<div class="shape">{{ item.shape }}</div>
</div>
</div>
</div>
</div>
</div>
</template>
// home/vite.config.ts
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
//npm i @originjs/vite-plugin-federation (已安装跳过)
import federation from "@originjs/vite-plugin-federation"; // 引入
export default defineConfig({
plugins: [
vue(),
federation({
name: "home",//自定义项目名称,调用时需要
filename: "remoteEntry.js",// 自定义构建文件名称,调用时需要
remotes: {
// '远端模块名称':'远端模块入口文件地址'
// ....
},
exposes: {
//.... 暴露组件
"./Goodslist":"./src/components/goodsList.vue"
...
},
shared: ["vue"] //依赖
})
],
build: {
target: ['edge90', 'chrome90', 'firefox90', 'safari15'], //非行内样式,需要构建规格为es2020,存在样式不生效/报错
}
})`
app项目
// app/vite.config.ts
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import federation from "@originjs/vite-plugin-federation";
export default defineConfig({
plugins: [
vue(),
federation({
name: "App",
filename: "remoteEntry.js",
remotes: {
home:'http://localhost:5174/dist/assets/remoteEntry.js'
// http://localhost:5174 本地服务地址
// dist/assets/remoteEntry.js 构建文件路径
},
shared: ["vue"]
})
],
})
// 这里不能使用setup 语法糖. 不支持es6 导出方式
<script lang="ts">
import { defineAsyncComponent } from 'vue'
//异步引入组件
const goodslist = defineAsyncComponent(() => import('home/Goodslist'))
export default {
components: {
HelloWorld,
//注册组件
goodslist,
},
}
</script>
<template>
// 组件引用
<goodslist />
</template>