內(nèi)部組件庫(kù)打包會(huì)把element-plus打包到node_modules/.pnpm/目錄問(wèn)題處理
問(wèn)題描述
將 element-plus 等第三方庫(kù)打包到內(nèi)部庫(kù)里面有可能會(huì)導(dǎo)致以下問(wèn)題:
- 應(yīng)用打包失敗
- 內(nèi)部組件庫(kù)用的 element-plus 組件是內(nèi)部庫(kù)的 element-plus 瘪阁,應(yīng)用用的 element-plus 組件是 node_modules 的 element-plus ,代碼用的不是一套邮偎,導(dǎo)致彈窗層級(jí)會(huì)有問(wèn)題管跺,會(huì)被覆蓋而看不到。(這個(gè)問(wèn)題還有其他解決方法禾进,不如這個(gè)方法好豁跑,這里就不在重點(diǎn)介紹了,大體的思路是通過(guò) useZIndex 同步各個(gè)組件庫(kù)的 zIndex , 解決多組件庫(kù)統(tǒng)一層疊順序問(wèn)題的本質(zhì)就是在項(xiàng)目的應(yīng)用層再實(shí)現(xiàn)一個(gè) zIndex 管理器泻云。管理器需要接受來(lái)自不同組件庫(kù)的 zIndex 管理器艇拍,并在任一管理器中的 zIndex 值發(fā)生變化時(shí),把變化同步到其它管理器中宠纯⌒断Γ可以參考:Element 黑魔法,統(tǒng)一多組件庫(kù)的層疊順序 https://juejin.cn/post/7131754451873824775)
解決思路
屬性 external 接收一個(gè)模塊名稱(chēng)組成的數(shù)組婆瓜,或者接收一個(gè)參數(shù)為模塊名字的函數(shù)娇哆,如果需要把某模塊設(shè)置為外部引入,只需要讓該函數(shù)返回 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: {
// 確保外部化處理那些你不想打包進(jìn)庫(kù)的依賴(lài)
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',
//讓打包目錄和我們目錄對(duì)應(yīng)
preserveModules: true,
//配置打包根目錄
dir: 'dist/es',
preserveModulesRoot: path.resolve(__dirname, '../../src'),
},
{
format: 'cjs',
entryFileNames: '[name].js',
//讓打包目錄和我們目錄對(duì)應(yīng)
preserveModules: true,
//配置打包根目錄
dir: 'dist/lib',
preserveModulesRoot: path.resolve(__dirname, '../../src'),
},
],
},
},
};
按這個(gè)配置配好后碍讨,一般的應(yīng)該不用太關(guān)心這個(gè)方法,特殊的打包有問(wèn)題了蒙秒,可以考慮一下是不是 external 這里的問(wèn)題勃黍,例如vue和內(nèi)部組件 pc- 有進(jìn)行特殊處理,避免沖突和問(wèn)題晕讲。