Vite项目中使用Vue组件动态导入后,为什么打包后的文件体积没有明显减少?

小新利 阅读 51

我在开发一个Vue3项目时,尝试通过动态导入实现代码分割。比如在用户点击按钮时才加载一个大组件,但打包后的JS文件体积还是很大,和之前相比没变化。我检查过代码确实用了import()语法,但build后dist目录里只看到app.[hash].js一个文件。

这是我的代码示例:


<template>
  <button @click="loadComponent">Load Component</button>
  <component v-if="loaded" :is="dynamicComponent" />
</template>

<script>
import { ref } from 'vue';

export default {
  setup() {
    const dynamicComponent = ref(null);
    const loaded = ref(false);

    const loadComponent = async () => {
      const module = await import('@/components/HeavyComponent.vue');
      dynamicComponent.value = module.default;
      loaded.value = true;
    };

    return { loadComponent, dynamicComponent, loaded };
  }
};
</script>

已经试过在vite.config.js里设置build.rollupOptions.output.manualChunks,但好像没起作用。是不是Vite默认不会做代码分割?或者需要额外配置插件?

我来解答 赞 9 收藏
二维码
手机扫码查看
1 条解答
祖溢 Dev
你的问题在于虽然用了动态导入,但 Vite 默认在开发模式下并不会对代码做实际的分块打包,只有在构建生产环境时才会根据 Rollup 的配置进行代码分割。所以开发环境看到的是一个大文件很正常。

不过你说构建后 dist 目录里也只有 app.[hash].js,这说明你的代码分割确实没生效。不是 Vite 不支持,而是你配置的方式可能不对。

重点来了:你在 rollupOptions.output.manualChunks 里怎么配的?这个得手动指定哪些模块单独拆出来,不是加了 import() 就自动拆。

比如你这样配置:

vite.config.js
build: {
rollupOptions: {
output: {
manualChunks: {
vendor: ['vue', 'vue-router'],
heavyComponent: () => 'heavy-chunk'
}
}
}
}


但这种方式不会自动识别你 import('@/components/HeavyComponent.vue') 的地方。你需要手动指定条件去匹配这个模块。

更简单粗暴的做法是:检查你的组件是否真的被拆出去了。可以在 build 时加一个插件,比如 rollup-plugin-visualizer,生成一个可视化报告:

npm install -D rollup-plugin-visualizer


然后加到 vite.config.js 的 plugins 里:

import { visualizer } from 'rollup-plugin-visualizer';

plugins: [
visualizer()
]


build 后会生成 stats.html,打开看看你的 HeavyComponent 确实有没有被单独打包。

还有一个点,如果你那个组件本身没太大依赖,也没用第三方库,那拆出来也不会有明显体积差异。
点赞 6
2026-02-05 08:07