默认情况下,Webpack 不支持处理样式文件,需要借助于 loader
和 插件。
加载 css 文件
要加载 css 文件,我们需要 css-loaderopen in new window 和 style-loaderopen in new window.
css-loader 会在所有匹配到的文件中查找 @import
和 url()
语句,并将它们当成普通的 import 语句来处理。如果 @import
语句指向了一个外部资源,比如一个 url 链接,那么 css-loader 会跳过。
style-loader 会将样式注入到 html 上的 style 元素中。可以通过配置来修改将样式注入 style 元素的方式。同时 style-loader 也实现了 HMR 接口,提供了更好的开发体验。
将样式内联到页面中通常不是一个好的实践方式,我们需要使用 MiniCssExtractPlugin
这个插件来讲 css 导出到文件中。这个插件后面章节会做说明。
安装依赖包:
npm add css-loader style-loader --develop
在 webpack.parts.js 中添加
exports.loadCSS = () => ({
module: {
rules: [{ test: /\.css$/, use: ['style-loader', 'css-loader'] }],
},
});
2
3
4
5
上面的配置说明如果文件是 .css
结尾,则需要使用这两个 loader。loader 返回处理后的文件内容,loader 之间可以像 Unix 的管道一样连接起来,从右向左一次处理:
styleLoader(cssLoader(input));
将配置组合到 webpack.config.js 中
const commonConfig = merge([...parts.loadCSS()]);
添加初始样式
src/main.css
body {
background: cornsilk;
}
2
3
在代码中引用这段样式, src/index.js
import "./main.css";
...
2
启动开发服务器 npm run start
,可以看到浏览器中的背景色发生了变化。这时,修改背景色为 background: lime
, 浏览器中的背景色会发生相应变化。
PostCSS
PostCSSopen in new window 允许你通过其提供的各种插件对 CSS 做各种转换处理。PostCSS 类似于处理样式的 Babel。后面章节会做说明。
使用 CSS 预处理器
Webpack 支持多种主流的 CSS 预处理器。
- 可以通过 less-loaderopen in new window 使用 less 预处理器。
- 可以通过 sass-loaderopen in new window 或者 fast-sass-loaderopen in new window 来使用 sass 预处理器。
- 可以通过 stylus-loaderopen in new window 来使用 stylus 预处理器。
深入理解 css-loader
要更好的使用 css-loader,首先需要明白 css-loader 是如何查找文件的。css-loader 默认只处理相对路径导入的模块,绝对路径导入(url("https://mydomain.com/static/demo.png")
)或者根路径导入(url("/static/img/demo.png")
)的模块不会被处理。
如果项目中需要使用到这些外部模块,需要将这些模块拷贝到项目中来,可以借助 webpack-copy-pluginopen in new window 完成。
如果你需要自定义 css-loader 如何处理要导入的模块,你需要设置 importLoaders
这个选项,来告诉 css-loader 在处理待导入模块之前,该模块必须要被多少个其他模块处理过。
举个例子加以说明。比如需要在 css 文件导入一个 sass 文件,@import "./variables.sass";
, 那么为了能处理 sass 文件,loader 的配置需要配置为:
const config = {
test: /\.css$/,
use: [
'style-loader',
{
loader: 'css-loader',
options: { importLoaders: 1 },
},
'sass-loader',
],
};
2
3
4
5
6
7
8
9
10
11
此时,importLoaders
为 1,告诉 css-loader 在处理导入的模块时,需要确保被导入的模块需要被 sass-loader 处理过。如果添加更多的 loader,比如再加一个 postcss-loader, 则 importLoaders
需要改为 2.
importLoaders
选项只在 css-loader 无法处理待导入的模块的时候才会被使用。比如上面的例子 css 文件中导入了一个 sass 文件,要处理 sass 文件需要借助于 sass-loader,因此需要确保在 css-loader 处理模块之前,sass-loader 先处理了该模块。而如果在 sass 文件中导入 sass 文件,则模块本身已经被 sass-loader 处理过,就不需要 css-loader 处理 sass 文件了。
如果需要导入 node_modules
目录下的样式文件,则需要加一个 ~
前缀。比如导入 bootstrap 的样式文件 @import "~bootstrap/less/bootstrap";
。~
告诉 webpack 该模块不是一个相对路径引入的模块,需要在 node_modules 目录下查找。
总结
Webapck 可以处理各种格式的样式文件,默认情况下,所有样式都会编译成 JavaScript bundle。
css-loader 处理 @import
和 url()
语句,style-loader 负责将样式编译成 js,同时实现了 HMR 接口。
Webapck 支持多种预处理器,可以将各种格式的样式转换成 CSS,常见的预处理器有 Sass,Less 和 Stylus。
PostCSS 借助其自身的插件系统,提供了多种处理 CSS 的能力,比如自动添加前缀等。
默认情况下 css-loader 不会处理绝对路径导入和根目录导入的模块。css-loader 通过 importLoaders
选项支持自定义模块导入处理能力。如果要导入一个 node_moduels 目录下的文件,需要使用 ~
前缀。
关注微信公众号,获取最新推送~
加微信,深入交流~