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

每天看一点webpack-001

时间:2023-04-03 10:39:38 Node.js

每天看一点webpackday-01-webpack入门npm包我们可以通过package.json中的包信息文件快速定位到这个包的入口文件,通过main字段获取webpack包信息整个webpack项目的入口位置是lib/index.js入口文件。入口文件通过动态导入的方式集成了项目的各个模块,比如各种内部插件、内部依赖、内部配置信息等。包的缓存通过入口文件中的一个缓存方法lazyFunction进行缓存,源码如下//通过lazyFunction缓存指定的包constfn=lazyFunction(()=>require("./webpack"));如何实现包缓存?lazyFunction实际上使用闭包来缓存包。我们先来看关键源码。memoize方法通过闭包将函数fn的执行结果缓存在入参中,这样下次想要获取fn函数的返回结果就不需要执行fn方法了。constmemoize=fn=>{letcache=falseletresult=undefined//返回一个函数构造一个闭包用于缓存fn函数的返回值return()=>{if(cache){returnresult}else{result=fn()cache=truereturnresult}}}而lazyFunction只是对上面memoize方法的简单封装,使得返回的方法支持参数传递,其实相当于一个柯里化过程。但是memoize不接受它的传入参数,所以这种封装没有任何作用。其实直接一步修改memoize方法,让它接受输入参数作为返回值函数,传给fn函数就可以达到想要的效果了,constlazyFunction=factory=>{constfac=memoize(工厂);constf=(...args)=>{returnfac()(...args);}返回f;};在包的合并入口文件中,并不是简单的合并依赖,而是通过mergeExports方法Assemble合并各个模块。该方法主要是利用Object.defineProperty来达到对象组装的目的。这样做的目的是为了更好地控制对象的属性,如读、写、删除和枚举属性。相关源码如下:getOwnPropertyDescriptors用于获取对象上所有属性的描述符。该方法采用递归的方式将对象类型的属性展开,从而保持源代码模块之间的特殊关系,同时减少模块功能的应用。复杂。constmergeExports=(obj,exports)=>{constdescriptors=Object.getOwnPropertyDescriptors(exports);for(constnameofObject.keys(descriptors)){constdescriptor=descriptors[name];if(descriptor.get){constfn=descriptor.get;Object.defineProperty(obj,name,{configurable:false,enumerable:true,get:memoize(fn)});}elseif(typeofdescriptor.value==="object"){Object.defineProperty(obj,name,{configurable:false,enumerable:true,writable:false,//通过递归的方式将对象类的属性平铺打开值:mergeExports({},descriptor.value)});}else{thrownewError("暴露的值必须是getter或嵌套对象");}}return/**@type{A&B}*/(Object.freeze(obj));};