您的当前位置:首页正文

javascript 构建模块化开发过程解析

2020-11-27 来源:帮我找美食网

在使用 sea.js 、require.js 、 angular 的时候。

我们使用到 define 、 module(require) 的方式,定义模块,和依赖模块

下面给出 define 和 module 的简单实现。 其本质,就是往一个对象上面添加方法

var F = {};
F.define = function(str,fn){
 var parts = str.split(".");
 var parent = this; // parent 当前模块的父模块
 var i = len = 0;
 //如果第一个模块是模块单体对象,则移除
 if(parts[0] == "F"){
 parts = parts.slice(1);
 }
 
 //屏蔽对 define module 模块方法重写
 if(parts[0] == "define" || parts[0] == "module"){
 return ;
 } 
 
 for(len = parts.length; i < len-1; i++){
 //如果父模块中不存在当前模块
 if(typeof parent[parts[i]] === 'undefined'){
 //声明当前模块
 parent[parts[i]] = {};
 }
 //缓存下一层父模块
 parent = parent[parts[i]];
 }
 
 if(fn && parts[i]){
 //如果给定模块方法,则绑定该模块的方法,
 parent[parts[i]] = fn();
 }
 return this;
}
 
F.module = function(){
 var args = [].slice.call(arguments);//复制参数
 var fn = args.pop(); //获取回调
 
 var parts = args[0] && args[0] instanceof Array ? args[0] : args;
 
 //模块的依赖
 var modules = [];
 
 //模块的路由
 var modIDs = "";
 
 //依赖模块的索引
 var i = 0;
 
 var len = parts.length; // 依赖模块的长度
 
 var parent,j,jlen; //父级模块,模块路由层级索引,模块路由层级长度
 
 while(i < len){
 if(typeof parts[i] == "string"){
 parent = this;
 //解析路由,并且屏蔽掉 F
 modIDs = parts[i].replace(/^F\./,"").split(".");
 //遍历模块层级
 for( j = 0,jlen = modIDs.length; j < jlen; j++){
 //迭代 父模块
 parent = parent[modIDs[j]] || false;
 }
 modules.push(parent); //将模块添加到依赖列表
 }else{
 //直接将模块添加到依赖列表
 modules.push(parts[i]);
 }
 //取下一个模块
 i++;
 }
 
 
 //执行回调,将依赖的模块注入
 fn.apply(null,modules); 
} 
//定义 string 模块
F.define("string",function(){
 return {
 trim(str){
 return str.replace(/^s+|\s+$/g,"");
 }
 }
});
//定义 string 模块,的子模块 sub
F.define("string.sub",function(){
 return {
 low(str){
 return str.toLowerCase();
 }
 }
});
console.log(F);
//使用模块
F.module(["string","string.sub",document],function(str,strSub,doc){
 console.log(str,strSub,doc)
});

当然了,这里使用的,F 对象,实际应用中,应该写在闭包里面。不能让外界直接访问,于是有如下代码。

var Sea = (function(){
 var F = {};
 F.define = function(str,fn){
 var parts = str.split(".");
 var parent = this; // parent 当前模块的父模块
 var i = len = 0;
 
 //如果第一个模块是模块单体对象,则移除
 if(parts[0] == "F"){
 parts = parts.slice(1);
 }
 
 //屏蔽对 define module 模块方法重写
 if(parts[0] == "define" || parts[0] == "module"){
 return ;
 } 
 
 for(len = parts.length; i < len-1; i++){
 //如果父模块中不存在当前模块
 if(typeof parent[parts[i]] === 'undefined'){
 //声明当前模块
 parent[parts[i]] = {};
 }
 //缓存下一层父模块
 parent = parent[parts[i]];
 }
 
 if(fn && parts[i]){
 //如果给定模块方法,则绑定该模块的方法,
 parent[parts[i]] = fn();
 }
 return this;
 }
 
 F.module = function(){
 var args = [].slice.call(arguments);//复制参数
 var fn = args.pop(); //获取回调
 
 var parts = args[0] && args[0] instanceof Array ? args[0] : args;
 
 //模块的依赖
 var modules = [];
 
 //模块的路由
 var modIDs = "";
 
 //依赖模块的索引
 var i = 0;
 
 var len = parts.length; // 依赖模块的长度
 
 var parent,j,jlen; //父级模块,模块路由层级索引,模块路由层级长度
 
 while(i < len){
 if(typeof parts[i] == "string"){
 parent = this;
 //解析路由,并且屏蔽掉 F
 modIDs = parts[i].replace(/^F\./,"").split(".");
 //遍历模块层级
 for( j = 0,jlen = modIDs.length; j < jlen; j++){
 //迭代 父模块
 parent = parent[modIDs[j]] || false;
 }
 modules.push(parent); //将模块添加到依赖列表
 }else{
 //直接将模块添加到依赖列表
 modules.push(parts[i]);
 }
 //取下一个模块
 i++;
 }
 
 
 //执行回调,将依赖的模块注入
 fn.apply(null,modules);
 }
 return {
 define:function(){
 F.define.apply(F,arguments);
 },
 module:function(){
 F.module.apply(F,arguments);
 }
 }
})();
 
 
//定义 string 模块
Sea.define("string",function(){
 return {
 trim(str){
 return str.replace(/^s+|\s+$/g,"");
 }
 }
});
//定义 string 模块,的子模块 sub
Sea.define("string.sub",function(){
 return {
 low(str){
 return str.toLowerCase();
 }
 }
});
console.log(Sea);
//使用模块
Sea.module(["string","string.sub",document],function(str,strSub,doc){
 console.log(str,strSub,doc)
});
显示全文