webpack打包优化配置

article/2025/9/24 15:07:10

文章目录

  • 前言
  • 不进行任何打包配置
  • 代码分离
    • splitChunk
    • runtimeChunk
    • 动态导入
  • css文件处理
    • css文件提取
    • css文件压缩
    • css实现Tree Shaking
  • js实现Tree shaking
  • Terser
  • scope Hoisting
  • 打包优化没效果
  • 打包界面显示分析
  • 总结


前言

之前使用webpack进行项目搭建配置时,都是操作一些基础的loader、基础插件配置与开发环境配置,没怎么考虑过打包配置。所以想整一下生产环境的配置,加深自己的理解。

不进行任何打包配置

当不进行任何打包配置时,使用的是production环境下webapck默认的配置。我将自己之前用webpack搭建的前端项目掏了出来,npm run build 进行打包,打出的包如下:
在这里插入图片描述
由图可以看出,打出的包中bundle.js文件很大。默认情况下所有的同步导入模块中的js代码会打包进bundle.js文件中,首页加载时会加载全部js代码,影响加载性能。下面对其进行优化。

代码分离

代码分离的作用是将代码打包进不同的bundle中,使每个bundle文件的体积减小,可以实现按需加载,提升加载性能。
常见的代码分离方法有配置多入口、splitChunk与动态导入等实现方式。多入口配置相对简单,可以自行配置,我这里用不到,主要说一下后面两种方式。

splitChunk

有大佬具体分析过:https://juejin.cn/post/6844903891922862093

先说一下splitChunk分包模式,需要使用SplitChunksPlugin实现(webpack已内置此插件)。
此方法默认处理异步导入的import的模块,将使用到的公共模块进行拆分,将公共的chunk拆成一些小的chunks,供各异步模块使用,实现按需加载chunk。
在production环境下webpack已对其进行默认配置,可以不进行其它额外配置,也可以手动更改配置。在开发环境也可以进行相应的配置,大型项目推荐开发环境也进行配置。

相关的配置项有:

  • chunks:默认值为async,表示异步导入处理;还可以取值initial,all。
  • minSize:拆分包的大小至少为minSize,如果一个包拆分出来达不到minSize,那么这个包就不会拆分。
  • maxSize:将大于maxSize的包,拆分为不小于minSize的包。
  • minChunks:至少被引入的次数,默认是1,没达到引入次数不会被拆分。
  • name:设置拆包的名称,可以不写,不写时在cacheGroups中要设置。
  • cacheGroups:用于对拆分的包就行分组。比如lodash在拆分之后,并不会立即打包,而是会等到有没有其他符合规则的包一起来打包。
optimization: {splitChunks: {                 // 这里一般不手动配置,最多平常只配置个 chunks: "all"chunks: "async",               minSize: 20000,maxSize: 20000,minChunks: 1,cacheGroups: {vendor: {test: /[\\/]node_modules[\\/]/,  //匹配规则,匹配模块是否属于node_modules文件夹中filename: "[id]_vendors.js",priority: -10                    // 优先级},default: {                          minChunks: 2,                     //匹配规则filename: "common_[id].js",priority: -20}}},
}

搞完重新打包后发现哈哈哈没啥变化,bundle.js文件还是大,因为只处理了异步导入模块,不影响打包后的bundle.js文件。
在这里插入图片描述

runtimeChunk

配置runtime相关的代码是否抽取到一个单独的chunk中。抽离出来后,有利于浏览器缓存的策略。
这个production环境中应该有默认配置,懒得搞了随便设个name值。

optimization: {runtimeChunk: {name: 'runtime'}
},

动态导入

动态导入通常是一定会打包成独立的文件的,所以并不会再cacheGroups中进行配置。命名通常会在output中,通过 chunkFilename 属性来命名。
这里有个chunkIds配置,让webpack使用什么算法生成打包出的独立文件的id,一般使用webpack的默认值即可。开发环境下的默认值为named,生产环境下的默认值为deterministic。

output: {chunkFilename: "js/[name].[contenthash:6].chunk.js",
},

代码分离一套流程搞完后发现体积还是没有减小,但是打包的产物文件变了。
在这里插入图片描述

css文件处理

下面接着处理css等样式资源,有以下处理流程:

  • css文件提取
  • css文件压缩
  • css文件实现Tree Shaking

css文件提取

主要使用mini-css-extract-plugin插件实现,将css提取到独立的css文件中,该插件需要在webpack4+才可以使用,且在生产环境才使用。

  1. 安装: npm install mini-css-extract-plugin -D
  2. 这里有个注意点,开发环境才会使用style-loader,生产环境要使用MiniCssExtractPlugin.loader,且需配合插件使用。
  3. 下面代码中的isProduction是我自己传的参数,如何判断开发环境还是生产环境根据项目自行处理。
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module: {rules: [{test: /\.css$/,use: [isProduction ? MiniCssExtractPlugin.loader: "style-loader", // style-loader最好只在开发环境使用{loader: "css-loader",options: {importLoaders: 1}},'postcss-loader']},]
},
// production环境下的配置
plugins: [new CleanWebpackPlugin(),new MiniCssExtractPlugin({filename: "css/[name].[contenthash:6].css"}),]

css文件压缩

主要使用插件css-minimizer-webpack-plugin实现,但是功能有限,只能去除一些无用的空格等,很难去修改选择器、属性的名称、值等,也是在生产环境使用。

npm install css-minimizer-webpack-plugin -D

const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
plugins: [new CssMinimizerPlugin()
]

css实现Tree Shaking

主要使用PurgeCSS插件来实现,用来删除未使用的CSS样式。

注意:这个方法慎用!我将产物部署到我的服务器上,发现部分样式缺失,给我删掉了

npm install purgecss-webpack-plugin -D

const PurgeCssPlugin = require('purgecss-webpack-plugin');
const glob = require('glob');  // webpack内置插件
plugins: [new PurgeCssPlugin({// 检测src文件夹下的所有文件夹中的所有文件,这是glob库中的固定写法// {nodir: true} 表示不检测文件夹,只检测文件paths: glob.sync(`${resolveApp("./src")}/**/*`, {nodir: true}),safelist: function() {return {standard: ["body", "html"]      // 保留html和body的样式}}})
]

这些操作整完发现bundle包变小一些了。
在这里插入图片描述

js实现Tree shaking

主要用来消除未调用的代码。
方式一:usedExports属性:通过标记某些函数是否被使用,之后通过Terser来进行优化的,这个在后面会讲到。还有这个生产环境webpack配了默认值了,一般不需手动修改。
还有一个方式可自行去了解,我不喜欢用。

Terser

可以压缩、丑化代码,让bundle(代码包)变得更小。在production模式下,默认就是使用TerserPlugin来处理我们的代码的,可以使用默认值,也可以手动配置。相关配置参数的含义可自行去了解。

局部安装: npm install terser

optimization: {usedExports: true, // 通过标记某些函数是否被使用,之后通过Terser来进行优化minimize: true, // 对js代码进行压缩,默认production模式下已经打开了minimizer: [// 由Terser将未使用的函数, 从我们的代码中删除new TerserPlugin({parallel: true,extractComments: false,  // 使用这个插件主要是删除build文件夹中的一个注释文件terserOptions: {output: {comments: false,  // 打包时去掉注释},compress: {arguments: false,dead_code: true,pure_funcs: ['console.log']  // 打包时清除掉无用的console.log},mangle: true,toplevel: true,keep_classnames: true,keep_fnames: true}})]},

打包成果物中有个注释文件,如果想去掉这个文件,可以配置 extractComments: false
在这里插入图片描述

scope Hoisting

主要是对作用域进行提升,并且让webpack打包后的代码更小、运行更快。
webpack打包会有很多的函数作用域,需要执行一系列的函数,scope Hoisting主要将函数合并到一个模块中来运行。
生产环境中该模块自启动,无需配置,开发环境可以自己配置。

const webpack = require('webpack');
plugins: [new webpack.optimize.ModuleConcatenationPlugin()
]

打包优化没效果

上面优化流程全部走完了,发现打包优化的还是不行。我就只能在splitChunk上下功夫了。
在这里插入图片描述
还记得上面的配置中,splitChunks只是处理了异步导入模块吗。现在将splitChunks的chunks默认属性值改为all,就是不止对异步导入做处理了,同步与异步导入都做处理进行代码分离。再打包一次发现有效果了,每个bundle的体积都小了很多,但是还有一个文件警告,显示为538kib大小。我实在不知怎搞了,这个文件包分析也看不懂。
在这里插入图片描述

打包界面显示分析

针对上面遗留的问题,想进行一个可视化的分析,主要使用webpack-bundle-analyzer插件,可以非常直观查看包大小与依赖关系。

npm install webpack-bundle-analyzer -D

const { BundleAnalyzerPlugin } = require("webpack-bundle-analyzer");
new BundleAnalyzerPlugin()

添加完成配置后,我直接运行打包,发现报错,报错理由在网上搜了一下说是8888端口被占用。
因为这个插件是帮助我们打开一个8888端口上的服务,方便我们可以直接的看到每个包的大小。
在这里插入图片描述

网上的处理方式都是什么在任务管理器中杀死8888端口的服务,太凶残了,我选择给它换个端口使用。

new BundleAnalyzerPlugin({analyzerPort:7777})

然后重新打包后打包成功,并给我开启一个服务,展示包的依赖关系与体积大小。
在这里插入图片描述
在这里插入图片描述
从图上可看出那个最大的包是我引入的element-ui,我说我怎么解决不掉。这个原因是我直接将element-ui全部引入了,后面进行按需引入可以解决,就是使用到哪些控件就引入哪些控件。

总结

对于webpack打包优化,感觉内容很多也很杂,这里做一下总结:

  1. 进行打包优化时,无法分析出包体积大的原因时,可使用可视化打包工具来协助分析;
  2. 在开发环境中,一般不会注意打包优化这些的,基本用不到;
  3. 在生产环境中,对于打包优化webpack也进行了一些默认配置,平常使用默认配置即可,有特殊需求时可以手动更改配置;
  4. 文中使用到的scope Hoisting,js的Tree shaking,Terser等,平常开发使用默认配置即可,如有在生产环境中要去掉全部的console.log等需求,可对Terser再进行额外配置;
  5. 如需严格控制打包的每个文件的体积,就可以对splitChunk动刀子,代码分离就完事。

http://chatgpt.dhexx.cn/article/dekbeSG8.shtml

相关文章

webpack打包路径更改_webpack打包教程

创建package.json文件 命令:npm init 安装webpack npm install --save-dev webpack npm install --save-dev webpack-cli 全局安装: npm install --global webpack webpack-cli 打包 默认entry入口 src/index.js 默认output出口 dist/main.js 打包模式: webpack --mode deve…

Vue基础知识总结 9:vue webpack打包原理

🏆作者简介:哪吒,CSDN2022博客之星Top1、CSDN2021博客之星Top2、多届新星计划导师✌、博客专家💪,专注Java硬核干货分享,立志做到Java赛道全网Top N。 🏆本文收录于,Java基础教程系列…

webpack 打包流程

流程梳理 在开始之前我们先对于整个打包流程进行一次梳理。 这里仅仅是一个全流程的梳理,现在你没有必要非常详细的去思考每一个步骤发生了什么,我们会在接下来的步骤中去一步一步带你串联它们。 整体我们将会从上边5个方面来分析Webpack打包流程: 初…

Webpack打包

webpack【依赖node环境】 什么是webpack? 从本质上将,webpack是一个现代的JavaScript应用的静态模板打包工具。 前端模块化: 前端模块化是指,通过将前端代码根据一定的规则解耦封装成几个代码文件(模块)&…

使用webpack打包vue项目

使用webpack打包vue项目 安装webpack工具,安装方式有两种:全局安装(命令:npm install -g webpack webpack-cli)以及安装在项目中,这里使用第二种: //在项目中安装,这里的-D表示运用到…

Idea 2017.3.+永久破解方法

一、下载Intellij IDEA2017.3.5x64旗舰版 去官网下载此处不赘述 二、下载破解jar包 链接在此http://idea.lanyus.com/jar/JetbrainsCrack-2.7-release-str.jar 三、打开安装好的IDEA路径下的bin目录 将下载好的jar包复制进来 例如 四、修改bin目录下的两个文件 idea.exe…

InetlliJ IDEA 2017破解(亲测,可用)

1.InetlliJ安装好后,启动,至License Activation界面; 2.选择License server; 3.在License server address中填入 http://idea.imsxm.com/

Intellij IDEA2017安装破解

IntelliJ IDEA(2017)安装和破解 IDEA 全称 IntelliJ IDEA,是Java语言开发的集成环境,IntelliJ在业界被公认为最好的java开发工具之一,尤其在智能代码助手、代码自动提示、重构、J2EE支持、各类版本工具(Git、svn、gith…

idea 2017 破解 可以使用

新版本的 自从升级到idea2017.3之后,之前的license server破解方法貌似已失效.于是找到大神用的破解插件,很好很强大. 安装好idea之后不要打开软件,从http://idea.lanyus.com/下载破解插件,这里面的插件是进行更新的,可能已经不是下面的文件名了&#xf…

IntelliJ idea2017 安装破解

下载 idea的安装包可以去官网下载,地址:IDEA各个历史版本请点击下载,选择自己需要的版本进行下载,本人下载的是ideaIU-2017.3.6.exe版本专业版。 安装 1、开始安装, 双击ideaIU-2017.3.6.exe,运行安装文…

intelliJ idea 2017破解

一、先进入Intellij IDEA的官网:https://www.jetbrains.com,下载安装 二、破解。 网上的破解方法较多,总结下来大概有下面几种办法供大家作为参考 声明:破解用于学习和试用,如果有经济条件的话,请支持…

idea 2017 破解方法

一、先进入Intellij IDEA的官网:https://www.jetbrains.com,下载安装 二、破解。 网上的破解方法较多,总结下来大概有下面几种办法供大家作为参考 声明:破解用于学习和试用,如果有经济条件的话,请支持…

IDEA 2017破解补丁方法

本文使用破解方式注册。 下载破解文件JetbrainsCrack-2.6.2.jar 下载地址: http://download.csdn.net/detail/gnail_oug/9824630 http://idea.lanyus.com/ 开始破解 一、将下载的 JetbrainsCrack-2.6.2.jar 破解补丁放在你的安装idea下面的bin的目录下面&#xff0…

INTELLIJ IDEA 2017 破解教程(2018也可以!)

INTELLIJ IDEA 破解教程 我们一般都用licence server来激活idea,网上传闻较广的licence server是 http://idea.iteblog.com/key.php,但是该server在2017年12月后就失效了,故我们现在不用licence server,直接破解吧! …

IDEA 2017 破解 license 激活

IDEA 2017 破解 license 激活 转自:http://blog.csdn.net/zhangwenwu2/article/details/54948959 进入ide主页面,help-register-license server,然后输入 http://idea.iteblog.com/key.php(注意:php要小写)即可~ 如下图…

IDEA 2017 破解教程(2018也可以)

点击 安装教程 获取安装详细步骤。 补充: 这一行是破解的jar包(JetbrainsCrack-2.7-release-str.jar)所在路径,本人的这个jar包已下载(在安装教程链接里面有下载地址)。 而且,这么配是错的。应…

intelliJ IDEA 2017 破解方法

原地址:http://blog.csdn.net/u013673242/article/details/72243066?utm_sourceitdadao&utm_mediumreferral 本文使用破解方式注册。 下载破解文件JetbrainsCrack-2.6.2.jar 下载地址: http://download.csdn.net/detail/gnail_oug/9824630 http://…

GAN(对抗生成网络)原理及数学推导

本文主要涉及GAN网络的直观理解和其背后的数学原理。 参考课程: 计算机视觉与深度学习 北京邮电大学 鲁鹏 概述 在所有生成模型中,GAN属于 “密度函数未知,直接硬train” 的那一类,和密度函数可定义的PixelRNN/CNN以及变分自编码…

对抗生成网络GAN系列——GANomaly原理及源码解析

🍊作者简介:秃头小苏,致力于用最通俗的语言描述问题 🍊往期回顾:对抗生成网络GAN系列——GAN原理及手写数字生成小案例   对抗生成网络GAN系列——DCGAN简介及人脸图像生成案例   对抗生成网络GAN系列——AnoGAN原…

强化学习和生成对抗网络

1. 强化学习的定义 强化学习(reinforcement learning)是机器学习的一个重要分支,是一门多领域交叉学科,它的本质是自行解决决策问题,并且能进行连续决策。 强化学习有四个主要组成部分∶ 1.代理(Agent&…