上一节我们学习到webpack中如何处理css文件,以及在使用了 css预处理器
后又改怎么处理。文章末尾我们也提到了两个需要解决的问题:
- 随着项目推进,一直将css写入js中会导致文件逐渐臃肿;
- css兼容性
这一节,我们将针对这两个问题提出相应的解决方案。
css文件提取
上一节中我们使用到了 style-loader
、 css-loader
以及 sass-loader
三种loader,在这三种loader的协同作用下,.scss文件先通过sass-loader转成普通的css文件,再通过css-loader将css转换成commonjs模块并打包到js中,最后通过style-loader将js文件中的css样式加载到head里的style标签中去。
除了上面提到的第一个问题外,这样也会导致页面会有短暂的错乱,然后等js文件加载完成后,页面样式才会恢复正常,这显然不符合我们的要求,用户的体验也非常不好。此时,我们需要将js中的css单独提取出来,作为css文件引入页面,这样就可以解决这个问题。而且js的文件体积会更小,上述第一个问题也能被解决。
如何使用
要将js中的css提取成单独的文件,我们需要用到一个 插件
:mini-css-extract-plugin
。
安装
yarn add -D mini-css-extract-plugin
配置
前几节我们主要使用的是webpack中的 loader
,与 loader
不同的是,插件
在使用之前需要先引入进来,然后在wbepack.config.js的 plugin
字段中添加配置:
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
/* ... */
plugins: [
new MiniCssExtractPlugin({
filename: 'css/index.[contenthash:10].css',
}),
]
/* ... */
}
其中,在实例化这个插件时,可以传入配置。上述配置中指定了提取出css文件的输出路径。
在配置完插件之后,我们来回顾一下之前的处理方式,最终的结果是通过 style-loader
将css的内容插入到页面的style标签中。而现在我们要实现的是将css文件单独提取出来。所以我们需要将 style-loader
替换掉。
在 mini-css-extract-plugin
插件内部提供了一个用于提取css的loader: MiniCssExtractPlugin.loader
,我们只需要将 style-loader
替换为 MiniCssExtractPlugin.loader
即可:
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
/* ... */
module: {
rules: [
/* ... */
{
test: /\.s[ac]ss/,
exclude: /(node_modules|build)/,
use: [
MiniCssExtractPlugin.loader,,
'css-loader',
'sass-loader'
],
},
]
},
plugins: [
new MiniCssExtractPlugin({
filename: 'css/index.[contenthash:10].css',
}),
]
/* ... */
}
css兼容性处理
在日常开发中,为了让css样式能够适用于大多数的设备或者浏览器,我们需要对css做好兼容性处理。
css的兼容性处理需要用到 postcss。 postcss
是一个用 JavaScript 工具和插件转换 CSS 代码的工具。在webpack中使用它需要用到两个包:postcss-loader
以及 postcss-preset-env
。
其中,postcss-preset-env
的作用是帮助 postcss-loader
找到 browserslist
的配置,加载指定的兼容性。browserslist
一般会配置到package.json下,或者在根目录下有一个 .browserslistrc
的文件去写相关的配置。
注意:package.json中的配置与.browserslistrc文件,两者只能存其一,否则会报错!!
安装
yarn add -D postcss-loader postcss-preset-env
配置
我们在上面的loader配置基础上进行一些修改:
{
test: /\.s[ac]ss$/i,
use: [
MiniCssExtractPlugin.loader,
'css-loader',
{
loader: 'postcss-loader',
options: {
postcssOptions: {
plugins: [
[
'postcss-preset-env',
{
// Options
},
],
],
},
}
},
// 将 Sass 编译成 CSS
'sass-loader',
],
},
然后在 package.json
文件中添加如下配置(更多配置可以参考:browserslist):
"browserslist": {
"development": [ // 开发环境
"last 1 chrome version",
"last 1 safari version",
"last 1 firefox version"
],
"production": [ // 生产环境
"> 0.2%",
"not dead",
"not op_mini all"
]
}
或者也可以在根目录下创建.browserslistrc文件。
注意:配置项是有顺序的!!> 0.2%写到后面会报错
> 0.2%
not dead
not op_mini all
关于postcss-loader更多的配置可以参考。
css文件压缩
在对css文件做完兼容性处理并提取成单个文件之后,我们可以进一步对其进行优化,将抽出的css文件进行压缩。此时我们需要用到一个插件: optimize-css-assets-webpack-plugin
。
安装
yarn add -D optimize-css-assets-webpack-plugin
使用
使用非常简单 ,只需要在 webpack.config.js
中引入使用即可。默认配置已经可以满足压缩需要,如果需要添加配置,可以参考。
const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
/* ... */
module: {
rules: [
/* ... */
{
test: /\.s[ac]ss$/i,
use: [
MiniCssExtractPlugin.loader,
'css-loader',
{
loader: 'postcss-loader',
options: {
postcssOptions: {
plugins: [
[
'postcss-preset-env',
{
// Options
},
],
],
},
}
},
// 将 Sass 编译成 CSS
'sass-loader',
],
},
]
},
plugins: [
new MiniCssExtractPlugin({
filename: 'css/index.[contenthash:10].css',
}),
new OptimizeCssAssetsWebpackPlugin()
]
/* ... */
}
预告
通过这两节,我们已经知道了webpack中如何对css文件进行处理,并在此过程中对其做了一些优化,包括提取单个css文件,兼容性处理以及css代码压缩。
下一节我们一起来看下,除了css文件与js文件外,其他的文件webpack要如何进行处理呢?拭目以待吧~