尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

vite打包配置

vite打包配置 Vite 前端构建工具的探索与实践本文基于 Vite 4.x 的实践经验整理并对照 Vite 5/6/7/8 的最新规范进行了修正与补充。文中的配置示例以**稳定版Vite 4/5/6Rollup 内核**为准凡与最新版本Vite 8Rolldown Oxc 内核存在差异处均以「 版本演进」标注说明方便在不同版本间迁移。目录Vite 是什么no-bundle 理念配置文件基础CSS 处理预处理器与 PostCSS静态资源处理生产环境构建配置构建优化核心手段浏览器兼容性适配缓存策略与部署总结1. Vite 是什么no-bundle 理念Vite 是一个面向现代浏览器的前端构建工具由两部分组成开发服务器Dev Server基于浏览器原生 ES ModulesESM能力利用 esbuild 做依赖预构建实现模块的按需编译与即时加载。生产构建器使用 RollupVite 8 起为 Rolldown进行打包产出高度优化的静态资源。一个 import 即一个请求在 Vite 的开发阶段源代码中的每一条import语句都对应一次独立的 HTTP 请求import{createApp}fromvueimportAppfrom./App.vuecreateApp(App).mount(#app)上述两条语句对应两个不同的请求。Vite Dev Server 读取本地文件并返回浏览器可解析的 ESM 代码浏览器解析到新的import时再发起新请求如此递归直到资源全部加载完成。no-bundle 的真正含义开发阶段利用浏览器原生 ESM 支持按模块粒度按需加载而不是像 Webpack 那样先整体打包再加载。这省去了开发期繁琐且耗时的打包过程是 Vite 启动快、热更新快的核心原因。生产构建则不同——Vite 会完整打包以保证线上性能Tree Shaking、代码分割、压缩等。因此 Vite 是「开发用 No Bundle生产用 Bundle」的双阶段策略。2. 配置文件基础Vite 的配置文件默认名为vite.config.ts或.js/.mjs使用defineConfig以获得类型提示import{defineConfig}fromviteimportvuefromvitejs/plugin-vue// defineConfig 提供 TS 类型推导推荐始终使用exportdefaultdefineConfig({plugins:[vue()],})plugins数组用于注册 Vite/Rollup 插件。Vue 项目必须配置官方的vitejs/plugin-vue它负责.vue单文件组件的编译与 HMR热更新。配置函数的两种形态 版本演进判断环境时原文常用process.env.NODE_ENV production这在 Vite 中不够可靠——Vite 通过mode区分环境而非依赖NODE_ENV。推荐改用配置函数签名import{defineConfig,loadEnv}fromviteexportdefaultdefineConfig(({command,mode}){// command: serve开发| build生产// mode: 来自 --mode 参数如 development / productionconstisProductioncommandbuildconstenvloadEnv(mode,process.cwd(),)return{// 基于 command / mode / env 返回配置base:isProduction?env.VITE_CDN_URL||/:/,}})loadEnv可读取.env、.env.[mode]文件中的环境变量仅VITE_前缀的变量会暴露给客户端代码。3. CSS 处理预处理器与 PostCSS3.1 CSS 预处理器Sass/Scss、Less、StylusVite 对主流 CSS 预处理器内置支持只需安装对应的编译器依赖即可直接使用无需额外插件pnpmi sass-D# 以 SCSS 为例Less 装 lessStylus 装 stylus3.2 全局注入 SCSS 变量 / mixin使用css.preprocessorOptions.scss.additionalData在每个 SCSS 文件头部自动注入变量文件避免手工重复importimport{defineConfig,normalizePath}fromviteimportpathfromnode:path// normalizePath 统一各平台路径分隔符避免 Windows 下路径报错constvariablePathnormalizePath(path.resolve(./src/assets/css/vars.scss),)exportdefaultdefineConfig({css:{preprocessorOptions:{scss:{// 注意注入的内容会出现在每个文件开头因此不能包含会产生实际样式的规则// 只能放变量、mixin、function 等不产生输出的声明additionalData:import ${variablePath};,},},},})注意additionalData注入的文件中不应包含普通 CSS 规则如.foo { color: red }否则每个 SCSS 文件都会重复输出这些样式导致产物体积膨胀。它只适合放变量、mixin、函数等无副作用声明。3.3 PostCSS 配置PostCSS 用于自动补齐浏览器前缀autoprefixer、使用未来 CSS 语法postcss-preset-env等。推荐将配置抽到独立的postcss.config.js或内联在css.postcss中必须是返回对象的函数形式不要用裸对象importautoprefixerfromautoprefixerimportpostcssPresetEnvfrompostcss-preset-envexportdefaultdefineConfig({css:{postcss:{plugins:[postcssPresetEnv({autoprefixer:{overrideBrowserslist:[ 1%,last 2 versions],},}),],},},}) 版本演进原文示例中overrideBrowserslist: [Chrome 40, ff 31, ie 11]已不合时宜——IE 11 已于 2022 年停止支持现代项目无需再为其做前缀/语法降级。若确有旧浏览器需求请使用vitejs/plugin-legacy见第 7 节。 版本演进Vite 8Vite 8 默认集成Lightning CSS处理样式可在css.transformer: lightningcss启用其兼具预处理器与 autoprefixer 能力性能显著优于 PostCSS。迁移到 Vite 8 时可考虑用 Lightning CSS 替代 PostCSS 链路。4. 静态资源处理4.1 路径别名alias用指向src可避免深层相对路径../../import{fileURLToPath,URL}fromnode:urlimport{defineConfig}fromviteexportdefaultdefineConfig({resolve:{alias:{:fileURLToPath(newURL(./src,import.meta.url)),assets:fileURLToPath(newURL(./src/assets,import.meta.url)),},},}) 版本演进原文使用path.join(__dirname, src/assets)但 Vite 配置为 ESMtype: module时__dirname不可用。推荐使用fileURLToPath(new URL(...))或import.meta.dirnameNode 20.11替代。4.2 SVG 作为组件加载使用vite-svg-loader可将 SVG 直接作为 Vue 组件引入便于通过props控制颜色、尺寸importsvgLoaderfromvite-svg-loaderexportdefaultdefineConfig({plugins:[vue(),svgLoader()],})script setup import IconHome from assets/icons/home.svg?component /script template IconHome classicon / /template4.3 JSON 加载Vite 原生支持 JSON 导入并支持具名导入与 Tree ShakingexportdefaultdefineConfig({json:{// 设为 true 时整个 JSON 被序列化为默认导出名为导入会被禁用// 默认 false支持具名导入未使用的字段会被 Tree Shaking 掉stringify:false,// namedDeclaration: true // Vite 6 可为具名导入生成类型声明},})4.4 其它静态资源类型媒体mp4/webm/ogg/mp3…、字体woff/woff2/ttf…、文本pdf/txt…等 Vite 默认按资源处理。如需识别额外扩展名如.gltf用assetsIncludeexportdefaultdefineConfig({assetsInclude:[**/*.gltf],})5. 生产环境构建配置5.1 基础路径 basebase决定资源在线上的公共路径部署到 CDN 子路径或非根域名时必须配置exportdefaultdefineConfig(({command})({// 生产环境指向 CDN开发环境用 /base:commandbuild?https://cdn.example.com/assets/:/,}))代码中引用资源请使用import.meta.env.BASE_URL它会随base自动替换。5.2 资源内联阈值 assetsInlineLimit小于阈值的静态资源会被内联为 base64省去一次请求大于阈值的提取为独立文件利于缓存与并行加载。exportdefaultdefineConfig({build:{// 默认 40964 KiB。设为 0 可完全禁用内联// 也可传函数做精细化控制(filePath, content) booleanassetsInlineLimit:4096,},})说明默认 4KB 是经验值——过小则内联收益低过大则 base64 体积膨胀且失去并行加载优势。多数场景保持默认即可小图标内联、大图外链是合理策略。5.3 构建目标 build.target控制语法降级程度直接影响产物体积与兼容性exportdefaultdefineConfig({build:{// modulesVite 4/5/6 默认 支持原生 ESM 的现代浏览器// Vite 7 默认改为 baseline-widely-availableChrome111/FF114/Safari16.4 等// esnext几乎不降级体积最小但兼容性最差target:modules,},}) 版本演进Vite 7 起build.target默认值由modules调整为baseline-widely-available对齐 Baseline 标准。如项目需兼容更老浏览器见第 7 节。5.4 压缩 minifyexportdefaultdefineConfig({build:{// Vite 4/5/6 默认 esbuild快压缩率略低// Vite 8 默认 oxcRust 实现比 terser 快数十倍minify:esbuild,// 使用 terser 可获得更高压缩率但需安装 terser 且更慢// minify: terser,// terserOptions: { compress: { drop_console: true } },},}) 重要变更build.minify: esbuild在新版 Vite 中已被标记为弃用未来将移除Vite 8 默认改用基于 Rust 的 Oxc Minifieroxc。如需极高压缩率可回退terser需npm i -D terser但会显著拖慢构建。5.5 CSS 代码分割 cssCodeSplitexportdefaultdefineConfig({build:{// 默认 true异步 chunk 的 CSS 会随该 chunk 一起按需加载// 设为 false所有 CSS 提取到单一文件首屏即全量加载cssCodeSplit:true,},})6. 构建优化核心手段6.1 代码分割Code Splitting代码分割是首屏优化最关键的手段把不随首屏渲染的第三方库、路由组件拆成独立 chunk实现按需加载与并行下载。方式一基于路由的动态导入推荐零配置使用import()动态导入路由组件Vite/Rollup 会自动将其拆为独立 chunk// router.ts —— 路由级懒加载constroutes[{path:/,component:()import(/views/Home.vue)},{path:/about,component:()import(/views/About.vue)},]方式二manualChunks 手动分包对node_modules中的第三方依赖做精细化拆分使其能长期缓存、不被业务改动 invalidateexportdefaultdefineConfig({build:{rollupOptions:{output:{// 函数式按模块来源决定分包manualChunks(id){if(id.includes(node_modules)){// 体积大、变更少的库单独成包if(id.includes(echarts)||id.includes(monaco-editor)){returnheavy-vendor}returnvendor// 其余第三方库归入 vendor}},// 或用对象式精确指定注意对象式与函数式二选一// manualChunks: {// vue-vendor: [vue, vue-router, pinia],// },},},},}) 修正原文使用的vite-plugin-chunk-split并非官方方案且原文示例在 Vue 项目里错误地写成了[react, vue-router]语义混乱。官方推荐直接用 Rollup 内置的manualChunks无需额外插件。 版本演进Vite 8build.rollupOptions已成为build.rolldownOptions的别名分包配置迁移到build.rolldownOptions.output.manualChunksRolldown 语法与 Rollup 基本兼容。6.2 Tree ShakingVite 生产构建基于 Rollup/Rolldown默认开启Tree Shaking依赖 ESM 的静态分析。要使其生效需注意始终使用 ESM 语法导出/导入export/import避免 CommonJS。副作用声明在package.json中声明sideEffects字段告诉打包器哪些文件有副作用不可删除{sideEffects:[*.css,./src/polyfills.ts]}库模式外部化依赖开发库时用build.librollupOptions.external排除不应打进产物的依赖见第 5 节延伸。避免import * as _ from lodash整包引入使用import debounce from lodash/debounce或lodash-es。6.3 资源压缩与优化图片压缩修正原文推荐的vite-plugin-imagemin已停止维护且其原生依赖binaries在多数环境下安装困难。推荐替代方案构建前处理用sharp、svgoCLI在 CI 流程中预处理图片构建期替代插件vite-plugin-image-optimizer基于 sharp/svgo维护活跃现代格式优先输出 AVIF/WebP体积比 PNG/JPG 小 30%~70%// 示例使用 vite-plugin-image-optimizer需安装 sharp / svgoimport{viteImageOptimizer}fromvite-plugin-image-optimizerexportdefaultdefineConfig({plugins:[viteImageOptimizer({png:{quality:80},webp:{quality:75},svgo:{plugins:[{name:preset-default}]},}),],})JS/CSS 压缩见 5.4 节minify默认 esbuild/oxc已是较优解。6.4 构建产物分析定位体积瓶颈针对性优化pnpmadd-Drollup-plugin-visualizerimport{visualizer}fromrollup-plugin-visualizerexportdefaultdefineConfig({plugins:[visualizer({filename:dist/stats.html,open:true}),],})构建后打开dist/stats.html可直观看到每个 chunk 的体积占比。6.5 减少报警阈值与产物校验exportdefaultdefineConfig({build:{// 超过该体积未压缩 kB会输出警告提示你做代码分割chunkSizeWarningLimit:500,},})7. 浏览器兼容性适配Vite默认只做语法转换不注入 polyfill。现代浏览器无需处理若需兼容旧浏览器分两种场景7.1 语法降级 Polyfillvitejs/plugin-legacy为旧浏览器生成 legacy chunk 并自动注入SystemJSpolyfill 与core-jsimportlegacyfromvitejs/plugin-legacyexportdefaultdefineConfig({plugins:[vue(),legacy({targets:[defaults,not IE 11],// 现代浏览器无需 polyfilllegacy 包才包含modernPolyfills:true,}),],}) 修正原文给出的babel/preset-envuseBuiltIns: usage是 Babel 体系做法。在 Vite 中不应手写 Babel 配置应使用官方plugin-legacy统一处理语法降级与 polyfill 注入。7.2 CSS 兼容性目标CSS 前缀与语法降级由第 3.3 节的 autoprefixer / postcss-preset-env 的browserslist控制无需单独工具。现代项目建议# .browserslistrc 0.5% last 2 versions not dead 修正原文中IE 11的目标已无意义IE 已 EOL。除非业务强依赖否则不必再为 IE 做兼容。8. 缓存策略与部署8.1 内容哈希与长效缓存Vite 构建产物默认带内容哈希如index-a1b2c3.js内容不变则文件名不变。配合 CDN/服务器的长效缓存策略可实现「一次下载长期复用」exportdefaultdefineConfig({build:{rollupOptions:{output:{// 自定义哈希格式默认已合理通常无需改entryFileNames:assets/[name]-[hash].js,chunkFileNames:assets/[name]-[hash].js,assetFileNames:assets/[name]-[hash][extname],},},},})8.2 HTML 不缓存、静态资源长缓存index.html设Cache-Control: no-cache避免用户拿到旧 HTML 引用旧资源JS/CSS/图片设Cache-Control: max-age31536000, immutable因带哈希可安全长缓存。Vite 在动态导入失败时派发vite:preloadError事件可借此做「刷新以获取新版本」处理window.addEventListener(vite:preloadError,(){window.location.reload()})9. 总结前端构建工具并非只有 Webpack 一种答案。Vite 用「开发 No Bundle 生产 Rollup/Rolldown 打包」的双引擎策略在开发体验与产物质量之间取得了很好的平衡开发期原生 ESM 按需加载启动与热更新极快生产期RollupVite 8 为 Rolldown提供 Tree Shaking、代码分割、压缩等成熟优化开箱即用内置最佳实践别名、CSS 预处理、资源处理、哈希缓存学习成本低。本文修正与补充要点回顾原文内容问题本文修正vite-plugin-imagemin已停止维护、安装困难改用vite-plugin-image-optimizer/ sharp / svgovite-plugin-chunk-split[react,vue-router]非官方、Vue 项目误用 react改用官方manualChunksbabel/preset-env手写配置与 Vite 体系冲突改用vitejs/plugin-legacybuild.minify: esbuild新版已弃用说明弃用Vite 8 默认oxcIE 11兼容目标IE 已 EOL现代 browserslist 目标缺少优化手段漏项补充 Tree Shaking、manualChunks、产物分析、缓存策略Vite 适合写 Demo 或在新项目尤其用户范围可控的中小型项目中直接落地。对于大型存量项目建议渐进式引入如先用 Vite 做开发服务器再逐步过渡构建流程避免一次性重构带来未知风险。随着 Vite 8 统一到 Rolldown Oxc 内核构建性能与产物一致性还将进一步提升值得持续关注。
返回列表