js模块

原创
2017/06/20 13:56
阅读数 47

#JS模块规范# (CommonJS,AMD,CMD,ES6模块)

commonjs

CommonJS定义的模块分为:

  • 模块引用 require
  • 模块定义 exports
  • 模块标识 module
	//sum.js
	exports.sum = function(){...做加操作..};
	 
	//calculate.js
	var math = require('sum');
	exports.add = function(n){
	    return math.sum(val,n);
	};
	

require()用来引入外部模块;exports对象用于导出当前模块的方法或变量,唯一的导出口;module对象就代表模块本身。

建议阅读 http://www.cnblogs.com/skylar/p/4065455.html

###AMD###

CommonJS是主要为了JS在后端的表现制定的,他是不适合前端的,为什么这么说呢?这需要分析一下浏览器端的js和服务器端js都主要做了哪些事,有什么不同了:

服务器端JS

  • 相同的代码需要多次执行
  • CPU和内存资源是瓶颈
  • 加载时从磁盘中加载

浏览器端JS

  • 代码需要从一个服务器端分发到多个客户端执行
  • 带宽是瓶颈
  • 加载时需要通过网络加载

于是乎,AMD(异步模块定义)出现了,它就主要为前端JS的表现制定规范。 AMD就只有一个接口:define(id?,dependencies?,factory);

它要在声明模块的时候制定所有的依赖(dep),并且还要当做形参传到factory中,像这样:

define(['dep1','dep2'],function(dep1,dep2){...});
  • RequireJS是一个工具库,主要用于客户端的模块管理。它可以让客户端的代码分成一个个模块,实现异步或动态加载,从而提高代码的性能和可维护性。它的模块管理遵守AMD规范(Asynchronous Module Definition)。
  • RequireJS对模块的态度是预执行。由于 RequireJS 是执行的 AMD 规范, 因此所有的依赖模块都是先执行.RequireJS是预先把依赖的模块执行,相当于是require被提前了

RequireJS执行流程

  1. require函数检查依赖的模块,根据配置文件,获取js文件的实际路径
  2. 根据js文件实际路径,在dom中插入script节点,并绑定onload事件来获取该模块加载完成的通知。
  3. 依赖script全部加载完成后,调用回调函数
	var head = document.getElementsByTagName('head')[0];
	var node = document.createElement('script');
	node.type = 'text/javascript';
	node.async = 'true';
	node.src = 'b.js';
	node.onload = function () {
	    test1();
	};
	head.appendChild(node);

####require例子###

<!DOCTYPE html>
<html>
<head>
    <title>requirejs</title>
    <script src="require.js"></script>
</head>
<body>
    <script type="text/javascript">
    require(["main"])
    </script>
</body>
</html>

main.js

define(["a","b"],function(a,b) {
   console.log("进入")
	a.hello();
	b.hello();
})

a.js

define(function() {
	console.log("这里是a模块")
	return {
		hello:function(){
			console.log("a模块的hello方法")
		}
	}
})

b.js

define(function(require, exports, module) {
	console.log("这里是b模块")
	return {
		hello:function(){
			console.log("b模块的hello方法")
		}
	}
})

###CMD###

sea.js就实现了CMD规范,官方网址是:http://seajs.org/docs/#docs

使用方式和AMD类似

define(function(require,exports,module){...});

CMD 就是 SeaJS 这个模块加载器在推广的过程中定义的一个模块规范

SeaJS对模块的态度是懒执行, SeaJS只会在真正需要使用(依赖)模块时才执行该模块。

SeaJS执行流程

  1. 通过回调函数的Function.toString函数,使用正则表达式来捕捉内部的require字段,找到require('jquery')内部依赖的模块jquery
  2. 根据配置文件,找到jquery的js文件的实际路径
  3. 在dom中插入script标签,载入模块指定的js,绑定加载完成的事件,使得加载完成后将js文件绑定到require模块指定的id(这里就是jquery这个字符串)上
  4. 回调函数内部依赖的js全部加载(暂不调用)完后,调用回调函数
  5. 当回调函数调用require('jquery'),即执行绑定在'jquery'这个id上的js文件,即刻执行,并将返回值传给var b

相关文档

https://github.com/seajs/seajs/issues/277

https://www.zhihu.com/question/20342350

####sea.js例子###

index.html

<!DOCTYPE html>
<html>
<head>
	<title></title>
	<script src="sea.js"></script>
</head>
<body>
	<script type="text/javascript">
		seajs.use("./main")
	</script>
</body>
</html>

main.js

define(function(require,exports,module){
	console.log("进入")
	var a = require("a");
	a.hello();
	var b = require("b");
	b.hello();
})

a.js

define(function(require,exports,module){
	console.log("这里是a模块")
	exports.hello = function(){
		console.log("a模块的hello方法")
	}
})

b.js

define(function(require,exports,module){
	console.log("这里是b模块")
	exports.hello = function(){
		console.log("b模块的hello方法")
	}
})

##ES6## modules是ES6引入的最重要一个特性。 所以以后再写模块,直接按照ES6的modules语法来写,然后使用打包工具打个包就行了。

modules规范分两部分,一部分是如何导出,一部分是如何导入。

导出 可以直接在任何变量或者函数前面加上一个 export 关键字,就可以将它导出。 这种写法非常简洁,和平时几乎没有区别,唯一的区别就是在需要导出的地方加上一个 export 关键字。

export const sqrt = Math.sqrt;
export function square(x) {
    return x * x;
}
export function diag(x, y) {
    return sqrt(square(x) + square(y));
}

导入

import { square, diag } from 'lib';
console.log(square(11)); // 121
console.log(diag(4, 3));

默认导出 一个包里只能有一个默认导出

export default function(){
	.....
}

导入
import add from 'lib';
console.log(add)

相关资料

http://www.cnblogs.com/zjzhome/p/4848592.html

###UMD###

  • umd是AMD和CommonJS的糅合
  • AMD 浏览器第一的原则发展 异步加载模块。
  • CommonJS 模块以服务器第一原则发展,选择同步加载,它的模块无需包装(unwrapped modules)。
  • 这迫使人们又想出另一个更通用的模式UMD (Universal Module Definition)。希望解决跨平台的解决方案。
  • UMD先判断是否支持Node.js的模块(exports)是否存在,存在则使用Node.js模块模式。
  • 在判断是否支持AMD(define是否存在),存在则使用AMD方式加载模块。
	(function (window, factory) {
	    if (typeof exports === 'object') {
	        module.exports = factory();
	    } else if (typeof define === 'function' && define.amd) {
	        define(factory);
	    } else {
	        window.eventUtil = factory();
	    }
	})(this, function () {
	    //module ...
	});
展开阅读全文
加载中
点击引领话题📣 发布并加入讨论🔥
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部