发布远程组件vue2+Webpack和vue3+vite
发布远程组件 Webpack与vite
- Webpack版本
- 一、旧项目A导出组件
- 二、旧项目引入并使用A项目导出组件
- 报错1:webpack/sharing/consume/default/vue/vue
- 报错2:bootstrap.js:7 [Vue warn]: Failed to resolve async component: () => __webpack_require__.e(/*! import() */ "webpack_container_remote_remote-
- 这个问题没解决 带更新。。。。。
- vite版本
- 一、旧项目A导出组件
- 1. 安装插件
- 2. vite.config.ts配置
- 二、旧项目引入并使用A项目导出组件
- 1. vite.config.ts配置
- 2. main.ts引入
- 3. 页面中使用
- 4. 效果如下:
使用场景:旧项目中个别模块在其它项目中也要用到,如果重新开发会导致后期维护2套代码,同时也不想用嵌入式使用。
示例:比如A项目中有个弹窗模块,我想在B项目中不打开A项目情况下直接调用该弹窗组件。
Webpack版本
主要是用modulefederation模块–>官网文档
ModuleFederationPlugin基本配置
name: 应用名称,需要唯一
filename:入口文件名称,用于对外的入口文件名
exposes: 暴露出去的文件名称,被引用的
remotes:依赖的远程模块,用于引入外部其他模块
shared:共享配置–>官网文档
升级
一、旧项目A导出组件
const { defineConfig } = require('@vue/cli-service')
const packageName = require('./package.json').name;
const { ModuleFederationPlugin } = require('webpack').container;// 用于将本项目组件导出成远程组件
module.exports = defineConfig({
transpileDependencies: true,
lintOnSave: false,
configureWebpack: {
//导出组件
plugins: [
new ModuleFederationPlugin({
name: 'remoteApp1', // 远程应用的名称
library: { type: 'var', name: 'remoteApp1' },
filename: 'js/remoteEntry.js', // 暴露给宿主应用加载的远程 entry 文件
exposes: {
'./Ball': './src/components/ball.vue', // 注意 Vue 组件的路径可能需要调整,确保 webpack 能正确处
},
shared: {
// 与 host 配置一致
vue: {
singleton: true,
eager: true, // 如果需要立即加载
requiredVersion: '^2.6.14',
},
lodash: {
singleton: true,
}
}
}),
],
},
})
二、旧项目引入并使用A项目导出组件
const { defineConfig } = require('@vue/cli-service')
const { ModuleFederationPlugin } = require('webpack').container;// 用于将本项目组件导出成远程组件
module.exports = defineConfig({
transpileDependencies: true,
configureWebpack: {
plugins: [
new ModuleFederationPlugin({
name: 'host', // 主机应用的名称
remotes: {
// 远程应用的名称和它的入口文件 URL
remoteApp1: 'remoteApp1@http://112.124.38.79:8070/js/remoteEntry.js',
},
shared: {
// 列出主机应用和远程应用都需要的共享库
vue: {
singleton: true,
eager: false, // 通常不需要为 Vue 设置为 eager
requiredVersion: '^2.6.14', // 与远程应用中指定的版本相匹配
},
// 其他共享库...
},
}),
],
}
})
报错1:webpack/sharing/consume/default/vue/vue
官网有说需要改造import(‘./bootstrap’)
之后重启项目就好了
报错2:bootstrap.js:7 [Vue warn]: Failed to resolve async component: () => webpack_require.e(/*! import() */ "webpack_container_remote_remote-
这个问题没解决 带更新。。。。。
vite版本
一、旧项目A导出组件
1. 安装插件
挑选一个安装或者其他也行,我是刚开始失败好几次才下载成功
// 使用npm
npm install @originjs/vite-plugin-federation
// 使用yarn
yarn add @originjs/vite-plugin-federation
2. vite.config.ts配置
// 远程组件
// https://vitejs.dev/config/
export default defineConfig({
plugins: [
vue(),
vueJsx(),
federation({
name: "remote-app",//远程模块的模块名称
filename: 'remoteEntry.js', // 打包后生成该文件,需要导入到B项目使用作为远程模块的入口文件
exposes: {//暴露的组件列表,可以放多个
'./details': './src/components/popover/index/details.vue',//要导出的组件
},
// 共享依赖声明 这里不添加的话 加载之后没有ui组件库样式
shared: ["vue"],
}),
],
// 打包配置
build: {
target: "esnext",//这个要配置 不然会报错
},
},
})
二、旧项目引入并使用A项目导出组件
1. vite.config.ts配置
// https://vitejs.dev/config/
export default defineConfig({
plugins: [
vue(),
federation({
name: 'host-app',
remotes: {//远程模块入口文件
remote_app: "http://192.168.50.248:5189/dist/assets/remoteEntry.js",//这里是A项目地址
},
shared: ['vue']
})
],
build: {
target: "esnext",
},
2. main.ts引入
//使用远程组件
const details = defineAsyncComponent(() => import("remote_app/details"));
app.component("Details", details);
3. 页面中使用
<el-dialog v-model="dialogVisible" title="xxxx" width="800">
<!-- Details直接使用因为 main.js已经引入过了 -->
<Details v-if="dialogVisible" :dataDetails="data" ></Details>
</el-dialog>
4. 效果如下:
我本地测试的需要B项目做接口代理才可以用