Node中的模块系统
使用Node编写应用程序主要就是在使用:
- EcmaScript语言
- 和浏览器一样,在Node中没有Bom和Dom
- 核心模块
- 文件操作的fs
- http服务操作的http
- url路径操作模块
- path路径处理模块
- os操作系统信息
- 第三方模块
- art-template
- 必须通过npm来下载才可以使用
- 自己写的模块
- 自己创建的文件
什么是模块化
- 文件作用域(模块是独立的,在不同的文件使用必须要重新引用)【在node中没有全局作用域,它是文件模块作用域】
- 通信规则
- 加载require
- 导出exports
CommonJS模块规范
在Node中的JavaScript还有一个重要的概念,模块系统。
- 模块作用域
- 使用require方法来加载模块
- 使用exports接口对象来导出模板中的成员加载
require
语法:
var 自定义变量名 = require('模块')
- 作用:
- 执行被加载模块中的代码
- 得到被加载模块中的
exports
导出接口对象
- 导出
exports
- Node中是模块作用域,默认文件中所有的成员只在当前模块有效
- 对于希望可以被其他模块访问到的成员,我们需要把这些公开的成员都挂载到
exports
接口对象中就可以了
导出多个成员(必须在对象中):
exports.a = 123; exports.b = function(){ console.log('bbb') }; exports.c = { foo:"bar" }; exports.d = 'hello';
- 导出单个成员(拿到的就是函数,字符串):
module.exports = 'hello';
- 以下情况会覆盖:
module.exports = 'hello'; //后者会覆盖前者 module.exports = function add(x,y) { return x+y; }
- 也可以通过以下方法来导出多个成员:
module.exports = { foo = 'hello', add:function(){ return x+y; } };
模块原理
exports和module.exports
的一个引用:
console.log(exports === module.exports); //true exports.foo = 'bar'; //等价于 module.exports.foo = 'bar';
当给exports重新赋值后,exports!= module.exports.
最终return的是module.exports,无论exports中的成员是什么都没用。
真正去使用的时候: 导出单个成员:exports.xxx = xxx; 导出多个成员:module.exports 或者 modeule.exports = {};
总结
// 引用服务 var http = require('http'); var fs = require('fs'); // 引用模板 var template = require('art-template'); // 创建服务 var server = http.createServer(); // 公共路径 var wwwDir = 'D:/app/www'; server.on('request', function (req, res) { var url = req.url; // 读取文件 fs.readFile('./template-apche.html', function (err, data) { if (err) { return res.end('404 Not Found'); } fs.readdir(wwwDir, function (err, files) { if (err) { return res.end('Can not find www Dir.') } // 使用模板引擎解析替换data中的模板字符串 // 去xmpTempleteList.html中编写模板语法 var htmlStr = template.render(data.toString(), { title: 'D:/app/www/ 的索引', files:files }); // 发送响应数据 res.end(htmlStr); }) }) }); server.listen(3000, function () { console.log('running....'); })
- jQuery中的each 和 原生JavaScript方法forEach的区别: 提供源头: 原生js是es5提供的(不兼容IE8), jQuery的each是jQuery第三方库提供的(如果要使用需要用2以下的版本也就是1.版本),它的each方法主要用来遍历jQuery实例对象(伪数组),同时也可以做低版本forEach的替代品,jQuery的实例对象不能使用forEach方法,如果想要使用必须转为数组([].slice.call(jQuery实例对象))才能使用
- 模块中导出多个成员和导出单个成员
- 301和302的区别: 301永久重定向,浏览器会记住 302临时重定向
- exports和module.exports的区别: 每个模块中都有一个module对象 module对象中有一个exports对象 我们可以把需要导出的成员都挂载到module.exports接口对象中 也就是
module.exports.xxx = xxx
的方式 但是每次写太多了就很麻烦,所以Node为了简化代码,就在每一个模块中都提供了一个成员叫exports
exports === module.exports
结果为true,所以完全可以exports.xxx = xxx
当一个模块需要导出单个成员的时候必须使用module.exports = xxx
的方式,=,使用exports = xxx
不管用,因为每个模块最终return的是module.exports,而exports只是module.exports的一个引用,所以exports
即使重新赋值,也不会影响module.exports
。 有一种赋值方式比较特殊:exports = module.exports
这个用来新建立引用关系的。