终于来到最后一节了!
今天我们会把我们的种子模块完成,之后就可以开始扩展我们的框架了!是不是开始有些兴奋了呢?
先来回顾一下之前的内容:
我们搞定了命名空间、多库共存机制、模块扩展机制。
恩,跟我们开始定好的目标只差一小步了。现在我们来完成它
首先,先来用模块扩展机制为我们的命名空间添加方法,我们来简单的添加三个方法:多库共存、toString、toNumber
function(module, exports, require){ var _Cvm = window.Cvm , _$ = window.$; //在exports上面注册方法,来为命名空间扩展功能 exports.reName=function(deep){ //冲突处理机制 window.$ = _$; if(deep){ window.Cvm = _Cvm; }; return Cvm; }; exports.toString=function(val){ //toString return val.toString(); } exports.toNumber=function(str){ //toNumber var n = Number(str); return !isNaN(n) ? n : ""; }}
OK,那么我们定义好了一个模块,之后在工厂方法中将模块的方法返回给命名空间:
return (function(modules){// 用来注册和生产用户调用的模块和方法,参数为模块的集合 var moduleDepot = {} //缓存区 function require(moduleId){ if(moduleDepot[moduleId]) return moduleDepot[moduleId]; //直接调用缓存 var module = { exports:{}, moduleId:moduleId, loaded:false }; modules[moduleId].call(module.exports, module, module.exports, require); //获得模块 moduleDepot[moduleId] = module; //添加缓存 module.loaded=true; return module.exports //返回模块 }; return require(0); // 返回第0个模块
测试一下:
OK,到现在为止,基本上我们的种子模块就完成了!
只差一个问题:我们只把第0个模块注册到了命名空间上,但是我们不可能把所有功能都写在同一个模块里,因为这样的话就无法多人去编写框架了,而且对以后的维护升级都是一个巨大的屏障。
我们需要一个中介者来完善模块的扩展机制:
function(module, exports, require){ var _ = require(1); //将扩展功能的模块请求过来 var extend = _.extend; //获得扩展的方法 var p = {}; // 中介者 extend(p , require(2)); // 为中介者注册方法 module.exports = p; //最终返回中介者},//* 0-end *////////* 1-start *//function(module, exports){ // 扩展模块 exports.extend = function(to , from){ var keys = Object.keys(from); var i = keys.length; while(i--){ to[keys[i]] = from[keys[i]]; } return to; }},//* 1-end *////////* 2-start *//function(module, exports, require){ //多库共存模块 var _Cvm = window.Cvm , _$ = window.$; exports.reName=function(deep){ //多库共存 window.$ = _$; if(deep){ window.Cvm = _Cvm; }; return Cvm; };},//* 2-end *//
使用中介者p来扩展功能,然后返回这个中介者。此时这个中介者已经拥有所有扩展后的功能了,所以即使我们在种子模块里并没有请求多库共存的模块,但因为它已经被扩展给了中介者,所以最后我们还是可以得到这个模块的所有功能。
这样,我们的种子模块就彻底宣告完成了。你可以在此基础上,任意的扩展你的命名空间,也可以很方便的完成模块之间的依赖引用。
完整代码:
!function(global , target){ if(typeof global !== 'undefined'){ global.Cvm = global.$ = target(); }else{ throw new Error("Cvm requires a window with a document") }}(typeof window !== 'undefined'? window : this , function(){ //工厂是一个函数 return (function(modules){// 用来注册和生产用户调用的模块和方法,参数为模块的集合 var moduleDepot = {} //缓存区 function require(moduleId){ if(moduleDepot[moduleId]) return moduleDepot[moduleId].exports; //直接调用缓存 var module = { exports:{}, moduleId:moduleId, loaded:false }; modules[moduleId].call(module.exports, module, module.exports, require); //获得模块 moduleDepot[moduleId] = module; //添加缓存 module.loaded=true; return module.exports //返回模块 }; return require(0);})([//* 0-start *//function(module, exports, require){ var _ = require(1); var extend = _.extend; var p = {}; // 中介者 extend(p , require(2)); module.exports = p;},//* 0-end *////////* 1-start *//function(module, exports){ exports.extend = function(to , from){ var keys = Object.keys(from); var i = keys.length; while(i--){ to[keys[i]] = from[keys[i]]; } return to; }},//* 1-end *////////* 2-start *//function(module, exports, require){ var _Cvm = window.Cvm , _$ = window.$; exports.reName=function(deep){ //多库共存 window.$ = _$; if(deep){ window.Cvm = _Cvm; }; return Cvm; };},//* 2-end *//])})
最后说两句:
模块扩展机制的好处是:方便多人协作完成一个框架的编写。
因为编写一个大型、功能完备的框架毕竟不是一个容易的事情,需要很多人很长时间去完成的,所以模块扩展机制的好处在此就有很大的发挥空间。
而模块的编写就像拼装玩具,把各个独立的功能拼接在一起,就变成了一个完整而强大的功能。
实际上,编写框架就是这样一个过程:在工作中不断积累业务需求与解决方法,并且不停的抽象你的代码。当你的代码累积到一定的数量级后,自然而然的就会开始编写框架。
至于之后的功能,我们以后再来展开!