简化js模块化开发

原文链接 http://leechan.me/?p=1241

如果你现在正在想要构建一种利于代码复用和后续维护开发的前端JS架构,那么也许你会选择模块化开发。然后在你的项目中引入requireJS或者seaJS这类模块加载器。这正是目前许多前端项目的布局。将公用的组件或功能模块分立成目标明确的小模块,按需加载。随着这种开发方式的流行,有好事者也在兴建各类规范,如commonJS或者AMD(requireJS)或者CMD(seaJS)等规范。然而今天我想推荐的一种布局方式同样也遵循commonJS规范,但是不需要使用模块加载器,更简单灵活,同时也能支持后续开发的良好进行。

其实我只是简化了requireJS这类模块加载器,而换成了十几行代码来替换。少了异步模块加载过程,少了模块依赖,而这正是这类加载器的复杂之处。然而却保留了最重要的模块开发良好的代码组织定义。少了这些还是模块开发吗?我们先来看看这十几行起到决定性作用的核心代码吧。

// 模块定义与引用核心代码
;(function(global){
	var mapping = {}, cache = [];
	global.define = function(id, func){
		mapping[id] = func;
	}
	global.require = function(id){
		if(cache[id]){
			return cache[id];
		}
		return cache[id] = mapping[id]({});
	}
})(this);

  

以上就是所有核心代码,在你的项目中写入以上代码,那么模块化开发就完成了一大半。接下这说说如何基于以上代码来定义模块和使用模块。

你可以像这样来定义一个功能模块:

define('src/utils.js',function(exports){
	var version = '1.0';
	exports.getVersion = function(){
		return version;
	}
	return exports;
})

  

你如果使用过模块加载器就应该知道exports是用来向外暴露接口的,这里作用相同。

在一个模块中引入另一个模块:

define('src/main.js', function(exports){
	var utils = require("src/utils.js");
	var version = utils.getVersion();
	console.log(version);
	return exports;
})

  

以上就已经基本搭建好了模块化开发环境,你就可以按照模块化开发的方式去开发了,将每一个模块保持为单独的js,如以上utils.js,main.js等。说到这里问题就来了,既然少了requireJS等模块加载器的加载行为,那我们怎么引入模块呀。这里我采用的方法也是将其简化。我利用ant结合脚本来对模块进行压缩合并。这样就可以满足当你改动某个模块JS代码,后台就自动将最新的代码合并。所以在你的页面中只会引入一个或少量的包含大部分公用模块的js文件。如我的项目中有个common.js,那么每当我修改utils.js则common.js也会进行最新的修改合并。所以在你的页面中只需要引入common.js就可以了。所以这里就少了模块异步加载的过程,一切都简化了。

这是有人可能会提出三个问题:
1.不需要的模块也加载进来了。
2.用户访问时不得不经常获取最新模块合并成的JS文件(如common.js),因为它经常改变。
3.模块过多会导致合并文件过大。

第一个问题,不需要的模块只是进行了定义,不会执行。对性能的影响可以忽略不计。第二个问题因为模块有时经常改变,就会导致整个模块合并成的JS文件更新,导致浏览器缓存不能使用。如果你的网站不是每天一次更新上线,那么这个问题就这样吧。第三个问题就是一般经过压缩后容量不会是太大问题,除非你做的是大型网站,还有就是正对不同功能的模块进行合并划分。比如UI组件模块可以进行单独合并,功能模块可以单独合并。

以上就是我推崇的针对中小型网站的开发模式。

posted @ 2016-02-26 11:25  倾其一生  阅读(1007)  评论(0)    收藏  举报