[webpack] 你真的知道 css-loader 怎么用吗?

15,604 阅读2分钟
原文链接: shuiyi.io

webpack是最近很流行的一款模块加载器兼打包工具,它能把各种资源,例如JS(含JSX)、coffee、样式(含less/sass)、图片等都作为模块来使用和处理。而loader是webpack使用中一个很重要的概念,我们可以通过loader来处理不同的文件,其中处理css的就是css-loader。css-loader,可能很多人用过,但是它都提供了什么功能,具体怎么使用,不一定都了解非常清楚。本文将对css-loader的功能做一个梳理,希望对大家使用的时候有帮助。

使用

和其他loader使用一样,我们需要现在webpack.config.js中设置css-loader(style-loader是用于将编译完成的css插入html中的工具):

loaders: [
      { test: /\.css$/, loader: "style-loader!css-loader" },
      ...
]

然后在js模块中引入你的css,例如:

var css = require("./app.css");

打包完成后你的app.css就会被编译且插入到了html中。

css-loader有以下几个参数可选:

参数 功能
root 修改css中url指向的根目录
modules 开启css-modules模式
localIdentName 设置css-modules模式下local类名的命名
minimize 压缩css代码
camelCase 给css类新增一个转换为驼峰命名的拷贝
-XXX 禁止处理某些css功能

下面我们来用实例说明如何使用这些参数。

root

对于绝对路径,css-loader默认是不会对它进行处理的 :

url(/image.png) => url(/image.png)

如果设置了root参数,root参数的值就会被添加到“/”的前面,然后会被css-loader处理:

webpack.config.js:

loaders: [
      { test: /\.css$/, loader: "style-loader!css-loader?root=./img" },
      ...
]

然后会被编译为:

url(/image.png) => url(./img/image.png)

modules

CSS MODULE是一种css in javascript的方式,当我们把一个css文件import到一个js模块时,这个css文件会暴露一个对象,这个对象映射所有的本地和全局css类名,例如:

import styles from "./style.css";

element.innerHTML = ' + styles.className + '">';

使用css-loader时可以通过设置modules参数,开启这种模式。

例如以下css:

.app{
  text-align: center;
}

如果设置了modules参数

loaders: [
      { test: /\.css$/, loader: "style-loader!css-loader?modules" },
      ...
]

会被编译为:

._2jCL78eMjlZHws9ajHxlDX{
  text-align: center;
}

它在js里暴露的对象为:

{app: "_2jCL78eMjlZHws9ajHxlDX"}

localIdentName

通常modules参数还要通过localIdentName的配合来设置css的类名。在上文中我们看到没有设置localIdentName的css编译后是一串随机字符串,可读性很差,因此我们还需要对它的类名进行处理,这就用到了localIdentName。

例如有一个名为app.css的文件:

.title{
  font-size: 16px;
}
.desc{
  text-align: center;
}

如果设置了modules和localIdentName参数

loaders: [
      { test: /\.css$/, loader: "style-loader!css-loader?modules&localIdentName=[name]---[local]---[hash:base64:5]" },
      ...
]

编译后结果为:

.app---title---103E5{
  font-size: 16px;
}
.app---desc---1LgG2{
  text-align: center;
}

补充说明: 在CSS MODULE中,可以通过给类名设置:local或:global来决定它是否是全局的css类。设置了:local的类会被编译,而设置了:global的类则会被当成是全局的类,不会被编译。如上文的css如果我们设置为:

:local(.title){
  font-size: 16px;
}
:global(.desc){
  text-align: center;
}

编译后为:

.app---title---103E5{
  font-size: 16px;
}
.desc{
  text-align: center;
}

minimize

css-loader中集成了压缩工具cssnano,上文的css设置minimize参数后,css会被压缩优化。

loaders: [
      { test: /\.css$/, loader: "style-loader!css-loader?minimize" },
      ...
]

编译后:

.title{font-size:16px}.desc{text-align:center}

camelCase

camelCase参数会为类名新增一个驼峰命名的拷贝,这个参数也需要配合modules参数使用,例如以下css:

.my-title{
  font-size: 16px;
}

设置webpack.config.js

loaders: [
      { test: /\.css$/, loader: "style-loader!css-loader?modules&camelCase" },
      ...
]

编译后暴露的对象,新增了一个驼峰命名的拷贝:

{
  my-title:"_3I8_gyz8vp7gOxXNP7ljNv",
  myTitle:"_3I8_gyz8vp7gOxXNP7ljNv"
}

此时你就可以在js中用驼峰来引用这个变量,require('app.css').myTitle

-XXX

通过设置-XXX参数,css-loader将不会处理某些css功能。 例如:

css-loader?-url // 不处理 url(...)

css-loader?-import // 不处理 @import

以上所有实际案例请移步github查看:github.com/zyf394/css-…