node模块机制
一、node模块化机制
1、commonJS模块规范包括三部分:模块引用、模块定义、模块标识。例如:
//math.js
exports.add = function(){
var sum = 0;
var args = arguments;
var len = args.length;
for(var i = 0;i < len;i++){
var num = args[i];
sum += num;
}
return sum;
}
var sum = 0;
var args = arguments;
var len = args.length;
for(var i = 0;i < len;i++){
var num = args[i];
sum += num;
}
return sum;
}
// increment.js
var math = require('./math');
exports.increment = function(val){
return math.add(val, 1);
};
var math = require('./math');
exports.increment = function(val){
return math.add(val, 1);
};
// app.js
var increment = require('./increment.js');
var increment = require('./increment.js');
console.log(increment.increment(5));
注意:模块标识符就是传递给require方法的参数,可以是./ 或者 ../ 开头的相对路径,也可以是 / 开头的绝对路径。
2、node实现了commonJS模块规范,同时引入了自己的特性。node引入模块需要经历一下三个步骤:
(1)、路径分析
(2)、文件定位。可以没有拓展名,如果没有拓展名,node将按照.js .node .json的顺序定位文件。
(3)、编译执行。
node中有两种模块:
(1)、核心模块(node自身提供)node进程启动时,会载入部分核心模块。
(2)、文件模块(用户编写)。第一次编译执行文件模块后,node以文件路径作为索引,将该模块对象缓存在Module._cache对象上。
3、commonJS包规范
目录结构:
package.json 包描述文件
bin 二进制可执行文件
lib JS代码目录
doc 文档
test 测试用例
4、基于commonJS包规范node有了npm npm的常用命令:npm install express可安装express框架
5、由于前端受网络环境的限制commonJS规范并不适用于前端。于是有了AMD。实现了AMD规范的JS库:require.js,curl.js
require.js 核心代码:
(function () {
require.load = function (context, moduleName, url) {
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.send();
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
eval(xhr.responseText);
//Support anonymous modules.
context.completeLoad(moduleName);
}
};
};
}());
require.load = function (context, moduleName, url) {
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.send();
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
eval(xhr.responseText);
//Support anonymous modules.
context.completeLoad(moduleName);
}
};
};
}());
curl.js核心代码:
loadScript: function (def, success, failure) {
// script processing rules learned from RequireJS
// TODO: pass a validate function into loadScript to check if a success really is a success
// insert script
var el = doc.createElement('script');
// initial script processing
function process (ev) {
ev = ev || global.event;
// detect when it's done loading
// ev.type == 'load' is for all browsers except IE6-9
// IE6-9 need to use onreadystatechange and look for
// el.readyState in {loaded, complete} (yes, we need both)
if (ev.type == 'load' || readyStates[el.readyState]) {
delete activeScripts[def.id];
// release event listeners
el.onload = el.onreadystatechange = el.onerror = ''; // ie cries if we use undefined
success();
}
}
function fail (e) {
// some browsers send an event, others send a string,
// but none of them send anything useful, so just say we failed:
failure(new Error('Syntax or http error: ' + def.url));
}
// set type first since setting other properties could
// prevent us from setting this later
// actually, we don't even need to set this at all
//el.type = 'text/javascript';
// using dom0 event handlers instead of wordy w3c/ms
el.onload = el.onreadystatechange = process;
el.onerror = fail;
// js! plugin uses alternate mimetypes
el.type = def.mimetype || 'text/javascript';
// TODO: support other charsets?
el.charset = 'utf-8';
el.async = !def.order;
el.src = def.url;
// loading will start when the script is inserted into the dom.
// IE will load the script sync if it's in the cache, so
// indicate the current resource definition if this happens.
activeScripts[def.id] = el;
head.insertBefore(el, insertBeforeEl);
// the js! plugin uses this
return el;
// script processing rules learned from RequireJS
// TODO: pass a validate function into loadScript to check if a success really is a success
// insert script
var el = doc.createElement('script');
// initial script processing
function process (ev) {
ev = ev || global.event;
// detect when it's done loading
// ev.type == 'load' is for all browsers except IE6-9
// IE6-9 need to use onreadystatechange and look for
// el.readyState in {loaded, complete} (yes, we need both)
if (ev.type == 'load' || readyStates[el.readyState]) {
delete activeScripts[def.id];
// release event listeners
el.onload = el.onreadystatechange = el.onerror = ''; // ie cries if we use undefined
success();
}
}
function fail (e) {
// some browsers send an event, others send a string,
// but none of them send anything useful, so just say we failed:
failure(new Error('Syntax or http error: ' + def.url));
}
// set type first since setting other properties could
// prevent us from setting this later
// actually, we don't even need to set this at all
//el.type = 'text/javascript';
// using dom0 event handlers instead of wordy w3c/ms
el.onload = el.onreadystatechange = process;
el.onerror = fail;
// js! plugin uses alternate mimetypes
el.type = def.mimetype || 'text/javascript';
// TODO: support other charsets?
el.charset = 'utf-8';
el.async = !def.order;
el.src = def.url;
// loading will start when the script is inserted into the dom.
// IE will load the script sync if it's in the cache, so
// indicate the current resource definition if this happens.
activeScripts[def.id] = el;
head.insertBefore(el, insertBeforeEl);
// the js! plugin uses this
return el;
}
二、前端脚本按需加载方式:
1、创建XMLHttpRequest对象获取JS文件,用eval方法执行完毕后,执行回调。(require.js) 存在跨域问题。
2、动态创建<script>标签,同时绑定onload onreadystatechange方法执行回调。(curl.js)
posted on 2014-07-27 20:49 Hellohuman 阅读(178) 评论(0) 编辑 收藏 举报