如何基于同一代码源构建不同版本的项目包并精简体积?
解决Vite构建阶段排除路由对应代码的方案
你当前的问题在于,路由过滤是运行时操作,Vite无法提前预判哪些路由会被移除,所以所有组件的动态导入都会被打包进产物里。要实现构建阶段就排除不需要的代码,得让Vite能静态分析出哪些代码不需要打包,下面是两种可行方案:
方案一:静态条件拼接路由数组
利用Vite在构建时会静态替换环境变量的特性,把需要排除的路由放在静态判断的分支里,这样Tree Shaking会自动移除不会执行的代码块:
import App from "@/App.vue"; import { createRouter, createWebHistory } from 'vue-router'; // 基础路由:轻量版和完整版都包含的部分 const baseRoutes = [ { path: "/", name: "main", component: App }, { path: "/login", name: "login", component: () => import("@/routes/Login.vue") }, { path: "/sign-up", name: "sign-up", component: () => import("@/routes/CreateAccount.vue"), }, ]; // 仅完整版需要的路由:构建时会根据环境变量决定是否保留 const fullOnlyRoutes = import.meta.env.VITE_BUILD_MODE !== 'light' ? [ { path: "/settings", name: "settings", component: () => import("@/routes/Settings.vue"), }, // 其他需要排除的路由都放在这里 ] : []; // 合并路由 const routes = [...baseRoutes, ...fullOnlyRoutes]; const router = createRouter({ history: createWebHistory(), routes, }); export default router;
当你执行vite build --mode light时,fullOnlyRoutes会被静态解析为空数组,里面的import("@/routes/Settings.vue")因为永远不会被执行,会被Vite的Tree Shaking完全移除,对应的组件代码不会出现在最终打包产物里。
方案二:拆分路由文件(适合路由较多的场景)
把轻量版和完整版的路由分别放在不同文件中,再通过环境变量动态导入对应文件:
- 创建
routes-light.js(轻量版路由):
import App from "@/App.vue"; export default [ { path: "/", name: "main", component: App }, { path: "/login", name: "login", component: () => import("@/routes/Login.vue") }, { path: "/sign-up", name: "sign-up", component: () => import("@/routes/CreateAccount.vue"), }, ];
- 创建
routes-full.js(完整版路由):
import App from "@/App.vue"; export default [ { path: "/", name: "main", component: App }, { path: "/login", name: "login", component: () => import("@/routes/Login.vue") }, { path: "/sign-up", name: "sign-up", component: () => import("@/routes/CreateAccount.vue"), }, { path: "/settings", name: "settings", component: () => import("@/routes/Settings.vue"), }, // 其他完整版专属路由 ];
- 在主路由文件
router/index.js中动态导入:
import { createRouter, createWebHistory } from 'vue-router'; // 根据环境变量导入对应路由文件 const routes = await import( import.meta.env.VITE_BUILD_MODE === 'light' ? './routes-light.js' : './routes-full.js' ); const router = createRouter({ history: createWebHistory(), routes: routes.default, }); export default router;
这种方式逻辑更清晰,维护起来更方便,构建时Vite只会打包对应路由文件里引用的组件,完全排除不需要的代码。
关键注意事项
- 必须使用
import.meta.env(Vite标准环境变量方式),且环境变量要以VITE_开头,这样Vite才能在构建时静态替换。你可以创建.env.light文件,内容为VITE_BUILD_MODE=light,构建时用vite build --mode light加载该环境配置。 - 组件导入必须用动态导入(
() => import()),这样Vite才能做代码分割和Tree Shaking。如果是静态导入(import Settings from '@/routes/Settings.vue'),即使路由被排除,组件代码还是会被打包。 - 验证结果:构建完成后,查看
dist目录下的chunk文件,确认被排除的组件(比如Settings.vue)对应的chunk不存在,就说明配置生效了。
内容的提问来源于stack exchange,提问作者ldekester
相关产品推荐
相关产品推荐

