文章目录

  • 前言
  • 不进行任何打包配置
  • 代码分离
    • 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动刀子,代码分离就完事。

webpack打包优化配置相关推荐

  1. webpack打包vue反编译_2020年你必须知道的webpack打包优化方法

    本文字数:3534字 预计阅读时间:10分钟 随着我们的项目项目越做越大,引入的第三方库会越来越多,打包的依赖也越来越多,每次 build 的时间越来越长,打包出来的文件会越来越大.最糟糕的是单页面应 ...

  2. webpack打包优化

    webpack打包优化 开发环境优化 1.开启热模块替换(HMR) **原因:**如果不开启 HMR功能 的话,修改某一个模块的时候,所有模块都会重新打包 实现: 给devServer添加 hot:t ...

  3. 混合开发与移动端--H5混合开发、H5页面的开发布局、开发注意事项、H5与原生(安卓)交互、webpack打包优化解决方案、H5调试工具、webview

    H5混合开发 混合开发.原生开发.H5开发的区别: 简述:主流APP:原生APP.H5(webapp).混合APP,相对应的定制研发即原生开发.H5开发.混合开发 原生APP开发优缺点: 可以访问手机 ...

  4. Webpack打包优化-外部扩展externals的实际应用

    Webpack打包优化-外部扩展externals的实际应用 拆分文件 我们在使用js库如vue或者react等的时候,webpack会将他们一起打包,react和react-dom文件就好几百k,全 ...

  5. webpack打包优化之外部扩展(Externals)配置

    基本使用 webpack可以使用externals配置,将某些模块不打包到输出文件中,从而使用用CDN引入外部模块 这样操作下来,不仅可以提高打包速度,还能优化网页加载性能. index.html & ...

  6. webpack打包优化_前端性能优化:webpack性能调优与Gzip原理

    链接:https://juejin.im/book/5b936540f265da0a9624b04b 从输入 URL 到显示页面这个过程中,涉及到网络层面的,有三个主要过程: DNS 解析 TCP 连 ...

  7. webpack打包优化_提速MAX 京东通天塔WEBPACK构建发布优化实践

    通天塔作为运营.商家搭建营销活动页的主力系统,数年来一直致力于提供用户更丰富.更强大的搭建体验.通天塔可视化CMS(简称可视化)作为直面商家运营搭建的第一层,在系统能力越来越强大的同时,自身的代码量. ...

  8. webpack打包优化之外部扩展externals的实际应用

    目录 前言 externals定义 用法 string array object function regex 实际案例 打包时间 打包之后包的大小 浏览器加载 需要注意 参考 前言 使用vue-cl ...

  9. 看看webpack打包优化

    webpack 打包策略,主要有下列几种方法. 1.CDN2.DllPlugin3.splitChunks4.happypack 下面详细介绍使用的流程. CDN 通常使用的第三方模块很大时,但是又想 ...

最新文章

  1. 美电信运营商Verizon推企业云计算服务
  2. Vue.2.0.5-模板语法
  3. Go工程化 - 手摸手带你理解依赖注入
  4. OpenCV 常用网址和基础知识
  5. jQuery橙色的网页右侧悬浮在线客服代码
  6. 空间数据挖掘与空间大数据的探索与思考(三)
  7. HTML控件事件一览表
  8. Object类中的hashCode方法
  9. 微信小程序背景图片不显示
  10. 是德科技34461a万用表
  11. IIS搭建http服务
  12. 2017腾讯LIVE开发者大会精彩回顾!
  13. 数字电子时钟的设计与实现
  14. excel转换成pdf java_Java基于Spire Cloud Excel把Excel转换成PDF
  15. Ubuntu18.04离线安装网卡驱动、gcc、make等
  16. CPIM SRM考试通过
  17. 西电计算机学院王宇平,王宇平 | 个人信息 | 西安电子科技大学个人主页
  18. 51单片机时钟(闹钟)
  19. 基于AIPL体系的用户生命周期管理—阿里数据银行指标体系
  20. SP8093 JZPGYZ - Sevenk Love Oimaster(广义SAM)

热门文章

  1. 计算机课程论文条件保障,论文的现有条件怎么写_完成课题的保障条件怎么写_论文结语怎么写文库...
  2. Windows扫雷的设计思路与实现
  3. java支持哪三种注释方式,震撼来袭免费下载!
  4. Android 源代码在线查看
  5. 联想z50-70,WiFi不能用解决办法
  6. js案例 小米秒杀倒计时 新年倒计时
  7. 如何修改Word页面的显示大小
  8. 蓝桥杯嵌入式第七届省赛——“模拟液位检测告警系统”旧板标准库
  9. 低通信道与带通信道的区别
  10. Perl中的闭包(closure)