一个模块加载器一般来说会在全局暴露出 define 和 require 两个函数。
define用来定义一个模块,其参数为:当前的模块名、依赖的模块名列表、当前模块的实现。
require用来加载并执行模块,其参数为:运行依赖的模块名列表、当前要执行的函数。
为此,我们需要对 define和requrie进行实现,以实现如下调用。
function define(name, deps, callback) { // todo... } function require(deps, callback) { // todo... } define('firstName', [], () => { return '饥人谷' }) define('lastName', [], () => { return '前端' }) define('sayHello', ['firstName', 'lastName'], (v1, v2) => { return function() { console.log(`Hello ${v1} ${v2}`) } }) require(['sayHello'], (fn) => { fn() })
let modules = {} function define(name, deps, callback) { depFns = deps.map(depName => modules[depName]) modules[name] = callback.apply(null, depFns) } function require(deps, callback) { depFns = deps.map(depName => modules[depName]) callback.apply(null, depFns) }
实现原理为:当定义一个模块时,先从依赖的模块名列表得到这些依赖的模块的函数实现构成的数组,给modules添加一个属性,其值为模块实现执行后的结果,其参数为依赖的模块实现函数数组。
(global => { let modules = {} function require(deps, callback) { if(!Array.isArray(deps)) { callback = deps deps = [] } depFns = deps.map(depName => modules[depName]) return callback.apply(null, depFns) } function define(name, deps, callback) { modules[name] = require(deps, callback) } global.define = define global.require = require })(window)
以上代码为模块加载器的简易实现,未涉及模块的网络下载以及循环引用的处理。
饥人谷一直致力于培养有灵魂的编程者,打造专业有爱的国内前端技术圈子。如造梦师一般帮助近千名不甘寂寞的追梦人把编程梦变为现实,他们以饥人谷为起点,足迹遍布包括facebook、阿里巴巴、百度、网易、京东、今日头条、大众美团、饿了么、ofo在内的国内外大小企业。 了解培训课程:加微信 xiedaimala03,官网:https://jirengu.com
本文作者:饥人谷若愚老师,如未经饥人谷官方同意,禁止转载