JavaScript 模块化编程

JavaScript 模块化编程

exapmle:

var module1 = ( function($, YAHOO){
	
	//...


})(jQuery, YAHOO);

模块规范: CommonJS 和 AMD

对于浏览器端的模块,只能采用“异步加载”。这就是AMD规范诞生的背景。

AMD: Asynchronous Module Definition

它采用异步方式加载模块,模块的加载不影响它后面语句的执行。所有依赖这个模块的语句,都定义在一个回调函数中,等到模块加载完成之后,这个回调函数才会执行。

写法如下:

require([module], callback);

第一个参数[module], 是一个数组,里面的成员是要加载的模块。

例如:

require(['math'], function(){
	math.add(2, 3);
})

一个流行的库 require.js

解决两个问题:

  • 实现js文件的异步加载,避免网页失去响应
  • 管理模块之间的依赖性,便于代码的编写和维护

引入库文件:

使其异步加载,可以加入属性:async="true" (IE支持 defer)

引入require之后,加入我们自己的代码:

假定我们的文件是main.js,在js目录下。

data-main属性的作用是,指定网页程序的主模块。

如何写主模块main.js:

require(['moduleA', 'moduleB', 'moduleC'], function(moduleA, moduleB, moduleC){
	
	// do something

});

一个实际的例子:

require(['jquery', 'underscore', 'backbone'], function($, _, Backbone){
	
	//some code here

});

模块的加载:

默认情况下,require假定所要加载的模块与main.js在同一目录下。

使用require.config()方法,我们可以自定义模块的加载行为。require.config()就写在main.js的头部。参数是一个对象,对象的path属性指定各个模块的加载路径。

// 相同路径,指定模块的文件名
require.config({
	
	paths: {
		'jquery': 'jquery.min',
		'underscore': 'underscore.min',
		'backbone': 'backbone.min'
	}
});

// 不同路径,指定路径及文件名
require.config({
	
	paths: {
		'jquery': 'lib/jquery.min',
		...
	}
});

// 或者指定基目录
require.config({
	
	baseUrl: 'js/lib',

	paths: {
		'jquery': 'jquery.min',
		...
	}
});

// 也可以指定url
require.config({
	
	paths: {
		'jquery': 'https://ajax.../jquery.min',
		...
	}
});

模块的写法

如果一个模块不依赖其他模块,则直接定义一个模块:

// math.js
define(function() {
	var add = function(x, y) {

		return x + y;

	};

	return {
		add: add
	}

})

加载方法:

require(['math'], function(math) {
	// ...
})

如果这个模块还以来其他模块,则define() 函数的第一个参数必须是一个数组,指明该模块的依赖性:

define(['myLib', function(mylib){
	function foo(){

		myLib.doSomething();

	}

	return {
		foo: foo
	};
}]);

加载非规范的模块:

比如underscore和backbone这两个库,都没有采用AMD规范编写。如果要加载他们的话,必须先定义他们的特征:

require.config({
	
	shim: {
		'underscore': {
			exports: '_'
		},

		'backbone': {
			deps: ['underscore', 'jquery'],
			exports: 'Backbone'
		}
	}
});

shim属性专门用来配置不兼容的模块,每个模块要定义:
(1) exports值(输出的变量名),表明这个模块外部调用时的名称
(2) deps数组,表明该模块的依赖

比如:

shim: {
	'jquery': {
		deps: ['jquery'],
		exports: 'jQuery.fn.scroll'
	}
}

require.js 插件:

domready插件,可以让回调函数在DOM结构加载完成后再执行。

require(['domready!'], function(doc){
	// called once the DOM is ready
});

text和image插件,允许require加载文本和图片文件:

define([
	'text!review.text',
	'image!cat.jpg'
],

function(review, cat) {
	console.log(review);
	document.body.appendChild(cat);
}
);
posted @ 2017-06-15 21:10  t1ree  阅读(139)  评论(0编辑  收藏  举报