webpack源码中一些精妙的方法总结

 更新时间:2022年02月11日 15:07:43   作者:花开花落花中妖  
正好最近在学习webpack的源码,所以下面这篇文章主要给大家介绍了关于webpack源码中一些精妙的方法的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下

前言

过年这一段时间一直在研究webpack的源码,由于过年周围气氛比较欢快,心态有点飘导致没有沉下心来仔细研究其中的细节。经过反思之后,静心重新捋顺webpack的源码,这时发现不少巧妙的方法值得学习。这里我已经迫不及待的跟大家分享了,希望对大家平常开发过程中有所帮助。

精妙方法

缓存函数

这个方法最精妙的地方在于将执行结果缓存,减少函数的重复执行以达到提升性能的目的,对于执行越复杂越耗时的函数收益越大。但是,不适用于动态执行结果的函数

    const memoize = fn => {
        let cache = false;
        let result = undefined;
        return () => {
            if (cache) {
                return result;
            } else {
                result = fn();
                cache = true;
                fn = undefined;
                return result;
            }
        };
    };

这个方法跟惰性函数有点相似,只在函数第一次调用的时候执行,将fn()的执行结果缓存到result上,然后通过cache设置为true来标记缓存已开启。这里还有个细节值得学习:由于闭包的原因,fn方法被新的函数持有,一直在调用栈中得不到释放,而在代码中有一句fn = undefined,手动释放内存。

属性劫持

这个方法通过自定义get方法或者value值来重定义obj的属性。实现的结果有点类似于Object.freeze,但又不完全相同。通过Object.defineProperty定义name的get属性描述符来保证obj的值永远不变;通过Object.defineProperty来将name的writable设置为false来保证obj的value不会被改变。

    const mergeExports = (obj, exports) => {
        ...
        for (const name of Object.keys(descriptors)) {
            const descriptor = descriptors[name];
            if (descriptor.get) {
                const fn = descriptor.get;
                Object.defineProperty(obj, name, {
                    configurable: false,
                    enumerable: true,
                    get: memoize(fn)
                });
            } else if (typeof descriptor.value === "object") {
                Object.defineProperty(obj, name, {
                    configurable: false,
                    enumerable: true,
                    writable: false,
                    value: mergeExports({}, descriptor.value)
                });
            } else {
                ...
            }
        }
        return Object.freeze(obj);
    };

这里还有个小的知识点:通过将属性的configurable属性描述符设置为false来保证属性不可被删除

数组比较

进行两个数组是否相等的比较。想必大家都知道,如果使用==进行数组比较的话,是进行引用地址的比较,所以想要判断两个数组是没有方法进行直接比较的。而webpack源码中的这个方法给我提供了一种数组比较的方式。当然了,这个方法只适用于扁平化的一维基本类型数组,如果想要比较复杂的情况的话,需要在for循环的基础上稍加改造。

    exports.equals = (a, b) => {
        if (a.length !== b.length) return false;
        for (let i = 0; i < a.length; i++) {
            if (a[i] !== b[i]) return false;
        }
        return true;
    };

配置项校验

webpack中的实现的代码量比较多,我们就只说一下大体实现思路,通过定义需要校验的所有配置项的Schema校验规则。大体Schema格式如下:

    "Amd": {
        "description": "Set the value of `require.amd` and `define.amd`. Or disable AMD support.",
        "anyOf": [
            {
                "description": "You can pass `false` to disable AMD support.",
                "enum": [false]
            },
            {
                "description": "You can pass an object to set the value of `require.amd` and `define.amd`.",
                "type": "object"
            }
        ]
    },

其中key对应的是需要校验的配置项,value中的desciption对应的是提示信息,其余部分对应的是校验规则。

结尾

到此这篇关于webpack源码中一些精妙的方法的文章就介绍到这了,更多相关webpack源码的精妙方法内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 原生JS实现前端本地文件上传

    原生JS实现前端本地文件上传

    这篇文章主要为大家详细介绍了原生JS实现前端本地文件上传,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-09-09
  • Google 爬虫如何抓取 JavaScript 的内容

    Google 爬虫如何抓取 JavaScript 的内容

    我们测试了谷歌爬虫是如何抓取 JavaScript,下面就是我们从中学习到的知识,需要的朋友可以参考下
    2017-04-04
  • JS简单生成随机数(随机密码)的方法

    JS简单生成随机数(随机密码)的方法

    这篇文章主要介绍了JS简单生成随机数(随机密码)的方法,简单分析了javascript随机数相关函数并结合具体实例形式分析了随机数的相关生成技巧,需要的朋友可以参考下
    2017-05-05
  • JavaScript六种常见的继承方法分享

    JavaScript六种常见的继承方法分享

    继承是面向对象编程中的一个重要概念,它允许一个对象(子类或派生类)获取另一个对象(父类或基类)的属性和方法,在 JavaScript 中,有多种方式可以实现继承,本文将给大家介绍六种常见的JavaScript继承方法,需要的朋友可以参考下
    2023-09-09
  • 阻止子元素继承父元素事件具体思路及实现

    阻止子元素继承父元素事件具体思路及实现

    想要阻止点击#p_cont区域时触发a事件,需要在#p_cont区域内加入阻止事件冒泡的代码,具体实现祥看本文,希望对你有所帮助
    2013-05-05
  • js用闭包遍历树状数组的方法

    js用闭包遍历树状数组的方法

    这篇文章主要介绍了js中用闭包遍历树状数组的方法,需要的朋友可以参考下
    2014-03-03
  • 微信小程序在text文本实现多种字体样式

    微信小程序在text文本实现多种字体样式

    这篇文章主要介绍了微信小程序在text文本实现多种字体样式,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-11-11
  • vant倒序年月日期组件封装实例详解

    vant倒序年月日期组件封装实例详解

    这篇文章主要介绍了vant倒序年月日期组件封装实例详解,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧
    2024-03-03
  • 关于better-scroll插件的无法滑动bug(2021通过插件解决)

    关于better-scroll插件的无法滑动bug(2021通过插件解决)

    这篇文章主要介绍了关于better-scroll插件的无法滑动bug(2021通过插件解决),本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-03-03
  • Javascript实现鼠标右键特色菜单

    Javascript实现鼠标右键特色菜单

    鼠标右键大家都经常操作,但是鼠标的内容是不是符合大家的“口味”?这篇文章就是教大家如何定制自己专属鼠标右键,需要的朋友可以参考下
    2015-08-08

最新评论