Node.js-COMMONJS 规范

ECMAScript 标准的缺陷

没有模块系统
标准库较少
没有标准接口
缺乏管理系统

模块化

如果程序设计的规模达到了一定程度,则必须对其进行模块化 。

模块化 可以有多种形式,但至少 应该 提供能够将代码分割为多个源文件的机制 。

CommonJS 的模块 功能可以帮我们解决该问题。

CommonJS 规范

CommonJS 规范的提出,主要是为了弥补当
前 JavaScript 没有 模块化 标准 的 缺陷 。
CommonJS 规范为 JS 指定了一个美好的愿景,
希望 JS 能够在任何地方运行 。
CommonJS 对模块的定义十分简单:
– 模块引用
– 模块定义
– 模块标识

模块 引用

在规范中,定义了 require() 方法,这个方
法接手模块标识,以此将一个模块引入到
当前运行环境中。
模块引用的示例代码:
– var math = require('math');

模块定义

在运行环境中,提供了 exports 对象用于导
出当前模块的方法或者变量,并且它是唯
一的导出的出口。
在模块中还存在一个 module 对象,它代表
模块自身,而 exports 是 module 的属性。
在 Node 中一个文件就是一个模块。

模块定义

exports . xxx = function () {};
module . exports = {} ;

模块标识

模块 标识 其实就是模块的名字,也就是传
递给 require() 方法的参数,它必须是符合
驼峰命名法的字符串,或者是以 .、 .. 开头的
相对路径、或者绝对路径。
模块的定义十分简单,接口也十分简洁。
每个模块具有独立的空间,它们互不干扰,
在引用时也显得干净利落。

Node 的模块实现

Node 中虽然使用的是 CommonJS 规范,但是
其自身也对规范做了一些取舍。
在 Node 中引入模块,需要经历如下 3 个步骤:
– 路径分析
– 文件定位
– 编译执行
在 Node 中,模块分为 三 类:一类是底层由
C++ 编写的 内建模块 ,一类是 Node 提供的 核
心模块 ;还有一类是用户编写的模块,称为 文
件模块 。前端培训

包 package

CommonJS 的包规范允许我们将一组相关
的模块组合到一起,形成一组完整的工具。
CommonJS 的包规范由 包结构 和 包描述文
件 两个部分组成。
包结构
– 用于组织包中的各种文件
包描述文件
– 描述包的相关信息,以供外部读取分析

包结构

包实际上就是一个压缩文件,解压以后还
原为目录。符合规范的目录,应该包含如
下文件:
– package.json 描述文件
– bin 可执行二进制文件
– lib js 代码
– doc 文档
– test 单元测试

包描述文件

包描述文件用于表达非代码相关的信息,
它是一个 JSON 格式的文件 – package.json ,
位于包的根目录下,是包的重要组成部分。
package.json 中的字段
– name 、 description 、 version 、 keywords 、
maintainers 、 contributors 、 bugs 、
licenses 、 repositories 、 dependencies 、
homepage 、 os 、 cpu 、 engine 、 builtin 、
directories 、 implements 、 scripts 、 author 、
bin 、 main 、 devDependencies 。

NPM(Node Package Manager)

CommonJS 包规范是理论, NPM 是其中一
种实践。
对于 Node 而言, NPM 帮助其完成了第三
方模块的发布、安装和依赖等。借助 NPM ,
Node 与第三方模块之间形成了很好的一个
生态系统。

NPM 命令

npm – v– 查看版本
npm– 帮助说明
npm search 包名– 搜索模块包
npm install 包名– 在当前目录安装 包
npm install 包名 – g– 全局模式安装 包

npm remove 包名– 删除一个 模块

npm install 文件路径– 从本地安装

npm install 包名 – registry= 地址– 从镜像源安装

npm config set registry 地址– 设置镜像源

Buffer( 缓冲区 )

从结构上看 Buffer 非常像一个数组,它的元
素为 16 进制的两位数。
实际上一个元素就表示内存中的一个字节。
实际上 Buffer 中的内存不是通过 JavaScript
分配的,而是在底层通过 C++ 申请的。
也就是我们可以直接通过 Buffer 来创建内存
中的空间。

Buffer 的操作

使用 Buffer 保存字符串
创建指定大小的 Buffer 对象
let str = " 你好 atguigu";
let buf = Buffer.from(str , "utf -8") ;
let buf3 = Buffer.alloc( 1024*8 )

Buffer 的转换

Buffer 与字符串间的转换
– 支持的编码 :
ASCII 、 UTF - 8 、 UTF - 16LE/UCS - 2 、 Base64 、
Binary 、 Hex
– 字符串转 Buffer
Buffer.from(str , [encoding]);
– Buffer 转字符串
buf.toString([encoding] , [start] , [end]);

写入操作

向缓冲区中写入字符串
– buf.write(string [, offset[, length]][, encoding ])
替换指定索引位置的数据
– buf[index ]
将指定值填入到缓冲区的指定位置
– buf.fill(value [, offset[, end]][, encoding ])

读取 操作

将缓冲区中的内容,转换为一个字符串返回
– buf.toString ([encoding[, start[, end ]]])
读取缓冲区指定索引的内容
– buf[index ]

其他操作

复制缓冲区
– buf.copy(target[, targetStart[, sourceStart[, sourceEnd]]])
对缓冲区切片
– buf.slice([start[, end ]])
拼接缓冲区
– Buffer.concat(list[, totalLength])

fs (文件系统)

在 Node 中,与文件系统的交互是非常重要
的,服务器的本质就将本地的文件发送给
远程的客户端
Node 通过 fs 模块来和文件系统进行交互
该模块提供了一些标准文件访问 API 来打开、
读取、写入文件,以及与其交互。
要使用 fs 模块,首先需要对其进行加载
– const fs = require("fs");

同步和异步调用

fs 模块中所有的操作都有两种形式可供选择
同步 和 异步 。
同步文件系统会 阻塞 程序的执行,也就是
除非操作完毕,否则不会向下执行代码。
异步文件系统 不会阻塞 程序的执行,而是
在操作完成时,通过回调函数将结果返回。

打开和关闭文件

打开文件
– fs.open(path, flags[, mode], callback )
– fs.openSync(path, flags[, mode])
关闭文件
– fs.close(fd, callback )
– fs.closeSync(fd)

打开状态

写入文件

fs 中提供了四种不同的方式将数据写入文件
– 简单文件写入
– 同步文件写入
– 异步文件写入
– 流式文件写入

简单文件 写入

fs.writeFile(file , data[, options], callback )
fs.writeFileSync(file, data[, options ])
参数:
– file 文件路径
– data 被写入的内容,可以是 String 或 Buffer
– options 对象,包含属性( encoding 、 mode 、
flag )
– callback 回调函数

同步文件写入

fs.writeSync(fd, buffer, offset, length[, position ])
fs.writeSync(fd, data[, position[, encoding ]])
要完成同步写入文件,先需要通过 openSync() 打开文件来获取
一个文件描述符,然后在通过 writeSync() 写入文件。
参数
– fd 文件描述符,通过 openSync() 获取
– data 要写入的数据( String 或 Buffer )
– offset buffer 写入的偏移量
– length 写入的长度
– position 写入的起始位置
– encoding 写入编码

异步文件写入

fs.write(fd, buffer, offset, length[, position], callback )
fs.write(fd, data[, position[, encoding]], callback )
要使用异步写入文件,先需要通过 open() 打开文件,然后在回
调函数中通过 write() 写入。
参数:
– fd 文件描述符
– data 要写入的数据( String 或 Buffer )
– offset buffer 写入的偏移量
– length 写入的长度
– position 写入的起始位置
– encoding 写入编码

流式文件写入

往一个文件中写入大量数据时,最好的方法之一
是使用流。
若要将数据异步传送到文件,首需要使用以下语
法创建一个 Writable 对象:
– fs.createWriteStream(path[, options ])
path 文件路径
options {encoding:"",mode:"",flag:""}
一旦你打开了 Writable 文件流,就可以使用
write() 方法来写入它,写入完成后,在调用 end()
方法来关闭流。

读取文件

fs 中提供了四 种读取文件的方式
– 简单文件读取
– 同步文件读取
– 异步文件读取
– 流式文件读取

简单文件 读取

fs.readFile(file[, options], callback )
fs.readFileSync(file[, options ])
– 参数:
file 文件路径或文件描述符
options|
– encoding|默认 = null
– flag默认 = 'r '
callback 回调函数,有两个参数 err 、 data

同步文件读取

fs.readSync(fd, buffer, offset, length,
position )
– 参数:
fd 文件描述符
buffer 读取文件的缓冲区
offset buffer 的开始写入的位置
length 要读取的字节数
position 开始读取文件的位置

异步 文件读取

fs.read(fd, buffer, offset, length,
position, callback )
– 参数:
fd 文件描述符
buffer 读取文件的 缓冲区
offset buffer 的开始写入的位置
length 要读取的字节数
position 开始读取文件的 位置
callback 回调函数 参数 err , bytesRead , buffer

流式文件读取

从一个文件中读取大量的数据时,最好的方法之一就是
流式读取,这样将把一个文件作为 Readable 流的形式
打开。
要从异步从文件传输数据,首先需要通过以下语法创建
一个 Readable 流对象:
– fs.createReadStream(path[, options ])
path 文件路径
options {encoding:"",mode:"",flag :""}
当你打开 Readable 文件流以后,可以通过 readable 事
件和 read() 请求,或通过 data 事件处理程序轻松地从它
读出。

其他操作

验证路径是否存在
– fs.exists(path , callback)
– fs.existsSync(path )
获取文件信息
– fs.stat(path, callback )
– fs.statSync(path )
删除文件
– fs.unlink(path, callback )
– fs.unlinkSync(path )

其他操作

列出文件
– fs.readdir(path [, options], callback )
– fs.readdirSync(path[, options ])
截断文件
– fs.truncate(path, len, callback )
– fs.truncateSync(path, len )
建立目录
– fs.mkdir(path[, mode], callback )
– fs.mkdirSync(path[, mode])

其他操作

删除目录
– fs.rmdir(path, callback )
– fs.rmdirSync(path)
重命名文件和目录
– fs.rename(oldPath, newPath, callback )
– fs.renameSync(oldPath, newPath )
监视文件更改写入
– fs.watchFile(filename[, options], listener)

posted @ 2022-03-23 11:37  Linux运维阿铭  阅读(48)  评论(0编辑  收藏  举报