在Webpack项目里,我们经常会配置resolve.alias来简化路径引用,其中@通常是src目录的别名,而~@和@在CSS中的表现存在差异,这和Webpack的CSS解析机制有关。

基础配置前提
首先我们需要在Webpack配置中定义@别名,通常指向项目的src目录,基础配置如下:
// webpack.config.js
const path = require('path');
module.exports = {
resolve: {
alias: {
'@': path.resolve(__dirname, 'src')
}
},
module: {
rules: [
{
test: /.css$/,
use: ['style-loader', 'css-loader']
},
{
test: /.(png|jpg|gif|svg)$/,
type: 'asset/resource'
}
]
}
};
@在CSS中的表现
在CSS的url()函数里直接使用@作为别名开头时,CSS-loader默认不会把@识别为Webpack的别名,而是会按照CSS原生的相对路径规则解析。比如我们在src/styles/index.css中写如下代码:
/* src/styles/index.css */
.normal-bg {
/* 这里@不会被识别为Webpack别名,会去当前CSS文件所在目录找@开头的资源,大概率会报错 */
background-image: url(@/assets/bg.png);
}
这种情况下Webpack无法正确解析路径,会提示找不到对应资源,因为CSS原生语法中没有@作为别名的规则,CSS-loader默认不会对@做特殊处理。
~@在CSS中的表现
在CSS的url()中,~符号是CSS-loader约定的特殊前缀,用来告诉CSS-loader后面的内容是Webpack的模块路径,需要交给Webpack的模块解析系统处理。因此~@的组合含义是:先通过~触发Webpack模块解析,再用@别名定位到src目录。
正确的引用方式如下:
/* src/styles/index.css */
.correct-bg {
/* ~触发Webpack解析,@指向src目录,最终会解析为src/assets/bg.png */
background-image: url(~@/assets/bg.png);
}
此时CSS-loader会把~@/assets/bg.png交给Webpack的resolve系统,结合我们配置的@别名,就能正确找到src/assets/bg.png资源。
两种写法的核心差异对比
| 写法 | 解析规则 | 适用场景 | 解析结果 |
|---|---|---|---|
| @/path | 按CSS原生相对路径解析,不触发Webpack模块解析 | 仅适用于JS文件中的路径引用 | 大概率路径解析失败 |
| ~@/path | ~触发Webpack模块解析,@作为别名参与解析 | 适用于CSS、Less、Sass等样式文件中的路径引用 | 正确解析为对应别名目录下的资源 |
特殊情况说明
如果我们修改CSS-loader的配置,开启url: { filter: (url) => url.includes('@') }之类的自定义规则,也可以让@在CSS中被识别,但这种配置会增加项目复杂度,不如直接使用~@约定更通用。
另外在JS文件中引入CSS时,我们可以直接使用@作为路径开头,因为JS的模块解析本身会走Webpack的resolve系统:
// src/main.js // JS中可以直接用@别名 import '@/styles/index.css';
总结
~@和@的核心区别是解析触发机制不同:@是Webpack的通用别名,在JS中可以直接使用,但在CSS中不会被默认解析;~@是CSS场景下的专用写法,通过~前缀触发Webpack的模块解析流程,让@别名在样式文件中生效。实际开发中,样式文件里的资源引用建议统一使用~@开头,JS文件里的路径引用使用@开头,避免路径解析错误。
WebpackCSS_路径别名~@@resolve_alias修改时间:2026-06-17 14:18:33