本人微信公众号:前端修炼之路,欢迎关注。
前几天朋友聚餐突然想到,再过不到半年时间,第一批 20 后即将出生。这种感觉就像是,现在的 90 后看 60 后~ 一不小心我们这些 90 后在 20 后的眼中就变成了上个世纪的人。o(╯□╰)o
回顾 webpack 这个系列,结合自己使用的一个过程,是时候结束一下了。
css 优化
我在项目中发现,有些时候 css 会有重复,或者不知道谁写的根本就没有使用过的 css 样式。如果文件较小,影响不是很大。但是我有一个项目,发现其中的 css 有 9000 多行!
对于有代码洁癖的我来说,这是不能忍受的~ 要是文件小的话,我还有机会可以一行行的查找,将多余的代码删除。可惜这个文件内容过多。好在找到了一个 webpack
插件 mini-css-extract-plugin
,这个插件结合purifycss-webpack
使用,就可以满足我的需求,将功能交给 webpack
去做。
mini-css-extract-plugin
mini-css-extract-plugin
这个插件可以在 webpack plugins 中查看更多配置选项。这里我先只使用最简单的配置项。
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
plugins: [
new MiniCssExtractPlugin({ // css 文件抽离
filename: 'css/[name].min.css', // 指定抽离之后文件的名字和并且在 css 路径之下
chunkFilename: 'css/[id].min.css',
}),
],
module: {
rules: [
{
test: /\.css$/, // 因为我项目中只有 css 代码,所以正则只写 css
use: [
{
loader: MiniCssExtractPlugin.loader, // 指定使用 mimi-css-extract-plugin
options: {
publicPath: '../',
hmr: process.env.NODE_ENV === 'development', // 只在开发环境下开启 hmr
},
},
'css-loader', // 使用 css-loader
],
}
]
}
purifycss-webpack
purifycss-webpack
这个插件可以去 npm 官网查看更多配置项。
注:如果打开
purifycss-webpack
这个插件的 npm 说明,页面中会提示使用extract-text-webpack-plugin
这个插件,并且示例代码也是用这个插件演示的。但其实这个插件已经废弃了。官网推荐的使用就是上面使用的mini-css-extract-plugin
这个插件。
const glob = require('glob'); // 这里一定要安装 glob-all 这个插件而不是 glob
const PurifyCSSPlugin = require('purifycss-webpack');
new PurifyCSSPlugin({ // css 文件去重
paths: glob.sync(path.join(__dirname, 'index.html')) // 指定 html 页面,也可以使用通配符 * 进行匹配全部 html
})
purifycss-webpack
和 mini-css-extract-plugin
两者结合使用,才能实现将 css 去重。
optimize-css-assets-webpack-plugin
去重实现以后,文件缩减了不少,可是我还不满足。因为我想在线上使用压缩的 css,进一步缩小文件的大小,节省用户流量。如果自习阅读刚才文档,会发现 MiniCssExtractPlugin
这个插件之中有提到生成环境下使用压缩 css 和 js 的插件。
所以我就直接使用就好了。
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
const TerserJSPlugin = require('terser-webpack-plugin');
optimization: {minimizer: [new TerserJSPlugin({}), new OptimizeCSSAssetsPlugin({})], // js 压缩和 css 压缩
}
图片优化
url-loader
css 提取去重、css 压缩完成之后,又发现可以进一步优化的地方。网站中一般都会使用一些小图标和 logo,有些小图标会做成雪碧图,有些并不会。后来通过搜索,发现其实可以将一些足够小的小图标制作成 base64
,将小图标写到 css 文件中, 从而减少 http 请求数量。如果手动去做这个过程,是比较繁琐的。还好找到了url-loader
这个插件。插件详细配置可以看 webpack Loaders
module: {
rules: [
{test: /\.(png|jpe?g|gif|svg)$/i, // 匹配的图片文件类型
use: [
{
loader: 'url-loader',
options: {
limit: 1024, // 将 1024 以下的图片制作成 base64 图片,超过的不处理
name: '[name].[ext]',
outputPath: 'img/',
publicPath: '../img/' // 指定这个地址之后,css 中的 background 才会变成了 base64~,并且路径使用的是这个路径
},
}
]
}
]
}
需要说明的是,我修改了以下正则 /\.(png|jpe?g|gif|svg)$/i
,这样jpg
和jpeg
就都能匹配到了。另外需要指定 limit
这个参数,表示在 limit
配置的数值以下的图片才进行 base64
编码,超过的不进行处理。
在这个过程中,遇到的问题就是,如果图片没有 base64
,就会造成背景图片background
中引用的 url
地址不正确,导致图片引用失败。后来经过调试发现,指定 options.publicPath
这个属性,就可以正确引用了。
image-webpack-loader
处理完小图标,我想到需要处理一下大图片。因为如果仅仅处理了小图标,影响似乎并不大。真正占流量的其实是图片。其实在做项目的时候,会将 png 图片进行一遍压缩。但是我之前是使用的在线工具。现在我想使用打包工具,自动化进行处理。
image-webpack-loader
可以压缩png、jpeg、gif、webp、svg
。可以分别指定不同类型图片的压缩质量。
{
loader: 'image-webpack-loader',
options: {
mozjpeg: {
progressive: true,
quality: 65
},
// optipng.enabled: false will disable optipng
optipng: {enabled: false,},
pngquant: {
quality: '65-90',
speed: 4
},
gifsicle: {interlaced: false,},
// the webp option will enable WEBP
webp: {quality: 75}
}
}
使用完这个插件之后,确实发现我的图片缩小了不少。
整个配置
上面只是简单的罗列出来了需要使用的各个 loader
和plugin
。但是整个配置并不完整,完整的 webpack-config.js
代码如下:
const path = require('path');
const glob = require('glob');
const {CleanWebpackPlugin} = require('clean-webpack-plugin');
const TerserJSPlugin = require('terser-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
const PurifyCSSPlugin = require('purifycss-webpack');
module.exports = {
mode: 'production',
entry: {style: './js/style.js',},
optimization: {minimizer: [new TerserJSPlugin({}), new OptimizeCSSAssetsPlugin({})], // css 压缩
},
plugins: [new CleanWebpackPlugin(), // 文件清空
new MiniCssExtractPlugin({ // css 文件抽离
filename: 'css/[name].min.css',
chunkFilename: 'css/[id].min.css',
}),
new PurifyCSSPlugin({ // css 文件去重
paths: glob.sync(path.join(__dirname, 'index.html')),
})
],
module: {
rules: [
{
test: /\.css$/,
use: [
{
loader: MiniCssExtractPlugin.loader,
options: {
publicPath: '../',
hmr: process.env.NODE_ENV === 'development',
},
},
'css-loader',
],
},
{test: /\.(png|jpe?g|gif|svg)$/i,
use: [
{
loader: 'url-loader',
options: {
limit: 1024,
name: '[name].[ext]',
outputPath: 'img/',
publicPath: '../img/' // 指定这个地址之后,css 中的 background 才会变成了 base64~,并且路径使用的是这个路径
},
},
{
loader: 'image-webpack-loader',
options: {
mozjpeg: {
progressive: true,
quality: 65
},
// optipng.enabled: false will disable optipng
optipng: {enabled: false,},
pngquant: {
quality: '65-90',
speed: 4
},
gifsicle: {interlaced: false,},
// the webp option will enable WEBP
webp: {quality: 75}
}
}
],
}
],
},
output: {filename: '[name].min.js',
path: path.resolve(__dirname, './dist')
}
};
- 文件的
entry
入口是style.js
。 - 所有的打包文件目录是通过
output.path
指定的,输出到了dist
目录下。 - 在配置
loader
时,可以在一个正则匹配下,配置多个loader
。例如我先配置了url-loader
,然后配置了image-webpack-loader
。
在入口文件 style.js
中,其实什么事情也没有做,只是引入了需要使用的 css
文件。代码如下:
import style from '../css/style.css';
所以过程就是 style.js
引入了 style.css
,然后webpack
进行打包处理,生成 style.min.js
和style.min.css
。
整个的项目结构如下:
以上就是我在项目中使用 webpack
的一个情况。目前这个入门学习手记到这里就结束了。
(完)
相关文章
webpack 入门学习手记(一)
webpack 入门学习手记(二)
webpack 入门学习手记(三)
webpack 入门学习手记(四)