前言
今天我们一起来学习webpack是怎么打包CSS样式的。
webpack本身是无法打包CSS文件的,我们在使用时会遇到如下图中的报错。所以我们用借助loader来打包,loader的作用就是对特定类型的模块进行转换。
css-loader的使用
在项目目录下添加文件:
测试代码
// src -> main.js
import "./css/style_a.css";
// 测试less时放开
// import "./css/style_less.less"
const h1Ele = document.createElement("h1");
h1Ele.innerText = "hello CSS";
h1Ele.className = "title";
const divEle = document.createElement("div");
divEle.innerText = "webpack bundle css";
divEle.className = "content";
document.body.append(h1Ele);
document.body.append(divEle);
/* src -> css -> style_a.css */
.title {
color: red;
font-size: 32px;
font-weight: 700;
}
.content {
color: aqua;
font-size: 14px;
}
安装css-loader
npm install css-loader -D
yarn add css-loader -D
loader配置方式:
// webpack.config.js 文件
const path = require("path");
module.exports = {
entry: "./src/main.js",
output: {
path: path.resolve(__dirname,"./dist"),
filename: "./build.js"
},
module: {
rules: [
{
test: /.css$/,
loader:"css-loader" // 当只有一个loader时,可以这样写
// 有多个loader时,要用use
// use:["loader-a","loader-b"]
}
]
}
}
说明:
-
module是一个对象,rules属性对应的值是一个数组,其中允许配置多个loader;
-
test属性:用于配置资源,通常设置成正则表达式;
-
use属性:对应一个数组 [UseEntry]
- UseEntry是一个对象,可以通过对象的属性来设置一些属性
- loader:对应一个loader的名称,对用的值是一个字符串
- options:可选属性,设置一些其他属性
执行打包 npx webapck打包后,浏览器页面的效果
如上图所示,css样式并没有生效!
这是为什么呢?
- css-loader只是负责将.css文件进行解析,并不会将解析之后的css插入到页面中;
- 如果希望完成插入style的操作,那我们还需要另外一个loader,就是style-loader
style-loader的使用
安装style-loader
npm install style-laoder -D
yarn add style-laoder -D
配置style-loader
// webpack.config.js文件
module.exports = {
// ........
module: {
rules: [
{
test: /.css$/,
use:["style-loader","css-loader"] // 这里style-loader要写在css-loader前面,因为laoder的执行顺序是从右向左的
}
]
},
}
重新执行编译,发现样式生效了。
可以发现当前css样式是通过内联方式添加进来的。(在head标签中引入style)
在开发中,我们可能会使用less、sass等预处理器来编写css样式,效率会更高。
那么我们就要用相应的loader来转换,比如用less-loader把less转换成css。
less-loader的使用
安装
npm install less-loader -D
yarn add less-loader -D
配置less-loader
// webpack.config.js
module: {
rules: [
{
test: /.less$/,
use: ["style-loader","css-loader","less-loader"]
}
]
},
编写less样式
@textColor: green;
@fontSize: 14px;
.content {
color: @textColor;
font-size: @fontSize;
}
重新执行编译,样式会生效
开发中有些样式需要适配不同的浏览器,根据目标浏览器添加前缀或者运行时环境添加所需的polyfill等。这时候需要postcss-loader来帮助我们完成。
postcss-loader的使用
添加前缀的插件我们不使用autoprefixer,用另一个插件:postcss-preset-env
postcss-preset-env是一个postcss插件,也可以自动帮助我们添加前缀
安装:
npm install postcss-loader postcss-preset-env -D
yarn add postcss-loader postcss-preset-env -D
配置:
// webpack.config.js
module: {
rules: [
{
test: /.css$/,
use:[
"style-loader",
"css-loader",
{
loader: "postcss-loader",
options:{
postcssOptions: {
plugins: [
"postcss-preset-env"
]
}
}
}
]
}
]
},
单独的postcss配置文件
- 在根目录下创建postcss.config.js
// postcss.config.js
module.exports ={
plugins:[
"postcss-preset-env"
]
}
页面效果如图所示:
- 目前所有的样式都是以内联方式直接插入到head中的,随着开发的页面越来越多,head标签会越来越复杂,而已静态文件会越来越大,下载bundle时消耗很大的流量;
- 这个时候在生产环境中我们需要优化,把css提取到独立的css文件中;
- MiniCssExtractPlugin可以帮助我们完成;
MiniCssExtractPlugin
安装:
npm install mini-css-extract-plugin -D
yarn add mini-css-extract-plugin -D
配置:
// webpack.config.js
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
mudule.exports ={
// .......
module: {
rules: [
{
test: /.css$/,
use:[
MiniCssExtractPlugin.loader, // MiniCssExtractPlugin.loader可以取代style-loader
"css-loader"
]
}
]
},
plugins: [
new MiniCssExtractPlugin({
filename: "css/[name].css", // 打包后css文件的名称
chunkFilename: "css/[name].css"
// 更多配置请查阅相关文档
})
]
}
重新打包后,dist目录下新增了css文件,在index.html可以看到以link形式引入了css样式。
在生产环境中,css优化手段还有压缩,下图中是打包过后的css文件,还有很多空格,空格也会占用空间的大小。
css的压缩
- css的压缩通常是去除无用的空格,因为很难去修改选择器、属性的名称、值等;
- css的压缩我们可以使用另外一个插件:css-minimizer-webpack-plugin;
- css-minimizer-webpack-plugin底层是用cssnano工具来优化、压缩css的;
安装:
npm install css-minimizer-webpack-plugin -D
yarn add css-minimizer-webpack-plugin -D
在optimization.minimizer中配置
// webpack.config.js
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");
module.exports = {
// ..................
optimization:{
minimize: true, // 开启压缩
minimizer: [
new CssMinimizerPlugin({
// 更多配置请查阅相关文档
})
]
}
// ...............
}
打包后的css文件,如图
css中消除无用的代码
我们在生产环境还需要消除css中无用的代码(死代码)来进一步的优化;
这时候需要借助purgecss-webpack-plugin插件来帮助实现;
安装:
npm install purgecss-webpack-plugin -D
配置:
// webpack.config.js
const glob = require("glob");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const { PurgeCSSPlugin } = require("purgecss-webpack-plugin");
module.exports = {
// ........
module: {
rules: [
{
test: /.css$/,
use: [MiniCssExtractPlugin.loader, "css-loader"],
},
],
},
plugins: [
new MiniCssExtractPlugin({
filename: "css/[name].css",
chunkFilename: "css/[name].css",
}),
new PurgeCSSPlugin({ // 配合MiniCssExtractPlugin一起使用
paths: glob.globSync(`${path.join(__dirname, "src")}/**/*`, { nodir: true })
// 更多配置请查阅相关文档
}),
],
};
/* src -> css -> style_a.css */
.title {
color: red;
font-size: 32px;
font-weight: 700;
}
/* 这个类没有用到,将会被清除 */
.content {
color: aqua;
font-size: 14px;
}
以上就是全部,谢谢!