关于javascript:每天读一点webpack001

32次阅读

共计 1663 个字符,预计需要花费 5 分钟才能阅读完成。

每天读一点 webpack

day-01-webpack 入口

  • npm 包咱们能够通过 package.json 中的包信息文件疾速的定位到这个包的入口文件,通过 webpack 的包信息 main 字段能够失去整个 webpack 我的项目的入口地位为 lib/index.js

入口文件

  • 入口文件中通过动静导入的形式将我的项目的各个模块进行整合,如各种外部插件,外部依赖,外部配置信息等。

包的缓存

  • 在入口文件中通过一个缓存办法 lazyFunctionwebpack 这个模块进行了缓存操作,其中源码如下

    // 通过 lazyFunction 对指定包进行缓存操作
    const fn = lazyFunction(() => require("./webpack"));
  • 如何实现包的缓存?lazyFunction 其实是应用了 闭包 的形式对包进行了缓存。先看要害源码,memoize 办法通过闭包的形式将入参中函数 fn 的执行后果缓存起来,这样在下次想要获取 fn 函数的返回后果时就无需在执行 fn 办法了。

    const memoize = fn => {
    let cache = false
    let result = undefined
    // 返回一个函数 结构一个 闭包,用于缓存 fn 函数的返回值
    return () => {if(cache) {return result}else {result = fn()
        cache = true
        return result
      }
    }
    }
  • lazyFunction 只是对以上 memoize 办法的简略封装,使得其返回的办法反对参数传递,实际上相当于一次柯里化解决。然而 memoize 中并没有承受其传入的参数,因而此次封装并无成果。其实能够间接将 memoize 办法进行一步革新,让其作为返回值的函数承受入参,并传递给 fn 函数即可达到预期成果,

    const lazyFunction = factory => {const fac = memoize(factory);
      const f = (...args) => {return fac()(...args);
      }
      return f;
    };

包的合并

  • 入口文件中并没有简略对依赖进行组合,而是通过 mergeExports 办法对各个模块进行了 组装 。该办法次要通过Object.defineProperty 来达到对象组装的目标,这样做的目标是,能够更好的对对象的属性进行管制,如属性的 读、写、删除、枚举。相干源码如下

    • getOwnPropertyDescriptors 用于获取对象上 所有属性 的描述符
    • 该办法中应用了递归的形式将 对象类型的属性平铺开来,这样使得 源码模块特间关系能够放弃的同时,升高了模块性能利用的复杂性

      const mergeExports = (obj, exports) => {const descriptors = Object.getOwnPropertyDescriptors(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 {
              throw new Error("Exposed values must be either a getter or an nested object");
          }
      }
      return /** @type {A & B} */ (Object.freeze(obj));
      };

正文完
 0