内部组件库打包会把element-plus打包到node_modules/.pnpm/目录问题处理
问题描述
将 element-plus 等第三方库打包到内部库里面有可能会导致以下问题:
- 应用打包失败
- 内部组件库用的 element-plus 组件是内部库的 element-plus ,应用用的 element-plus 组件是 node_modules 的 element-plus ,代码用的不是一套,导致弹窗层级会有问题,会被覆盖而看不到。(这个问题还有其他解决方法,不如这个方法好,这里就不在重点介绍了,大体的思路是通过 useZIndex 同步各个组件库的 zIndex , 解决多组件库统一层叠顺序问题的本质就是在项目的应用层再实现一个 zIndex 管理器。管理器需要接受来自不同组件库的 zIndex 管理器,并在任一管理器中的 zIndex 值发生变化时,把变化同步到其它管理器中。可以参考:Element 黑魔法,统一多组件库的层叠顺序 https://juejin.cn/post/7131754451873824775)
解决思路
属性 external 接收一个模块名称组成的数组,或者接收一个参数为模块名字的函数,如果需要把某模块设置为外部引入,只需要让该函数返回 true。例如:
export default {
// ...
external: id => /lodash/.test(id)
}
解决方案:具体配置
/** @format */
// vite.config.js
import path from 'path';
import packageJsonObj from '../../package.json';
const { peerDependencies, dependencies } = packageJsonObj;
const externalList = [...Object.keys(peerDependencies), ...Object.keys(dependencies)];
export default {
build: {
lib: {
entry: path.resolve(__dirname, '../../src/entry/lib/main/index.ts'),
name: 'PowerComponentsMain',
formats: ['es', 'cjs'],
// the proper extensions will be added
fileName: 'index',
},
sourcemap: true,
rollupOptions: {
// 确保外部化处理那些你不想打包进库的依赖
external: (id) => {
const str = `${externalList.join('|').replaceAll('/', '[\\\\/]')}`;
const newId = id.replaceAll('.vue', '').replaceAll('?vue', '').replaceAll('vue&', '');
const regExp = new RegExp(str);
let external = false;
if (newId.indexOf('pc-') > -1) {
external = false;
} else {
external = regExp.test(newId);
}
return external;
},
// external: [
// '@element-plus/icons-vue',
// '@vueuse/core',
// 'ace-builds',
// 'ace-builds/src-min-noconflict/mode-javascript',
// 'js-cookie',
// 'quill',
// 'element-plus/es',
// 'element-plus',
// 'axios',
// 'dayjs',
// 'echarts',
// 'pinia',
// 'vue',
// 'vue-router',
// ],
input: [path.resolve(__dirname, '../../src/entry/lib/main/index.ts')],
output: [
{
format: 'es',
//不用打包成.es.js,这里我们想把它打包成.js
entryFileNames: '[name].js',
//让打包目录和我们目录对应
preserveModules: true,
//配置打包根目录
dir: 'dist/es',
preserveModulesRoot: path.resolve(__dirname, '../../src'),
},
{
format: 'cjs',
entryFileNames: '[name].js',
//让打包目录和我们目录对应
preserveModules: true,
//配置打包根目录
dir: 'dist/lib',
preserveModulesRoot: path.resolve(__dirname, '../../src'),
},
],
},
},
};
按这个配置配好后,一般的应该不用太关心这个方法,特殊的打包有问题了,可以考虑一下是不是 external 这里的问题,例如vue和内部组件 pc- 有进行特殊处理,避免冲突和问题。