前段时间百度二面,面试官问了webpack等相关问题,加上平时实验室的umi项目整合了webpack,同时实验室就用的css,所以loader也没怎么使用。这段时间先相对空余了,就顺带学习学习webpack的构建优化,同时本文的webpack是4x版本的,5x版本有所区别
plugin的优化
plugin我们使用缓存插件和清除之前打包构建的文件插件,以及代码压缩插件他们对应的插件分别是hard-source-webpack-plugin
、clean-webpack-plugin
和terser-webpack-plugin
插件
实验室umi框架整合了webpack要想改变webpack,umi提供了chainWebpack
这个字段,他的值是一个函数,函数的参数就是webpackInstance,只不过我们用config来代表webpackInstance
js
chainWebpack: (config)=>{
config.plugin('插件别名').use('插件实例')
}
js
//导入插件
import { CleanWebpackPlugin } from 'clean-webpack-plugin';
import HardSourceWebpackPlugin from 'hard-source-webpack-plugin'
const TerserPlugin = require('terser-webpack-plugin');
//使用插件
config.plugin('HardSourceWebpackPlugin').use(HardSourceWebpackPlugin)//持久化缓存
config.plugin('CleanWebpackPlugin').use(CleanWebpackPlugin)//清除之前的缓存
对应原生的webpack写法则是
js
plugins: [
new progressPlugin(),
new CleanWebpackPlugin(),
new HardSourceWebpackPlugin(),
],
loader的优化
loader作用则是处理css和js代码,我们有时候需要用loader将es6、less、sass等要翻译,当然翻译也是要耗时的,我们可以用thread-loader
来帮助我们开启多进程并行翻译,提高速度,用thread-loader也是需要下载依赖
js
module: {
rules: [
{
test: /.vue$/,
use: [
'thread-loader',
'vue-loader',
],
},
{
test: /.css$/i,
use: ['style-loader', 'css-loader'],
},
{
test: /.less$/i,
use: [
'thread-loader',
'style-loader',
'css-loader',
'less-loader',
],
},
{
test: /.(png|jpe?g|gif|svg)$/i,
use: [
'thread-loader',
{
loader: 'url-loader',
options: {
esModule: false,
limit: 100 * 1024,
name: '[name].[hash:8].[ext]',
outputPath: 'images/',
},
},
],
},
{
test: /.m?js$/,
exclude: /node_modules/,
use: [
'thread-loader',
{
loader: 'babel-loader',
options: {
presets: [
['@babel/preset-env', { targets: 'defaults' }],
],
},
},
],
},
],
},
optimization优化
optimization的意思就是最佳化,我们通过配置optimization也可以实现优化,当然其中也用了plugin来优化
js
//css压缩
config.optimization
.minimizer('css-minimizer')
.use(CssMinimizerPlugin, [{
cache: true, // 缓存开启
parallel: true, // 多线程并行处理
minimizerOptions: {
preset: ['default', { discardComments: { removeAll: true } }], // 移除注释
},
}]);
//代码压缩
config.optimization
.minimizer('terser')
.use(TerserPlugin, [{
cache: true,//缓存开启
parallel: true,//多线程并行处理
terserOptions: {
compress: {
drop_console: true,//去除console语句
unused: true,//移除未使用的变量和函数
dead_code: true,//移除未使用的代码
},
},
}]);
//代码分离
config.optimization
.splitChunks({
chunks: 'all',
minSize: 30000,
minChunks: 3,,
automaticNameDelimiter: '.',
cacheGroups: {
vendor: {
name: 'vendors',
test({ resource }) {
return /[\/]node_modules[\/]/.test(resource);
},
priority: 10,
},
},
});
对应原生的webpack,我们只需要设置他的optimization字段就可以了
js
optimization: {
minimizer: [
new TerserPlugin({
cache: true,
parallel: true,
terserOptions: {
compress: {
drop_console: true,
unused: true,
dead_code: true,
},
},
}),
new CssMinimizerPlugin({
cache: true, // 缓存开启
parallel: true, // 多线程并行处理
minimizerOptions: {
preset: ['default', { discardComments: { removeAll: true } }], // 移除注释
},
})
],
splitChunks: {
chunks: 'all',
minSize: 30000,
minChunks: 3,
automaticNameDelimiter: '.',
cacheGroups: {
vendor: {
name: 'vendors',
test({ resource }) {
return /[\/]node_modules[\/]/.test(resource);
},
priority: 10,
},
},
},
},
总结
对于打包优化,webpack有很多插件和loader可以提高构建的速度,以及减少构建之后包的大小,但是对于速度的话,运行那些插件本身也需要一定的速度,当我们打包构建本来就快的时候,再用那些插件反倒速度会变慢。当然,现在的项目基本上都区分了开发环境和生产环境,我们只需要在相应的环境配置我们的loader和plugin就可以让每个阶段基本最优解决时间问题