Vue CLI 中全局引入 CSS 变量必须通过 style-resources-loader 在编译期注入,而非 main.js 中 import;因 import 是运行时行为,不参与 Less/Sass 编译,变量不可见。

Vue CLI 项目中全局自动引入 CSS 变量(如 Less/Sass)不能靠 import 或 @import 语句手动写,必须用 loader 在编译时注入;否则变量在组件内直接使用会报 undefined variable。
为什么 main.js 里 import './assets/styles/vars.less' 不生效?
因为那是运行时加载的 CSS 文件,只生成样式规则,不向 Less 编译器暴露变量、mixin 或函数。你在 <style lang="less"></style> 里写的 @primary-color 是编译期符号,和运行时的 CSS 完全不在一个阶段。
- 手动 import 的文件不会被 less-loader 解析为“作用域上下文”,变量不可见
- 哪怕你 import 了两次,也不会触发重复定义警告——它根本没进编译流程
- scoped 样式下变量照样不可用,不是 scoped 的问题,是注入时机错了
style-resources-loader 配置必须用绝对路径 + preProcessor
这是目前 Vue CLI 3/4/5 唯一稳定支持 mixin、@import、嵌套变量的方案。关键不是“装了就行”,而是三点对齐:
-
patterns数组里每个路径必须是path.resolve(__dirname, './src/styles/variables.less'),不能写@/styles/variables.less或相对路径../styles/variables.less,否则构建时报Cannot find module -
preProcessor必须设为'less'(或'sass'),且值要和<style lang="xxx"></style>中的 lang 严格一致,大小写敏感 - 被注入的
variables.less文件本身不能有语法错误:漏分号、括号不闭合、@import路径错,都会导致整个样式编译失败,页面白屏
css.loaderOptions.less.globalVars 只能塞字符串字面量
这个配置看着简洁,但底层走的是 Less 的 modifyVars,它把对象值全转成字符串字面量塞进去,所以:
从零开始编排 SpringBoot+Vue 全栈项目工作流,适用于新建全栈项目或完整脚手架请求,触发后依次调用 product‑spec‑builder(需求调研)等模块。
立即学习“前端免费学习笔记(深入)”;
- 写
{ primaryColor: '#1890ff' }✅ 可用 - 写
{ theme: '@import "./theme.less"' }❌ 报ParseError: Unexpected token @ - 写
{ secondary: 'darken(@primaryColor, 10%)' }❌darken函数未注册,报 undefined function - 写
{ baseFontSize: '14px' }✅,但没法参与 calc() 运算(因为是字符串,不是 number 类型)
重启后变量仍不生效?先清缓存再查 loader 加载顺序
Vue CLI 会缓存 webpack 配置,改了 vue.config.js 不一定立刻生效:
- 必须彻底终止
npm run serve进程,再删掉node_modules/.cache目录(不是只删.cache子目录) - 确保
style-resources-loader在less-loader之前执行:它负责把内容“追加到每个 style 块开头”,顺序反了就等于没加 - 检查
variables.less里有没有把 mixin 写在媒体查询里,比如@media (min-width: 768px) { .my-mixin() { ... } }—— loader 只注入顶层内容,这种会被忽略
真正麻烦的点不在配置写法,而在「注入内容是否被 less 编译器识别为有效上下文」——变量名拼错、路径多一层 ../、少一个分号,都可能让整个注入静默失败,连 warning 都不抛。建议第一次配通后,立刻在某个组件里写个 @debug @nonexistent-var; 看控制台是否报错,来验证注入通道是否真实打通。

















