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

《深入浅出webpack》感觉

时间:2023-04-03 15:18:50 Node.js

对于前端小白来说,相信大家都对webpack很熟悉了,但是你对webpack的理解到底有多深呢?花了几天时间看了《深入浅出webpack》,虽然书中的大部分介绍都是配置和使用相关的,但是如果你对webpack的配置、使用、原理和构建过程比较熟悉的话,可以说是对你的发展无害!这篇文章不会局限于配置的介绍,也不会详细介绍打包的原理(我打算后面写一篇关于webpack打包原理的文章~),更侧重于介绍的思想webpack打包。在没有打包构建的年代,nodejs的出现对于构建工具来说意义重大。在nodejs之前,js只能在浏览器环境下执行,所以意味着发布前的js文件必须处理,非常有限,而且没有打包工具,只能用PHP脚本来处理文件,甚至需要依靠一些在线压缩网站。打包压缩工作;2、文件没有模块化,直接用CDN导入第三方库,需要处理依赖管理,人为控制脚本的加载顺序,存在全局变量命名冲突的问题;3、缺乏代码校验自动化测试,代码提交入库前,需要验证代码是否符合规范,单元测试是否通过。随着打包构建工具的时代,随着nodejs的诞生,我们可以在开发环境中编写nodejs代码脚本,预处理我们的前端代码,编译压缩等等。最初,诞生了grunt和gulp,而Grunt和Gulp都属于任务流工具TastRunner,都是通过配置配置文件来配置的,但是相比之下,gulp是以函数式的方式编写配置文件的,而前端人员熟悉的chaincall让大家感觉更容易理解和使用,gulp是借鉴了grunt的经验升级和增加了一些新特性。由于流管理和多任务配置输出的改进,人们逐渐选择使用Gulp而不是grunt。有了grunt和gulp,文件压缩处理的工作就解决了,代码验证和测试也可以搞定,但是模块化还是没有结果?其实前端的痛点远不止简单的模块化。频繁的DOM节点处理,JS混合了交互逻辑、请求逻辑、数据处理和验证逻辑、DOM操作逻辑,让JQ写的代码更意大利化。呸!炒意大利面也一样。在团队开发中,你的代码可能需要别人维护,这是非常痛苦的。webpack的诞生1.模块化思想隔离不同的js文件,模块化开发,只暴露当前模块需要的其他模块。这就是模块化思想想传递给我们的东西。nodejs诞生后,后端采用的模块化思想是commonjs。但是,与后端不同的是,前端代码运行在浏览器端。区别有两个:1.没有nodejs执行环境,不支持module.exports2.后端需要一个文件,是读取本地文件的形式,速度极快,但是对于前端来说,它需要动态加载一个js文件,需要额外的时间。于是AMD的想法应运而生。这个对应的实现是requireJS,可以定义模块名称、模块依赖、当前模块代码(函数),通过广度优先遍历递归加载父模块依赖的子模块。但是这也暴露了一些问题:1.通过js加载执行后,加载它所依赖的子模块。这个递归加载过程本身很耗时;2、模块化思想提倡我们把逻辑分离,把每个js文件管理好。内部逻辑,一旦拆分的JS文件过多,最终会造成前端资源加载压力。不过不用担心,requireJS提供了r.js来处理发布前的模块合成,帮你把多个JS文件打包成一个文件。后来国内出现了CMD的idea,区别于AMD的声明式依赖形式,可以让你动态加载依赖,但是它的实现方式和具体的运行结果却被大家诟病。后来为了解决模块在不同库中实现不一致的问题,提出了UMD,其实很简单,写个hack就可以让你的模块兼容不同的模块加载场景,不管是commonjs还是AMD,如果如果没有,直接声明为全局变量。下面引用了一段UMD代码:'&&define.amd?define(factory):(global=global||self,global.Vue=factory());}(this,function(){'usestrict';//你的代码在这里}然后稍后,未来统一,es6中提出的import和export的形式统一前后端的模块化加载方式,import/export的形式相比之前的实现,保留了模块化加载JS文件时动态执行的引用,其次,不允许动态控制加载依赖,使得tree-shaking成为可能。2.组件化思维。assign一起开发一个首页,包括导航栏,轮播图,网站列表数据,登录框等,两者如何实现需要分工合作?导航栏和列表需要在多个页面复用怎么办?如果没有组件处理怎么办:1.A和B分工困难,麻烦,大量的提交代码时会处理冲突;2、对于导航栏、列表等多处复用的地方,需要直接将cv大法复制粘贴到另一个页面中使用。组件化的思想,让我们把页面分成组件。组件维护自己的UI显示和交互逻辑,组件之间可以进行数据通信,实现变相的相互隔离。用B编辑一段html的难受场景,同时提高了代码的可维护性和复用性,这是它解决的重点痛点。引用vue官网上的一张图关于组件化的思想:3.MVC框架和MVVM框架的流行,在模块化和组件化的基础上实现了页面组件的隔离和维护,但是面临的最大的痛点问题还是和上面说的一样。前端JS逻辑混合了各种处理逻辑、交互逻辑、请求逻辑、数据处理和验证逻辑、DOM操作逻辑;其实这一切都可以分为两个层次。一个是数据层,一个是视图层,如何避免DOM逻辑的重复编写和操作,如果说早期的各种模板引擎给了我们初步的解决方案,那么vue、react和angular都是基于模板引擎上层建筑。为了让我们更专注于数据处理,MVC框架和MVVM框架帮助我们做了以下两件事:1.监听页面操作事件,触发相应的事件钩子,执行代码逻辑,即从V开始的流程层到M层;2、代码逻辑执行完毕后,修改数据层,帮助我们更新渲染页面,即M层到V层的过程;在vue中是通过vm实现的,在react中是通过触发setState来通知的。这样我们只需要写一次html,在html中指定绑定或者显示的数据,同时绑定事件监听器,这样我们就不需要处理view层相关的操作以后,只需要关注自己的业务逻辑代码,数据层处理等即可。MVVM架构流程图:4.代码打包构建前面介绍了grunt和gulp打包构建工具。其实webpack的本质也是一个打包构建工具,只是webpack所呈现的功能更加强大和成熟。对于代码预处理、模块化加载、代码拆分等,webpack有更大的优势。webpack诞生了!读者读到这里,可能还有一些疑惑。说了这么多,为什么不引入webpack呢?事实上,并非如此。仔细想想前面介绍的思路,平时使用webpack打包构建的时候。事实上,webpack正在帮助你处理这些复杂而琐碎的事情。如果代码预处理压缩就足够了,那么grunt和gulp就足够了;如果模块化开发就足够了,那么requireJS和Browserify就足够了;如果组件化开发和MV*框架就足够了,那你只需要引入相应的Vue或者react框架就可以了。作者写这篇文章更多是为了让大家思考工具或者框架背后的思想。Webpack就像一个巨人,一个大师,它解决了打包构建,它处理了模块化开发,它帮助你与其他框架完美集成,实现组件化开发;而MV*框架在过去几年的流行为webpack市场的快速扩张做出了很大贡献。Webpack为我们做了以下事情:(引自《深入浅出webpack》)代码转换:TypeScript编译成JavaScript,SCSS编译成CSS等文件优化:压缩JavaScript、CSS、HTML代码,压缩合并图像等代码拆分:提取多个页面的公共代码,将不需要在首屏执行的代码提取出来,让它异步加载。模块合并:一个模块化项目中会有很多模块和文件,需要一个构建函数将模块分类合并到一个文件中。自动刷新:监控本地源代码变化,自动重建和刷新浏览器。代码校验:代码提交入库前,需要校验代码是否符合规范,单元测试是否通过。其实以小见大。看到的不仅仅是webpack的思想,还有前端的开发。从最初不规范的本土化炼钢,到今天的模块化、组件化、MV*架构,是前端思想的进步。作为一个前端小伙,我们更应该去探索和研究的是如何磨刀,把刀磨好,而不仅仅是砍柴。谢谢观看~