Node.js基础知识整理

Node.js——Node.js基础知识记录,持续更新...

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'
      

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 个方法:spawnexecexecFilefork

模块化

模块化是把一个大文件拆成独立并互相依赖的多个小模块,提高了代码的复用性,提高了代码的可维护性,可以实现按需加载。 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 包名 -Dnpm i 包名 --save-dev命令把包记录到devDependencies。

3、包的发布

  1. 新建 xxx 文件夹,作为包的根目录;
  2. 在 xxx 文件夹中,新建如下三个文件:package.json(包管理配置文件)、index.js(包的入口文件)、README.md(包的说明文档)
  3. 初始化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"
    }
    
  4. 编写包的说明文档README.md:安装方式、导入方式、开源协议
  5. 以在终端中执行npm login 命令,依次输入用户名、密码、邮箱后,即可登录成功。

    注意:在运行npm login命令之前,必须先把下包的服务器地址切换为npm的官方服务器。否则会导致发布包失败!

  6. 将终端切换到包的根目录之后,运行 npm publish 命令,即可将包发布到 npm 上(注意:包名不能重复)。
  7. 删除已发布的包:运行 npm unpublish 包名 --force 命令,即可从 npm 删除已发布的包。

    注意:npm unpublish 命令只能删除 72 小时以内发布的包。npm unpublish 删除的包,在 24 小时内不允许重复发布。

模块的加载机制

模块在第一次加载后会被缓存。 这也意味着多次调用 require() 不会导致模块的代码被执行多次。

注意:不论是内置模块、用户自定义模块、还是第三方模块,它们都会优先从缓存中加载,从而提高模块的加载效率。

  • 内置模块:由 Node.js 官方提供的模块,内置模块的加载优先级最高
  • 自定义模块:必须指定以 ./ 或 ../ 开头的路径标识符,否则会把它当作内置模块或第三方模块进行加载
  • 第三方模块:如果传递给 require()的模块标识符不是一个内置模块,也没有以‘./’或‘../’开头,则Node.js会从当前模块的父目录开始,尝试从 /node_modules 文件夹中加载第三方模块。


-->