Vite 4 默认开箱即用支持 Less,只需安装 less(v4+),无需 less-loader;全局变量需通过 css.preprocessorOptions.less.additionalData 注入,CSS 压缩由构建链自动完成,依赖 build.minify 和 cssCodeSplit 启用。

直接上结论:Vite 4 默认支持 Less,无需额外 loader;但要输出压缩后的 CSS,必须确认构建阶段启用 cssCodeSplit 和 minify,且不能依赖开发时的 additionalData 配置来“假装已压缩”。
确认 Vite 4 的 Less 支持是否开箱即用
Vite 4(基于 esbuild + Rollup)对 Less 的支持是原生的——只要安装了 less(运行时依赖),less-loader 不再需要。这是和 Webpack 的关键区别,也是最容易踩坑的地方:
- ✅ 正确做法:
npm install less --save-dev(仅此一条) - ❌ 错误做法:再装
less-loader@7.x或less-loader@8.x,Vite 会忽略它,甚至在某些版本报Cannot find module 'less-loader' - ⚠️ 注意:
less包必须是 Dart Sass 的同级替代(即官方推荐的lessv4+),旧版less(v3)可能不兼容 ESM 环境
全局变量注入要用 additionalData,不是 @import 文件
很多人试图在 main.ts 或组件里 @import './styles/variables.less' 实现全局变量,结果变量只在当前文件生效,或编译报错 Cannot resolve。Vite 的正确姿势是通过配置注入:
- 在
vite.config.ts的css.preprocessorOptions.less.additionalData中写入@import语句 - 路径必须是相对于项目根目录的绝对路径,例如:
@import "@/styles/variables.less";(前提是已配resolve.alias) - 不要在
additionalData里写多条@import,每条都需以分号结尾,否则 Less 解析失败 - 示例配置片段:
css: {
preprocessorOptions: {
less: {
additionalData: `@import "@/styles/variables.less"; @import "@/styles/mixins.less";`
}
}
}
压缩 CSS 不靠 Less 编译器,而靠 Vite 构建链
Less 本身不负责压缩(--clean-css 是旧 CLI 工具逻辑),Vite 生产构建时的 CSS 压缩由 esbuild(开发期)和 rollup-plugin-css-only + cssnano(生产期)协同完成。关键点:
立即学习“前端免费学习笔记(深入)”;
- 默认开启:Vite 4 生产构建(
vite build)自动启用 CSS 压缩,无需额外插件 - 验证方式:构建后查看
dist/assets/index.*.css,内容应无换行、空格被删减,color: #000变成color:#000 - 若未压缩,检查是否误设
build.minify: false,或覆盖了build.cssCodeSplit: false(这会导致 CSS 不进压缩流水线) - 想微调压缩行为(比如保留注释),需引入
cssnano并自定义build.rollupOptions.plugins,但绝大多数项目不需要
跨项目复用 Less 变量时,paths 必须显式声明
当你把 @myorg/styles 这类公共 Less 包通过 npm link 或 file: 引入,Vite 默认找不到它的子路径(如 @import "mixins/border-radius")。这不是 Less 的 bug,而是 Node.js 模块解析规则在 Less 中未自动继承:
- 必须在
vite.config.ts中为 Less 显式配置paths:
css: {
preprocessorOptions: {
less: {
paths: [
path.resolve(__dirname, 'node_modules/@myorg/styles'),
path.resolve(__dirname, 'src/styles')
]
}
}
}
-
paths是数组,不能只写一个;顺序决定查找优先级 - 禁止在公共包内部使用相对路径
@import "../core/variables",它在被引用时基准目录是调用方文件,而非包自身 - 最稳方案:所有公共包内
@import都用包名前缀,如@import "@myorg/styles/variables",并在paths中包含该包路径
真正容易被忽略的是:Vite 的 additionalData 注入发生在每个 Less 文件编译前,它不改变文件物理路径,也不触发模块解析重试。所以一旦 paths 漏配,错误往往表现为 “variable is undefined”,而不是 “file not found”。


















