css 设置背景图的资源时用~@, 正常import时用@, @和~@的区别

为什么css里要这么用

background-image: url(~@/assets/imgs/decorate.png);
resolve: {
    extensions: ['.ts', '.tsx', '.js', '.jsx'],
    alias: {
        '@': path.resolve(__dirname, '../src'),
    },
},
阅读 2.7k
1 个回答

不是 CSS 要这么写,是因为你用了 Webpack 之类的构建工具,其中的 css-loader 要求你这么写。

没啥特殊的,就是路径别名(Path Alias)而已,css-loader 处理时看到了 ~ 就知道这是个别名或者 node_modules 模块了,构建时要替换成真实的相对路径。

你要问为啥要用波浪号,也没啥特殊的,只是 css-loader 的作者选择了它而已,如果当初他选的是 ^,那你今天要写的就是 ^@/assets/image.jpg 了。


如果你想问为啥只有 css-loader 需要写波浪号,而 JS 里也有路径别名,为啥不要求写呢?

其实 css-loader 这么做才是更合理的。因为路径别名其实就是一个字符串字典,不是非得定义成 @ 的,你完全可以定义成 MYROOT 之类的,使用时 ~MYROOT/assets/image.jpg

如果不加波浪号,就变成了 MYROOT/assets/image.jpg。但如果你的项目目录下真的有一个文件夹,名字就叫做 MYROOT 呢?是不是就产生歧义了?你这样写 MYROOT 到底是一个路径别名还是一个真实路径呢?

所以为了避免这种歧义,css-loader 的作者就引入了一个特殊的符号,它一定不会存在于文件名中,所以看到它才认为后面是个别名,不加它就当作是普通的相对路径,这样一来就消除了歧义。

所以写 JS 模块化 loader 的作者就没考虑这么细,是会有歧义的。但都已经发布了,积重难返,你也没办法再要求大家改过来了。


另外还有一点,css-loader 可以让你导入处于 node_modules 下的模块文件。在 JS 里由于 Node.js 的原因,当你在开头不指定 / 或者 ./ 绝对路径或相对路径时,天然就会从 node_modules 下找;而 CSS 中没有这样的规则。所以需要一个符号来告知 Webpack 从 node_modules 下找。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题