Node.js
- 浏览器是JavaScript的前端运行环境;
- Node.js是JavaScript的后端运行环境;
- Node.js中无法调用DOM和BOM等浏览器内置的API。
global全局对象
1、常用的全局变量
__filename
表示当前文件所在的绝对路径。例如:H:\My_Projects\nodeProject\test.js
process.cwd()
获取当前工作目录的绝对路径process.env
获取当前执行环境的环境变量 (对象形式)process.version
获取当前 Node 版本process.exit([code])
终止 Node.js 进程,如果指定了 code 参数,则使用该参数作为退出状态码。在终端里可以通过echo $?
获取传递的退出状态码
__dirname
表示当前文件所在目录的绝对路径。例如:H:\My_Projects\nodeProject
- 创建 Buffer 对象
1 2 3
const buf = Buffer.alloc(10); // 创建一个大小为 10 的 Buffer 对象,默认会用 0 填充 const buf2 = Buffer.from('Hello, world!'); // 创建一个包含字符串 'Hello, world!' 的 Buffer 对象 const buf3 = Buffer.from([0x68, 0x65, 0x6c, 0x6c, 0x6f]); // 内容为hello构成的16进制数组 Buffer 对象
- 转换内容格式
1 2 3 4 5 6 7 8 9 10 11 12 13
const buf = Buffer.from('Hello, world!'); // 转为字符串输出 console.log(buf.toString()); // 输出 'Hello, world!' // 转为16进制字符串输出 console.log(buf.toString('hex')); // 输出 '48656c6c6f2c20776f726c6421'(对应的是 'Hello, world!' 的 ASCII 码) // 转为数组输出 console.log(Array.from(buf)); // 输出 [ // 72, 101, 108, 108, 111, // 44, 32, 119, 111, 114, // 108, 100, 33 // ] // 转为base64格式输出 console.log(buf.toString('base64')); // 输出 'SGVsbG8sIHdvcmxkIQ=='
- 写入内容
1 2 3 4 5 6 7 8 9 10 11
// 创建一个长度为 10 的 Buffer 实例并将它填充为 0 const buf = Buffer.alloc(10); // 将字符串 'Hello' 写入 Buffer 实例的前 5 个字节 buf.write('Hello'); // 将字符串 'world' 写入 Buffer 实例的第 6 个字节开始的位置,由于 'world' 的长度为 5,所以不会覆盖掉之前写入的 'Hello' buf.write('world', 5); // 将 Buffer 实例转换为字符串并输出 'Hello world' console.log(buf.toString());
- 合并多个 Buffer 对象
1 2 3 4
const buf1 = Buffer.from('Hello'); const buf2 = Buffer.from('World'); const buf3 = Buffer.concat([buf1, buf2]); console.log(buf3.toString()); // 输出 'HelloWorld'
- 截取 Buffer 对象
1 2 3
const buf = Buffer.from('Hello, world!'); const buf2 = buf.slice(0, 5); console.log(buf2.toString()); // 输出 'Hello'
- 创建 Buffer 对象
2、常用 global 属性
process
提供了与当前 Node.js 进程相关的信息和控制方法Buffer
用于处理二进制数据。类似于数组,并提供了一些方便的方法来操作二进制数据
fs 文件系统模块
fs 模块是 Node.js 官方提供的、用来操作文件的模块。它提供了一系列的方法和属性,用来满足用户对文件的操作需求。
1、读取指定文件中的内容fs.readFile()
- 参数1:必选参数,字符串,表示文件的路径。
- 参数2:可选参数,表示以什么编码格式来读取文件。
- 参数3:必选参数,文件读取完成后,通过回调函数拿到读取的结果。
1 2 3 4
const fs = require('fs'); fs.readFile('./test.txt', 'utf8', function(err, dataStr){ //如果文件写入成功,则err等于null,否则err等于一个错误对象 })
2、读取指定文件中的内容fs.writeFile()
(会替代文件原有内容,如果想追加内容,使用appendFile()
)
- 参数1:必选参数,需要指定一个文件路径的字符串,表示文件的存放路径。
- 参数2:必选参数,表示要写入的内容。
- 参数3:可选参数,表示以什么格式写入文件内容,默认值是 utf8。
- 参数4:必选参数,文件写入完成后的回调函数。
1 2 3 4 5
const fs = require('fs'); fs.writeFile('./test.txt', 'Hello World', (err) => { //如果文件写入成功,则err等于null,否则err等于一个错误对象 //如果该路径下不存在这个文件,就会自动创建 })
path 路径模块
path 模块是 Node.js 官方提供的、用来处理路径的模块。它提供了一系列的方法和属性,用来满足用户对路径的处理需求。
1、path.join()
路径拼接
1
2
3
4
const res = path.join('a','/b/c/d', '../', '/e')
console.log(res); //a\b\c\e
//用__dirname和path.join(),取代用+拼接
path.join(__dirname, './成绩-ok.txt')
2、path.resolve()
将多个路径拼接成一个绝对路径
1
2
console.log(path.resolve('a', 'b', 'c')) // H:\My_Projects\nodeProject\a\b\c
console.log(path.resolve('/a', './b', 'c')) // H:\a\b\c
3、path.dirname()
返回路径中的目录名
1
2
3
//__filename: H:\My_Projects\nodeProject\test.js
console.log(path.dirname(__filename)) // H:\My_Projects\nodeProject
console.log(path.dirname('/a/b/c')) // /a/b
4、path.basename()
获取路径中的文件名,并可选地去除给定的文件扩展名
- 参数1:必选参数,表示一个路径的字符串
- 参数2:可选参数,表示文件扩展名(加上之后,结果不会返回这个扩展名)
1 2 3 4
const PATH = '/a/b/c/index.html'; console.log(path.basename(PATH)); // index.html console.log(path.basename(PATH, '.html')); // index console.log(path.basename(PATH, 'ml')); // index.ht
5、path.extname()
获取路径中的文件扩展名
- 参数1:必选参数,表示一个路径的字符串
1 2 3 4
console.log(path.extname('a/b/c.js')) // .js console.log(path.extname('a/b/c')) // '' console.log(path.extname('a/b/c.d.ts')) // .ts console.log(path.extname('a/b/.npmrc')) // ''
6、path.normalize()
用于规范化路径,将路径中的不规范部分调整为标准格式
- 参数1:必选参数,表示一个路径的字符串
1 2
// 消除路径中多余的斜杠;处理路径中存在的 ./ 或 ../ console.log(path.normalize('a//b//c/../d/e/..')) // a\b\d
7、path.parse()
用于解析文件路径,将其拆分为一个对象
http 模块
http 模块是 Node.js 官方提供的、用来创建 web 服务器的模块。通过 http 模块提供的 http.createServer()
方法,就能方便的把一台普通的电脑,变成一台 Web 服务器,从而对外提供 Web 资源服务。
1、创建基本web服务器
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
const http = require('http');
const serve = http.createServer();//创建web服务器实例
serve.on('request', (req, res) => {
//req是请求对象, 包含了与客户端相关的数据和属性,例如:
//req.url 是客户端请求的URL地址(端口号后面的内容)
//req.method 是客户端的请求类型
const url = req.url;
const method = req.method;
// 为防止中文显示乱码问题,需要设置响应头Content-Type的值为text/html; charset=utf-8
res.setHeader('Content-Type', 'text/html; charset=utf-8')
// res是响应对象, 包含了与服务器相关的数据和属性
// res.end() 方法作用:向客户端发送指定的内容,并结束这次请求的处理过程
res.end(`你的请求地址是${url},请求类型是${method}`);
})
serve.listen(3000, () => {
console.log('启动成功');
})
child_process创建子进程
虽然 js 是单线程的,但通过创建子进程也能实现多任务并行处理,也可通过其调用系统的功能指令完成复杂的任务。
主要提供了 4 个方法:spawn
、exec
、execFile
和 fork
模块化
模块化是把一个大文件拆成独立并互相依赖的多个小模块,提高了代码的复用性,提高了代码的可维护性,可以实现按需加载。 1、模块的分类,分别是:
- 内置模块(内置模块是由 Node.js 官方提供的,例如 fs、path、http 等)
- 自定义模块(用户创建的每个 .js 文件,都是自定义模块)
- 第三方模块(由第三方开发出来的模块,并非官方提供的内置模块,也不是用户创建的自定义模块,使用前需要先下载)
2、模块的加载
使用require()
方法可以加载需要的内置模块、用户自定义模块、第三方模块(包)。
注意:
- 使用 require() 方法加载其它模块时,会执行被加载模块中的代码。
- require() 模块时,得到的永远是 module.exports 指向的对象
3、模块作用域 在自定义模块中定义的变量、方法等成员,只能在当前模块内被访问,这种模块级别的访问限制,叫做模块作用域。
4、module 对象 在每个 .js 自定义模块中都有一个 module 对象,它里面存储了和当前模块有关的信息。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
Module {
id: '.',
path: 'D:\\Code\\MyProjects\\studyNode',
exports: {},
filename: 'D:\\Code\\MyProjects\\studyNode\\index.js',
loaded: false,
children: [],
paths: [
'D:\\Code\\MyProjects\\studyNode\\node_modules',
'D:\\Code\\MyProjects\\node_modules',
'D:\\Code\\node_modules',
'D:\\node_modules'
]
}
其中包含的exports
属性可以将模块内的成员共享出去,供外界使用,外界用 require()
方法导入自定义模块时,得到的就是 module.exports
所指向的对象。
5、exports 对象 Node 提供了 exports 对象。默认情况下,exports 和 module.exports 指向同一个对象。
6、 CommonJS 模块化规范 Node.js 遵循了 CommonJS 模块化规范,CommonJS 规定了模块的特性和各模块之间如何相互依赖。
CommonJS 规定:
- 每个模块内部,module 变量代表当前模块。
- module 变量是一个对象,它的 exports 属性(即 module.exports)是对外的接口。
- 加载某个模块,其实是加载该模块的 module.exports 属性。require() 方法用于加载模块。
npm与包
1、包的安装
安装指定版本的包:可以在包名之后,通过 @ 符号指定具体的版本。例如:npm install elementUI@1.1.1
安装某个包后悔自动生成node_modules
的文件夹、做 package.json
的包管理配置文件、 package-lock.json
配置文件
node_modules
文件夹用来存放所有已安装到项目中的包。require()
导入第三方包时,就是从这个目录中查找并加载包。package.json
用来记录与项目有关的一些配置信息.package-lock.json
配置文件用来记录node_modules
目录下的每一个包的下载信息,例如包的名字、版本号、下载地址等。
包的版本号(1.1.1)意义:第1位数字(大版本)、第2位数字(功能版本)、第3位数字(Bug修复版本)
2、package.json文件
-
dependencies
节点:记录在项目开发和项目上线都会用到的包信息 -
devDependencies
节点:记录只在项目开发阶段会用到,在项目上线之后不会用到的包信息 通过npm i 包名 -D
或npm i 包名 --save-dev
命令把包记录到devDependencies。
3、包的发布
- 新建 xxx 文件夹,作为包的根目录;
- 在 xxx 文件夹中,新建如下三个文件:
package.json
(包管理配置文件)、index.js
(包的入口文件)、README.md
(包的说明文档) - 初始化
package.json
1 2 3 4 5 6 7 8 9
{ "name": "dj-test", "version": "1.0.0", "main": "index.js", "description": "first dj package", "keywords": ["dj", "test"], "license": "ISC", "author": "dj" }
- 编写包的说明文档
README.md
:安装方式、导入方式、开源协议 - 以在终端中执行
npm login
命令,依次输入用户名、密码、邮箱后,即可登录成功。注意:在运行
npm login
命令之前,必须先把下包的服务器地址切换为npm的官方服务器。否则会导致发布包失败! - 将终端切换到包的根目录之后,运行 npm publish 命令,即可将包发布到 npm 上(注意:包名不能重复)。
- 删除已发布的包:运行
npm unpublish 包名 --force
命令,即可从 npm 删除已发布的包。注意:npm unpublish 命令只能删除 72 小时以内发布的包。npm unpublish 删除的包,在 24 小时内不允许重复发布。
模块的加载机制
模块在第一次加载后会被缓存。 这也意味着多次调用 require() 不会导致模块的代码被执行多次。
注意:不论是内置模块、用户自定义模块、还是第三方模块,它们都会优先从缓存中加载,从而提高模块的加载效率。
- 内置模块:由 Node.js 官方提供的模块,内置模块的加载优先级最高
- 自定义模块:必须指定以 ./ 或 ../ 开头的路径标识符,否则会把它当作内置模块或第三方模块进行加载
- 第三方模块:如果传递给
require()
的模块标识符不是一个内置模块,也没有以‘./’或‘../’开头,则Node.js会从当前模块的父目录开始,尝试从/node_modules
文件夹中加载第三方模块。