手写梳理 AMD 模块管理原理

161 阅读1分钟

首先我们可以用一个自执行函数来启动这个模块管理器:

const ModuleController = (()=>{})();

既然要进行模块管理,那么肯定需要:

  • 一个容器:用于存储管理的模块
  • 一个方法:用于定义模块
const ModuleController = (()=>{
    const moduleList = {}
    const defind = () =>{}
    
    return {
        defind
    }
})();

继续分析,定义一个模块的时候,我们需要知道:

  • 模块名
  • 是否依赖其他模块,如果依赖了,是哪些
  • 模块功能

那么我们这里用:

  • 字符串存储模块名
  • 数组存储依赖
  • 函数存储功能
const ModuleController = (()=>{
    const moduleList = {}
    const defind = (name, modules, action) =>{}
    
    return {
        defind
    }
})();

首先我们需要将定义的模块压入前面定义的用于存储模块的容器里:

const ModuleController = (()=>{
    const moduleList = {}
    const defind = (name, modules, action) =>{
        // 并不需要改变 this 指向
        moduleList[name] = action.apply(null, modules);
    }
    
    return {
        defind
    }
})();

到这里就完成了模块的添加了,可以通过如下代码定义模块:

ModuleController.define('arrCtl',[],() =>{
    // 不依赖任何其他模块
    return {
        max(arr){
            return arr.sort((a,b) => b-a)[0]
        }
    }
})

接下来我们需要实现模块的引入,将模块从 moduleList 中取出放到 modules 中即可:

const ModuleController = (()=>{
    const moduleList = {}
    const defind = (name, modules, action) =>{
        modules.map((m,i) =>{
            modules[i] = moduleList[m]
        })
        moduleList[name] = action.apply(null, modules);
    }
    
    return {
        defind
    }
})();

到这里就可以进行模块引入了,比如引入上面定义的数组操作模块:

ModuleController.define('myModule',['arrCtl'],() =>{
    const myArr = [0,1,2,3,56,12,5,123]
    const maxNum = arrCtl.max(myArr)
})