![「开发记录」Vite开发中的烦恼:vant组件自动引入导致的二次构建问题插图 「开发记录」Vite开发中的烦恼:vant组件自动引入导致的二次构建问题插图](https://blog.eswlnk.com/wp-content/uploads/wpcy/1b7b7d5ed47770406500d019cb49917d.jpg)
遇到的问题
最近在使用Vite开发中,引入vant组件的按需加载功能后,经常碰到以下提示:
17:33:46 [vite] ✨ new dependencies optimized: vant/es/button/style/index
17:33:46 [vite] ✨ optimized dependencies changed. reloading
然后页面就会刷新,让人感到非常难受。为了解决这个问题,我花了一些时间去了解为什么会出现这种情况。
问题原因
为了在启动时不占用大量编译时间,Vite只处理一些常用的组件和依赖,尤其是在按需加载的情况下。加上Vite本身会忽略node_modules
中的内容,导致一些按需的依赖在开发进入到对应页面时才会被处理。这就引发了一直在处理依赖优化和重新加载,导致大量的等待时间。
解决方案
目前官方并没有提供较好的解决方案,但我发现社区中有人提供了一种可行的做法,即在开发时直接全局加载优化项。
通过分析,发现vant的优化触发主要是样式加载。因此,我们可以在开发模式下将所有组件的样式都进行全局优化,从而避免出现重新加载的问题。
解决方法示例
以下是我在vite.config.ts
中应用的解决方法:
import { defineConfig, loadEnv } from "vite";
import { resolve } from "path";
import { readdirSync, statSync } from "fs";
export default ({ mode }) => {
process.env = { ...process.env, ...loadEnv(mode, process.cwd()) };
// 解决 optimized dependencies changed. reloading
const devOptimizeDepsInclude: Array<string> = [];
if (process.env.VITE_ENV === "development") {
const excludedDirs = ["utils", "style", "composables"];
const vantPath = resolve(__dirname, "./node_modules/vant/es");
const dirNames = readdirSync(vantPath);
dirNames
.filter((dirName) => {
const isDir = statSync(`${vantPath}/${dirName}`).isDirectory();
const isExcluded = excludedDirs.includes(dirName);
return isDir && !isExcluded;
})
.forEach((dirName) => {
devOptimizeDepsInclude.push(`vant/es/${dirName}/style/index`);
});
}
return defineConfig({
optimizeDeps: {
include: [...devOptimizeDepsInclude]
},
});
};
在这个配置中,我们通过devOptimizeDepsInclude
数组将所有vant组件的样式目录都包含进来,然后在optimizeDeps.include
中导入,从而解决了问题。
更加省事的配置
我发现除了include
选项,还有一个exclude
选项。如果使用include
会导致地址精度匹配非常高,所以上面的代码需要通过Node的fs
模块读取对应的目录来生成准确的地址。
但如果使用exclude
,就可以直接使用插件名,这样这个插件在使用时就不会再次被编译了。
通过这样的配置,我们更加粗暴地排除了vant及其插件,解决了问题,让配置更加省心。期待未来有更好的解决方案出现。
📮评论