Less 本身并不能直接识别 @ 这类路径别名,前面必须补上一个 ~,Webpack 才会接管并执行模块解析;否则,它只会严格按照文件系统中的相对路径去查找,结果通常就是 404。这个规则在 @import、url() 和 data-uri() 中都完全一致,写法都需要带上 ~,例如 @import "~@/styles/vars.less"。简单来说,~ 就是 Webpack 用来明确模块解析边界的标记;一旦漏写,路径解析就会重新交还给文件系统,最终自然导致路径失效。

Less 默认不识别 @ 别名,必须添加 ~ 前缀才能触发 Webpack 的模块解析机制,否则都会按文件系统相对路径查找,最终出现 404 或找不到文件的报错。
@import 中写 @/xxx.less 报错
Less 编译器只能识别真实存在的文件路径,而 @ 这种写法本质上属于 Webpack 中 resolve.alias 提供给 JS 的路径别名能力,放到 .less 文件里后,并不会自动按照这套规则解析。像 Less resolver error: '@/styles/vars.less' wasn't found 这样的错误提示,通常就是 Less 路径别名无法识别的典型表现。
- 错误写法:
@import "@/styles/vars.less";—— Less 会直接去当前 .less 文件所在目录下查找@/styles/...这个子目录 - 正确写法:
@import "~@/styles/vars.less";——~是 Webpack 传递给 loader 的解析信号,表示“这是模块路径,请按 alias 别名规则处理” - 如果已经配置了
lessOptions.paths(例如paths: [path.resolve(__dirname, 'src/styles')]),还可以简写成@import "~vars.less";
url() 和 data-uri() 里用 @/ 路径失败
与 @import 的原理相同,url('./xxx.png') 在 Less 中默认会被 css-loader 当作普通路径处理,并不会自动解析 . 和 ..;而 url('@/assets/logo.png') 则更容易被当成字面量字符串,导致 Webpack 无法介入解析,因此经常出现资源路径失效的问题。
- 推荐方案:
background: url('~@/assets/logo.png');—— 使用~触发 Webpack 模块解析,最稳定也最常用 - 备选方案:增加
resolve-url-loader(放在less-loader之前),它可以重写url()中的相对路径 - 临时 hack:
background: url('./assets/logo.png');—— 反斜杠转义点号,仅适用于单层相对路径场景,不建议长期使用 data-uri()中同样需要加~,例如data-uri('~@/icons/close.svg')
Webpack 配置漏掉 ~ 或 paths 导致 AntD 等第三方库引入失败
例如 @import '~antd/es/style/themes/index.less'; 出现报错时,通常并不是 antd 没有安装成功,而是 less-loader 没有正确配置 paths,或者 Webpack 的 resolve.alias 没有覆盖到 ~antd 这一类模块路径。
- 最稳妥的做法:在
less-loader的lessOptions中显式加入paths,例如paths: [path.resolve(__dirname, 'node_modules')] - 或者在 Webpack 的
resolve.alias中补全:'~antd': path.resolve(__dirname, 'node_modules/antd'),并确保这个 alias 同时能被less-loader和css-loader正常识别 - 临时绕过方案:
@import 'antd/es/style/themes/index.less';—— 去掉~,依赖 Webpack 默认的node_modules查找机制,但会失去 alias 配置带来的灵活性
Vite 中用 additionalData 注入变量文件时别名失效
Vite 的 CSS 插件虽然能够捕获 .less 文件,但 additionalData 中的 @import 实际上是由 Less 引擎在运行时执行的,此时 Vite 的别名解析机制已经不再生效,因此很容易出现变量文件路径别名失效的问题。
- 错误写法:
additionalData: `@import "@/styles/variables.less";`—— 通常会静默失败,HMR 不触发,变量直接变成undefined - 正确写法:
additionalData: `@import "${path.resolve(__dirname, 'src/styles/variables.less')}";`—— 必须改为绝对路径 - 同时还要确认
lessOptions.ja vascriptEnabled: true已开启,否则@import可能不会被正常执行
真正容易被忽视的一点是:所有 Less 路径别名报错的核心并不在于“怎么写更简洁”,而在于“究竟是谁在解析、在哪个阶段解析、又是按照什么规则解析”。~ 并不是语法糖,它是 Webpack 用来显式划分解析边界的重要信号;一旦漏掉,就等于把模块路径重新交给文件系统处理——而文件系统本身根本不知道 @ 代表什么,所以路径识别失败也就成了必然结果。
