- 核心模块
- fs 文件操作模块
- http 网络服务构建模块
- os 操作系统信息模块
- path 路径处理模块
- 用户自定义模块
- 通过require(‘路径’) 加载模块,例如:require(‘./b.js’),
相对路径 ./ 不能省略
- 可以省略文件后缀名,默认 .js
- 通过require(‘路径’) 加载模块,例如:require(‘./b.js’),
- 第三方模块
- art-template
- 必须通过 npm 来下载才可以使用
CommonJS 模块规范
- 模块作用域(模块是独立的,在不同的文件使用必须要重新引用)
- 使用 require 方法来加载模块
- 使用 exports 接口对象来导出模板中的成员
加载(require)
语法:
var 自定义变量名 = require('模块')
作用:
- 执行被加载模块中的代码
- 得到被加载模块中的
exports
导出接口对象
导出(exports)
- Node 中是模块作用域,默认文件中所有的成员只在当前模块有效
- 对于希望可以被其他模块访问到的成员,我们需要把这些公开的成员都挂载到
exports
接口对象中就可以了
导出多个成员(必须在对象中,exports 是一个对象):
exports.a = 123;
exports.b = 'hello';
exports.c = function(){
console.log('bbb')
};
exports.d = {
foo:"bar"
};
导出单个成员:
module.exports = 'hello';
// 后者会覆盖前者
module.exports = function add(x,y) {
return x+y;
}
也可以通过以下方法来导出多个成员:
module.exports = {
foo: 'hello',
add:function(){
return x+y;
}
};
原理
在 node 中,每个模块内部都有一个自已的 module 对象
在 module 对象中,有一个成员 exports(也是一个对象)
module = {
exports = {
}
}
即可以通过 module.exports 也可以通过 exports 导出,因为 exports
是 module.exports
的一个引用:
console.log(exports === module.exports); // true
exports.foo = 'bar';
//等价于
module.exports.foo = 'bar';
当给 exports 重新赋值后, exports != module.exports
可以通过 exports == module.exports
用来重新建立关系
最终 return 的是 module.exports,无论 exports 中的成员是什么都没用
真正去使用的时候:
- 导出单个成员:
module.exports = xxx;
- 导出多个成员:
module.exports.xxx 或者 module.exports = {};
require方法加载规则
- 优先从缓存加载(不会重复加载)
- 判断模块标识符
- 核心模块(模块名)
- 用户自定义模块(以路径形式加载)
- 第三方模块
- 先找到当前文件所处目录中的 node_modules 目录
- node_modules/art-template(模块名)
- node_modules/art-template/package.json 文件
- node_modules/art-template/package.json 文件中的 main 属性
- main 属性中就记录了 art-template 的入口模块
- 然后加载使用这个第三方包
- 如果 package.json 文件不存在或者 main 指定的入口模块也没有
- 则 node 会默认找该目录下的 Index.js
- 如果以上任何一个条件都不成立,则会进入上一级目录按以上规则查找
- 直到磁盘根目录,最后报错
核心模块使用
文件的读写
// 1.使用fs核心模块
var fs = require('fs');
// 2.读取文件
// 第一个参数就是要读取的文件路径
// 第二个参数是一个回调函数
// 成功
// data 数据
// err null
// 失败
// data undefined 没有数据
// err 错误对象
fs.readFile('./data/a.txt',function(err,data){
if(err){
console.log('文件读取失败');
}else{
// 文件中存储的都是二进制数据
// 通过toString()方法转换为我们能认识的字符
// 可以结合服务器通过读取文件来实现发送页面
console.log(data.toString());
}
})
// 3.将数据写入文件
// 第一个参数:文件路径
// 第二个参数:文件内容
// 第三个参数:回调函数
fs.writeFile('./data/a.txt','写入文件的内容',function(err){
if(err){
console.log('写入失败');
}
else{
console.log('写入成功');
}
})
HTTP 服务
- 提供服务:对数据服务
- 发送请求
- 接收请求
- 处理请求
- 反馈(发送响应)
- 当客户端请求过来,就会自动触发服务器的 request 请求事件,然后执行第二个参数:回调处理函数
// 1.加载http核心模块
var http = require('http');
var fs = require('fs');
// 2.使用http.createServer()创建一个web服务器
var server = http.createServer();
// 读取文件时的根目录
var wwwDir = 'D:/app/www'
// 3.触发服务器的request请求事件
// request 请求事件处理函数,需要接收两个参数:
// request 请求对象
// 请求对象可以用来获取客户端的一些请求信息,例如请求地址
// response 响应对象
// 响应对象可以用来给客户端发送响应消息
server.on('request', function (req, res) {
// 获取当前 url(端口号后面的路径)
var url = req.url
// 默认为 /index.html
var filePath = '/index.html'
// 如果不是默认 url,则获取当前用户输入的 url
if (url !== '/') {
filePath = url
}
// 读取文件
fs.readFile(wwwDir + filePath, function (err, data) {
if (err) {
// 响应内容只能是字符串或二进制数据
// 告诉浏览器发送的是什么类型的内容
// 图片不需要指定编码
response.setHeader('Content-Type', 'text/html; charset=utf-8')
return res.end('404 NOT Found')
}
res.end(data)
})
})
// 4.绑定端口号,启动服务
server.listen(3000, function () {
console.log('running')
})
path 路径操作模块
参考文档: https://nodejs.org/dist/latest-v14.x/docs/api/path.html
- path.basename:获取路径的文件名,默认包含扩展名
- 第二个参数传一个文件扩展名获取到的文件名就不包含扩展名
- path.dirname:获取路径中的目录部分
- path.extname:获取一个路径中的扩展名部分
- path.isAbsolute:判断一个路径是否为绝对路径
- path.parse:把路径转换为对象
- root:根路径
- dir:目录
- base:包含扩展名的文件名
- ext:扩展名
- name:不包含扩展名的文件名
- path.join:拼接路径
Node中的其它成员
在每个模块中,除了 require
, exports
等模块相关的 API 之外,还有两个特殊的成员:
__dirname
,可以用来 动态 获取当前文件模块所属目录的绝对路径(不包含文件名)__filename
,可以用来 动态 获取当前文件的绝对路径(包含文件名)__dirname
和filename
是不受执行 node 命令所属路径影响的
在文件操作中,使用相对路径是不可靠的,因为 node 中文件操作的路径被设计为相对于执行 node 命令所处的终端路径。
所以为了解决这个问题,只需要把相对路径变为绝对路径(绝对路径不受任何影响)就可以了。
就可以使用 __dirname
或者 __filename
来帮助我们解决这个问题
在拼接路径的过程中,为了避免手动拼接带来的一些低级错误,推荐使用 path.join()
来辅助拼接
模块中的路径标识和这里的路径没关系,不受 node 命令执行所处目录影响(相对于文件模块)
var fs = require('fs');
var path = require('path');
// console.log(__dirname + 'a.txt');
// path.join方法会将文件操作中的相对路径都统一的转为动态的绝对路径
fs.readFile(path.join(__dirname + '/a.txt'),'utf8',function(err,data){
if(err){
throw err
}
console.log(data);
});
补充:模块中的路径标识和这里的路径没关系,不受影响(就是相对于文件模块) 注意: 模块中的路径标识和文件操作中的相对路径标识不一致 模块中的路径标识就是相对于当前文件模块,不受node命令所处路径影响