【源码解读】模块懒加载(在使用时)

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

思想

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

使用方式

1
2
3
4
const importLazy = require('import-lazy')(require);
const _ = importLazy('lodash');

_.isNumber(2); // 在使用的时候才触发模块加载

实现方式

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
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的时候不能按需加载

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

Liang

发布于

2021-09-23

更新于

2023-04-19

许可协议


评论