JS的模块懒加载

594 阅读1分钟

模块懒加载

在看为什么vue文档能做到新内容可用更新(利用service worker)的时候,顺便看到了update-notifier(提示版本更新的库,实现方式:定时检查npm上的版本和本地package.json的版本对比,有差异就提示用户更新),看update-notifier源码的时候发现有很多lazyImport,觉得挺新奇,于是有了这篇文章

思想

为了提高应用的启动时间,在没有用到仓库的额外功能时不加载模块,所以将模块加载延迟到使用之前

使用方式

const importLazy = require('import-lazy')(require);
const _ = importLazy('lodash');
​
_.isNumber(2); // 在使用的时候才触发模块加载

实现方式

实际上是用proxy代理了get操作,在get的时候才触发模块加载

const lazy = (importedModule, importFn, moduleId) =>
    importedModule === undefined ? importFn(moduleId) : importedModule;module.exports = importFn => {
    return moduleId => {
        let importedModule;
​
        const handler = {
            get: (target, property) => {
                importedModule = lazy(importedModule, importFn, moduleId);
                return Reflect.get(importedModule, property);
            },
            apply: (target, thisArgument, argumentsList) => {
                importedModule = lazy(importedModule, importFn, moduleId);
                return Reflect.apply(importedModule, thisArgument, argumentsList);
            },
            construct: (target, argumentsList) => {
                importedModule = lazy(importedModule, importFn, moduleId);
                return Reflect.construct(importedModule, argumentsList);
            }
        };
​
        // eslint-disable-next-line prefer-arrow-callback
        return new Proxy(function () {}, handler);
    };
};

这也导致我们在使用import-lazy的时候不能按需加载

const {isNumber, isString} = importLazy('lodash'); // 不支持