当前位置: 首页 > 后端技术 > Node.js

辛辛苦苦学来的webpackdll配置可能已经过时了

时间:2023-04-03 16:54:01 Node.js

前段时间写了一篇解释webpack4中容易混淆的知识点的文章。没想到得到了将近600个赞。在这里要感谢大家。在上一篇文章中,我花了很多时间来构思演示和原图,只是为了彻底理清一些概念。看着评论区的回复,感觉达到了自己定下的目标。如果你看过一些webpack4优化的文章,肯定有dll动态链接库。复杂的配置让很多初学者记忆犹新。今天我将从一个学习者的角度来一步步讨论webpackdll的配置,最终得出一个完美的解决方案。本文内容与大部分讲解webpack4优化的文章不同。如有不同意见,欢迎在评论区与我讨论。
友情提示:本文不是入门教程,不会花费大量的笔墨来描述webpack的基本配置。请读者配合教程源码。
1.基本概念:dll其实就是一个缓存。说实话,当我第一次看到这个dll动态链接库的时候,着实吓了一跳:这是什么东西?为什么从来没有听说过?很快google了一下,找到了维基百科的标准定义:所谓动态链接就是把一些经常共享的代码做成dll文件。当可执行文件调用DLL文件中的函数时,Windows操作系统将启动DLL文件加载到内存中。DLL文件的结构本身就是一个可执行文件,函数会在程序需要的时候链接起来。通过动态链接的方式,可以大大减少内存浪费的情况。唉,你们的官员就是不讲人话。我结合webpack,从前端的角度来翻译:具体到webpack,就是把常用但需要很长时间提前构建的代码打包(比如react,react-dom),命名为dll.后面重新打包的时候,跳过原来解包后的代码,直接使用dll。这导致更短的构建时间和更快的webpack打包。我盯着上面这句话看了三分钟,什么DLL,什么动态链接库,在前端世界,不就是个缓存吗!他们用空间换取时间。注:狭义上可以理解为用空间换取时间。如果真要讨论dll背后的知识:动态链接库和静态链接库,又会涉及到编译器的知识,再详细说说又是新文章了。文章,所以暂时压在桌子上。下面对比一下前端经常接触的DLL和网络缓存,一张表就可以看的一清二楚:DLL缓存1.将常用的代码打包成DLL文件保存到硬盘中1.保存常用的文件到硬盘/内存2.二次第一次打包时动态链接DLL文件,无需重新打包2.第二次加载时直接读取缓存,无需重新请求3.缩短打包时间3.缩短加载时间所以在前端世界中,DLL是一种替代缓存。2.DLL手动配置:这么多步骤记不住了。我们不要一开始就做配置。想象一下,如果让你手动创建和管理缓存,你会怎么做?我想大家的思路一般是这样的:第一次请求的时候,存储请求之后的内容,建立映射表。如果没有缓存,如果有,就加载缓存,如果没有,就按照正常的请求流程(也就是所谓的缓存命中问题)。命中缓存后,直接从缓存中取出内容,交给程序处理。主要流程无非就是这3个步骤。做大的话可以加更多的权重,过期时间,多级缓存等等,但是主要流程就是上面3个步骤。一般我们在开发的时候,浏览器和http协议可以帮我们封装这些操作,我们只需要记住几个参数,调整即可;但是webpackdll就不一样了,它需要我们手动去实现上面的3个步骤,所以非常枯燥+繁琐。下面的代码比较乱,因为我本来不打算讲这些绕口的配置。具体结构最好看我github上发布的示例源码。如果你不明白也没关系。以后有更好的解决办法。如果您觉得无聊,请跳过以下内容的第一步。我们首先需要创建一个dll文件,相当于存放了第一个请求的内容,然后我们需要创建一个映射表,告诉程序我们要什么文件做一个dll(这个相当于第2步):首先我们写一个打包脚本创建一个dll文件,目的是将react,react-dom打包成一个dll文件://文件目录:configs/webpack.dll.js//代码太长忽略'使用严格的';constpath=require('路径');constwebpack=require('webpack');module.exports={mode:'production',entry:{react:['react','react-dom'],},//这是输出的dll文件output:{path:path.resolve(__dirname,'../dll'),filename:'_dll_[name].js',library:'_dll_[name]',},//这是输出映射表plugins:[newwebpack.DllPlugin({name:'_dll_[name]',//name===output.librarypath:path.resolve(__dirname,'../dll/[name].manifest.json'),})]};打包脚本写好了,我们要跑起来对不对?所以我们写一个运行脚本放在package.json的scripts标签中,这样我们就可以通过运行npmrunbuild:dll://package.json{"scripts":{"build:dll"来打包dll文件:"webpack--configconfigs/webpack.dll.js",},}第三步,链接dll文件,也就是告诉webpack命中的dll文件,配置也是一大堆://文件目录:configs/webpack.common.js//代码太长忽略constpath=require('路径');constAddAssetHtmlPlugin=require('add-asset-html-webpack-plugin');//顾名思义,给html添加资源,然后这个插件给index.html添加dllconstwebpack=require('webpack');module.exports={//......plugins:[newwebpack.DllReferencePlugin({//注意:DllReferencePlugin的context必须和package.json同级,否则会链接失败context:path.resolve(__dirname,'../'),manifest:path.resolve(__dirname,'../dll/react.manifest.json'),}),newAddAssetHtmlPlugin({filepath:path.resolve(__dirname,'../dll/_dll_react.js'),}),]}为了减少一些大库的二次打包时候,我们在3个文件里写了一堆配置代码。链接失败(是的,就是我)配置dll会给人带来巨大的心理阴影。有没有其他方法可以减轻我们的精神负担呢?3.AutoDllPlugin:解放你的配置负担。第二节疯狂劝退。我只是想介绍一下这个插件:autodll-webpack-plugin。这个插件将以上3段代码整合为一体,让我们摆脱繁琐的配置,下面看看如何使用://文件目录:configs/webpack.common.jsconstpath=require('path');constAutoDllPlugin=require('autodll-webpack-plugin');//第一步:引入DLL自动链接库插件module.exports={//......plugins:[//第二步:配置打包为dll的文件newAutoDllPlugin({inject:true,//设置为true并且只有DLL包被插入到index.htmlfilename:'[name].dll.js',context:path.resolve(__dirname,'../'),//AutoDllPlugin的上下文必须是与package.json同目录,否则链接会失败entry:{react:['react','react-dom']}})]}autodll-webpack-plugin的用法和其他的用法很相似webpack的plugins,和手动引入dll的方法相比,简单多了,而且这个插件之前vue-cli用过,质量比较稳定,大家可以放心使用。4、放弃DLL:Vue&React官方常用的选择在第3节,我说了autodll-webpack-plugin是之前vue-cli使用的。意思是现在不用了?有错误吗?事实并非如此。在学习webpack的时候,为了借鉴业界优秀框架的webpack配置,我特地看了vue-cli和create-react-app的源码,但是并没有发现dll配置的痕迹。这很奇怪。之前看过一些nuxt.js1.0的源码,里面有dll的配置代码。按道理vue-cli应该也有。我猜是在升级过程中删除了dll。于是我开始查找commit记录,结果发现:黑白两色,删除DLL选项3明明是大字写的,请问是什么原因呢?于雨溪在本期解释了移除的原因:dll选项将被移除。Webpack4应该提供足够好的性能,在VueCLI中维护DLL模式的成本不再是合理的。dll配置将被删除,因为Webpack4的打包性能足够好,并且dll不需要在VueCLI中维护了。同样,在这个PR中的create-react-app中也给出了类似的解释:webpack4打包性能优于dll。所以,如果项目安装的是webpack4,使用dll的好处不是很大。我用实际项目的代码试了一下。添加dll可能会提升1-2s的速度,对于整体的打包时间来说可以说是微不足道。Vue和React都在2018年正式不再使用dll了,现在2019年都快结束了,所以我上面说的没用了,也没必要学了,是不是松了一口气(疯狂提示之类的)?5.插件dll的加速,比DLL好,不明显。有更好的替代品吗?在AutoDllPlugin的README.md中,推荐给我们HardSourceWebpackPlugin,初始配置更简单,只需要一行代码:constHardSourceWebpackPlugin=require('hard-source-webpack-plugin');module.exports={//......plugins:[newHardSourceWebpackPlugin()//<-直接添加这行代码即可]}这个插件的加速有多明显?我用本文中的示例代码对其进行了测试。下图是正常打包时间,900ms左右:加入dll优化后,打包时间为507ms,缩短了400ms左右:只使用HardSourceWebpackPlugin,打包时间缩短为253ms:看相关文档,好像这个技术是直接放到webpack5里面开箱即用的。所以,虽然不需要学习dll的配置,但是webpack5来了……6.这篇文章写到最后不好说了。探索过程。说实话,手动配置dll后,我觉得自己挺nb的。这么复杂的配置我都能配置。当我找到autodll-webpack-plugin的时候,发现dll已经被废弃了,其实有点失望。觉得自己之前的努力都白费了,不禁觉得自己学不会了。但是仔细想想dll的原理,发现只是时间问题,用空间换时间,只是配置比较复杂。所以这也提醒我们,在学习新知识的时候,不要把注意力放在流程配置和参数调整上。因为流程终将简化,参数(API)终将升级。一定要抓大放小,抓核心内容,因为核心思想最不容易过时。7.面试必备参考书!webpack中最容易混淆的5个知识点webpack官方文档autodll-webpack-pluginHardSourceWebpackPlugin终于打广告了,业余写了一些关于数据可视化科普的文章,目前一周一篇,内容不技术。我目前正在写一个不需要写代码的爬虫教程。如果觉得不错,可以推荐给非技术的同事。公众号ID是sky-chx,有兴趣的可以关注一下。