「开发记录」Vite开发中的烦恼:vant组件自动引入导致的二次构建问题插图

遇到的问题

最近在使用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,就可以直接使用插件名,这样这个插件在使用时就不会再次被编译了。

// 更加省事的配置
optimizeDeps: {
    exclude: ["vant", "@vant/use"]
},

通过这样的配置,我们更加粗暴地排除了vant及其插件,解决了问题,让配置更加省心。期待未来有更好的解决方案出现。