参考文档:webpack打包体积优化(超详细)
- 使用分析器webpack-bundle-analyzer(可视化大小的webpack输出文件与互动缩放树形图。)
安装:npm i -D webpack-bundle-analyzer
配置:
const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer');
plugins: [
new BundleAnalyzerPlugin({
analyzerPort: 8081
})
],
打包运行:npm run build
,结果如下:可见,包都很小,是因为现在只是脚手架,使用到的包很少。
- 压缩js
(1)使用uglifyjs-webpack-plugin
打包一直报错,最后就换了一下插件,结果打包成功,因此,可能是这个插件的版本和webpack的版本不兼容吧。
(2)安装npm i -D terser-webpack-plugin
,并在pro里配置:
这里只做了一般的配置,更多配置查看npm库terser-webpack-plugin
optimization: {
minimizer: [
// 压缩js
new TerserPlugin({
cache: true,
parallel: true,
sourceMap: false,
terserOptions: {
ecma: undefined,
warnings: false,
parse: {},
compress: {
drop_debugger: true, // 删除 debugger
drop_console: true, // 删除 console
},
mangle: true, // 不跳过错误的名称
module: false,
output: null,
toplevel: false,
nameCache: null,
ie8: false,
keep_classnames: undefined,
keep_fnames: false,
safari10: true,
},
})
]
}
- 压缩css(配置参考)
(1)安装npm i -D optimize-css-assets-webpack-plugin
(2)在pro里配置如下:
new OptimizeCssAssetsPlugin({
assetNameRegExp: /\.css\.*(?!.*map)/g, // 注意不要写成 /\.css$/g
cssProcessor: require('cssnano'),
cssProcessorOptions: {
// 使用安全模式,避免 cssnano 重新计算 z-index
safe: true,
// 默认不移除许可证注释,这里移除所有
discardComments: { removeAll: true },
// cssnano通过移除注释、空白、重复规则、过时的浏览器前缀以及做出其他的优化来工作,一般能减少至少 50% 的大小
// cssnano 集成了autoprefixer的功能
// 会使用到autoprefixer进行无关前缀的清理
// 因此这里关闭autoprefixer功能
// 使用postcss的autoprefixer功能
autoprefixer: false,
},
canPrint: true
})
- 分离:将antd之类的第三方库从主要的包里分离出来,打包后的chunk前缀名为vendor。
注意:
(1)设置css/js的chunkFilename
,设置为[id]——vendor前缀不生效
,设置为[name]——生效
;
(2)若不设置css/js的chunkFilename
,并且不配置cacheGroups,则会默认添加前缀为vendor~app
。
配置如下:splitChunks配置参考
// chunks: 'all',表示显示块的范围,有三个可选值:initial(初始块)、async(按需加载块)、all(全部块),默认为all
optimization: {
splitChunks: {
chunks: 'all',
cacheGroups: { // 缓存组默认将node_modules中的模块拆分带一个叫做vendors的代码块中
vendor: {
test: /node_modules/,
name: 'vendor', // 决定打包的chunk前缀名
chunks: 'initial',
enforce: true,
},
},
}
}
- 附pro的完整配置
const path = require('path');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const HtmlWebpackIncludeAssetsPlugin = require('html-webpack-include-assets-plugin');
const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer');
const TerserPlugin = require('terser-webpack-plugin');
const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin');
module.exports = {
entry: {
app: path.resolve(__dirname, '../src/index.js')
},
output: {
filename: 'public/js/[name].[hash:8].js',
chunkFilename: 'public/js/[name].[hash:8].chunk.js',
path: path.resolve(__dirname, '../dist'),
publicPath: '/' // 构建资源存放路径(绝对路径)
},
optimization: {
minimizer: [
// 压缩js
new TerserPlugin({
cache: true,
parallel: true,
sourceMap: false,
terserOptions: {
ecma: undefined,
warnings: false,
parse: {},
compress: {
drop_debugger: true, // 删除 debugger
drop_console: true, // 删除 console
},
mangle: true, // 不跳过错误的名称
module: false,
output: null,
toplevel: false,
nameCache: null,
ie8: false,
keep_classnames: undefined,
keep_fnames: false,
safari10: true,
},
}),
new OptimizeCssAssetsPlugin({
assetNameRegExp: /\.css\.*(?!.*map)/g, // 注意不要写成 /\.css$/g
cssProcessor: require('cssnano'),
cssProcessorOptions: {
// 使用安全模式,避免 cssnano 重新计算 z-index
safe: true,
// 默认不移除许可证注释,这里移除所有
discardComments: { removeAll: true },
// cssnano通过移除注释、空白、重复规则、过时的浏览器前缀以及做出其他的优化来工作,一般能减少至少 50% 的大小
// cssnano 集成了autoprefixer的功能
// 会使用到autoprefixer进行无关前缀的清理
// 关闭autoprefixer功能
// 使用postcss的autoprefixer功能
autoprefixer: false,
},
canPrint: true
})
],
splitChunks: {
chunks: 'all', // 表示显示块的范围,有三个可选值:initial(初始块)、async(按需加载块)、all(全部块),默认为all
cacheGroups: { // 缓存组默认将node_modules中的模块拆分带一个叫做vendors的代码块中
vendor: {
test: /node_modules/,
name: 'vendor', // 决定打包的chunk前缀名
chunks: 'initial',
enforce: true,
},
},
}
},
module: {
rules: [
{
test: /\.js|jsx$/,
use: [{
loader: 'babel-loader'
}],
exclude: /node_modules/
},
{
test: /\.(css|less)$/,
exclude: /node_modules/,
use: [
MiniCssExtractPlugin.loader,
{
loader: 'css-loader',
options: {
modules: true,
localIdentName: '[name]_[local]_[hash:8]'
}
},
'postcss-loader',
{
loader: 'less-loader',
options: {
javascriptEnabled: true
}
}
]
},
{
test: /\.(css|less)$/,
include: /node_modules/,
use: [
MiniCssExtractPlugin.loader,
'css-loader',
'postcss-loader',
{
loader: 'less-loader',
options: {
javascriptEnabled: true
}
}
]
},
{
test: /\.(png|svg|jpe?g|gif)$/i,
use: [
{
loader: 'file-loader',
options: {
outputPath: 'public/images/',
name: '[name].[hash:8].[ext]'
}
},
{
loader: 'image-webpack-loader' // 对图片的压缩使用相应的默认配置
}
]
},
{
test: /\.(woff|woff2|eot|ttf|otf)$/,
use: [
{
loader: 'file-loader',
options: {
outputPath: 'public/font/',
name: '[name].[hash:8].[ext]'
}
}
]
}
]
},
plugins: [
new CleanWebpackPlugin(['public', 'index.html'], {
root: path.resolve(__dirname, '../dist'),
exclude: ['dll'] // clean时,不删除dll文件夹
}),
new HtmlWebpackPlugin({
template: path.resolve(__dirname, '../public/index.html'),
filename: 'index.html'
}),
new MiniCssExtractPlugin({
filename: 'public/css/[name].[hash:8].css',
chunkFilename: 'public/css/[id].[hash:8].chunk.css'
}),
// webpack读取到vendor的manifest文件对于vendor的依赖不会进行编译打包
new webpack.DllReferencePlugin({
manifest: require(path.resolve(__dirname, '../dist/public/dll/vendor-manifest.json'))
}),
// 将第三方打包文件vendor.dll.js动态添加进html里
new HtmlWebpackIncludeAssetsPlugin({
assets: ['public/dll/vendor.dll.js'],
append: false // false 在其他资源的之前添加 true 在其他资源之后添加
}),
new BundleAnalyzerPlugin({
analyzerPort: 8081
})
],
resolve: {
alias: {
pages: path.resolve(__dirname, '../src/pages'),
components: path.resolve(__dirname, '../src/components'),
assets: path.resolve(__dirname, '../src/assets'),
utils: path.resolve(__dirname, '../src/utils')
}
}
};
这些配置已经ok,后面需要写页面代码进行测试,并查看这些配置所提升的地方。
注意:后面还需要对页面路由的跳转进行测试和配置。
网友评论