2021-10-21 18:07:55
在 Vite + Svelte 项目中,优化条件动态导入的核心策略是通过静态分析实现死代码消除,确保仅打包实际执行的模块。主要方法包括利用 Vite 环境变量或 @rollup/plugin-replace 插件,使条件判断在构建阶段可被打包器解析,从而移除未使用的动态导入。
一、动态导入的默认行为与问题默认行为:Vite 会将动态导入(import())的模块打包为独立 chunk,即使未被调用也会保留在最终构建中。例如:
const imports = { 'basic': () => import('./BasicTemplate.svelte'), 'advanced': () => import('./AdvancedTemplate.svelte')};const templateKey = __CONFIG__.template; // 运行时确定imports[templateKey]().then(...);打包器无法静态分析 templateKey 的值,会保留所有潜在模块。
问题:未执行的分支模块仍会被打包,增加初始加载体积。
定义环境变量:在 .env.production 中设置以 VITE_ 开头的变量。VITE_TEMPLATE=advanced
代码中使用:通过 import.meta.env 访问变量,构建时会被替换为实际值。const getModule = import.meta.env.VITE_TEMPLATE === 'advanced' ? () => import('./AdvancedTemplate.svelte') : () => import('./BasicTemplate.svelte');
效果:打包器识别 VITE_TEMPLATE 为常量,移除未执行的分支模块。
安装插件:npm install -D @rollup/plugin-replace
配置 Vite:在 vite.config.js 中替换全局变量。import replace from '@rollup/plugin-replace';const BUILD_CONFIG = { template: 'advanced' };export default defineConfig({ plugins: [ svelte(), replace({ __CONFIG__: JSON.stringify(BUILD_CONFIG), preventAssignment: true }) ]});
代码中使用:替换后的变量可被静态分析。const getModule = __CONFIG__.template === 'advanced' ? () => import('./AdvancedTemplate.svelte') : () => import('./BasicTemplate.svelte');
效果:插件将 __CONFIG__ 替换为常量,打包器移除死代码。
使用 rollup-plugin-visualizer 可视化 bundle 内容,确认未使用模块被移除。
检查生产构建的输出文件,确保优化生效。
未优化代码(无法静态分析):
const imports = { 'basic': () => import('./BasicTemplate.svelte'), 'advanced': () => import('./AdvancedTemplate.svelte')};const templateKey = __CONFIG__.template; // 运行时确定imports[templateKey]().then(...); // 两个模块均被打包优化后代码(静态可分析):
// 使用环境变量const getModule = import.meta.env.VITE_TEMPLATE === 'advanced' ? () => import('./AdvancedTemplate.svelte') : () => import('./BasicTemplate.svelte');getModule().then(...); // 仅打包实际使用的模块通过 Vite 环境变量 或 @rollup/plugin-replace,将条件判断转化为构建时可解析的常量表达式,使打包器能执行死代码消除。此方法可显著减小初始包体积,提升加载性能。优化时需确保条件静态可分析,并验证构建结果以确认效果。