文章目录
css解析
乞丐版webpack想认识css需要css-loader。
主要用于加载css文件,例如在main.js中引入css文件,没有css-loader的webpack是不认识的。
原理是转换成commonjs对象,本质是js,里面内容是样式字符串。
光只有css-loader还不行,同时还需要style-loader,因为打包后的css一般都会放在页面的style标签插入到head中,但css-loader不会做这些事,需要style-loader帮忙做。
安装
npm i style-loader css-loader -D
配置
然后在webpack中设置module:
module.exports = {
module: {
rules: [
{
test: /.css$/,
use: [
'style-loader', // 这个要在写在第一个,因为loader读取顺序是倒序的,而且会把结果传递给下一个loader去做处理
'css-loader'
]
}
]
}
}
预处理器
预处理器的话,就多添加相关loader即可,例如less-loader用于将less转换成css。
npm i less less-loader -D
module.exports = {
module: {
rules: [
{
test: /.css$/,
use: [
'style-loader',
'css-loader',
]
},
{
test: /.less$/,
use: [
'style-loader',
'css-loader',
'less-loader'
]
}
]
}
}
提取css成单独文件(MiniCssExtractPlugin)
css文件最终打包后生成的资源是集成在js文件中的,如果把css单独打包成一个css文件会带来什么好处。
这里引用下掘金的一片文章【面试官:生产环境构建时为什么要提取css文件?】
文章讲了一些优点:
更好的缓存,当 CSS 和 JS 分开时,浏览器可以缓存 CSS 文件并重复使用,而不必重新加载,也不用因为js内容的变化,导致css缓存失效
更快的渲染速度,浏览器是同时可以并行加载多个静态资源,当我们将css从js中抽离出来时,能够加快js的加载与解析速度,最终加快页面的渲染速度
更好的代码可读性,独立的css文件更方便代码的阅读与调试
安装
npm i mini-css-extract-plugin -D
配置
const HtmlWebpackPlugin = require('html-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin') // 引入相关
module.exports = {
module: {
rules: [
{
test: /.css$/,
use: [
//'style-loader', 这回不使用这个loader了,二者只能选一
MiniCssExtractPlugin.loader, // 能提取js中的css成单独文件
'css-loader',
]
}
]
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html'
}),
new MiniCssExtractPlugin({
filename: 'css/build.css', // 默认会生成main.css文件在输出文件的位置上,可以通过filename自定义。html文件会自动用link标签引入这个.css文件。
// filename: '[name].css' 这样命名能和js文件一致
// chunkFilename: '[name].css' // 异步引入的css文件也可以单独分离打包,但此时[name]不是js的文件名称了,是webpack自动生成的
})
]
}
这样减少了js文件体积,css也通过link标签去单独引入,就不会出现闪屏现象。
兼容处理(postcss)
每个浏览器对一些css属性的支持情况是不一样的,需要一个postcss库的帮助,去针对性的对每个浏览器做兼容。
安装
npm i postcss-loader postcss-preset-env -D
postcss-preset-env可以通过环境的识别加载不同的配置,能够让兼容性精确到每一个浏览器的版本。
原理是帮postcss找到package.json中browserlist字段里面的配置,通过配置生成指定的css兼容样式
配置
const HtmlWebpackPlugin = require('html-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin') // 引入相关
module.exports = {
module: {
rules: [
{
test: /.css$/,
use: [
//'style-loader', 这回不使用这个loader了
MiniCssExtractPlugin.loader, // 能提取js中的css成单独文件
'css-loader',
{
loader: 'postcss-loader',
options: {
ident: 'postcss', // 固定写法,应该是表示要修改postcss
plugins: () => { // 使用postcss的插件
require('postcss-preset-env')()
}
}
}
]
}
]
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html'
}),
new MiniCssExtractPlugin({
filename: 'css/build.css' // 默认会生成main.css文件在输出文件的位置上,可以通过filename自定义。html文件会自动用link标签引入这个.css文件。
})
]
}
同时还需要在package.json中设置
{
"browserlist": {
// 开发模式可以只写自己调试用的浏览器
"development" : [
"last 1 chrome version" // 兼容chrome最近的一个版本
],
// 生产环境(默认),和webpack中mode配置无关
"production": [
">0.2%", // 大于0.2%的浏览器都兼容
"not dead", // 已经淘汰的浏览器不要兼容,例如ie8
"not op_mini all", // 所有op浏览器都不要兼容
]
}
}
如果需要使用browserlist里的开发模式,需要在webpack中修改node的环境变量。
process.env.NODE_ENV = 'development' // 让这个项目在node的开发环境中运行
这样,打包后的css样式属性就会自动添加前缀来兼容不同的浏览器。在开发中可以点击元素审查看到。
browserlist字段有很多设置,可以百度。
当然postcss不止能做这些事情,还有:
- 当你使用了高级css原生语法时,会被编译成普通的css,
postcss-preset-env
。 - 当你定义了多个相同类名的选择器时,会编译后加哈希唯一值,
postcss-modules
。 - 第三方css编写库,例如tailwindcss也有postcss的插件
postcss的工作过程大致是,拿到css,把css处理成抽象语法树,然后交给一个个的postcss插件,每个插件各司其职(例如上面说的兼容不同浏览器、降级、加哈希等等),最后postcss再把处理好的抽象语法树还原成css文本。
压缩
就是压缩打包的css文件,我了解到有两个插件可以用,麻了,不知道用哪个好,用的时候去github预研下吧。
OptimizeCssAssetsWebpackPlugin
安装
需要安装以下插件
npm i optimize-css-assets-webpack-plugin -D
配置
const OptimizeCssAssetsWebpackPlugin = require('mini-css-extract-plugin') // 引入相关
module.exports = {
plugins: [
new OptimizeCssAssetsWebpackPlugin()
]
}
CssMinimizerPlugin
安装
需要安装以下插件
npm install css-minimizer-webpack-plugin --save-dev
配置
关于它的配置我很迷茫,我看有的人说直接在plugins里配置就好,有的人说要在optimization里配置,我麻了。先记录optimization里的方式把,和plugins是同级的
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");
module.exports = {
optimization: [
minimizer: [
// 普通情况下直接使用即可new CssMinimizerPlugin()
new CssMinimizerPlugin({
// 只记录我认为有用的配置
exclude: '正则或者路径地址', // 哪些不压缩
})
]
]
}
可能css文件少的时候,效果不明显,但是当文件积累越来越多,优势就越来越明显。