webpack是最近很流行的一款模块加载器兼打包工具,它能把各种资源,例如JS(含JSX)、coffee、样式(含less/sass)、图片等都作为模块来使用和处理。而loader是webpack使用中一个很重要的概念,我们可以通过loader来处理不同的文件,其中处理css的就是css-loader。css-loader,可能很多人用过,但是它都提供了什么功能,具体怎么使用,不一定都了解非常清楚。本文将对css-loader的功能做一个梳理,希望对大家使用的时候有帮助。
使用
css-loader会遍历css文件,找到所有的url(...)并且处理。style-loader会把所有的样式插入到你页面的一个style
和其他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 = '<div class="' + 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查看:https://github.com/zyf394/css-loader-demo