Node.js

它们都是基于nodejs开发的
Webpack
Vite
Babel

VSCode
Figma
Postman

常用的命令行指令

C:/D: 切换盘符
dir 列出当前目录下的所有文件
cd 目录名 进入到指定目录
md 目录名 创建一个文件夹
rd 目录名 删除一个文件夹
.表示当前目录
..表示上一级目录

当我们在命令行窗口打开一个文件,或调用一个程序时,系统会首先在当前目录下寻找文件程序,如果找到了则直接打开如果没有找到则会依次到环境变量path的路径中寻找,直到找到为止,如果没找到则报错。
所以我们可以将一些经常需要访问的程序和文件的路径添加到path中,这样我们就可以在任意位置来访问这些文件和程序了

  • 进程
    - 进程就是一个一个的工作计划(工厂中的车间)

  • 线程
    - 线程是计算机最小的运算单位(工厂中的工人)线程是干活的
    - 线程

  • 传统的服务器都是多线程的
    - 每进来一个请求,就创建一个线程去处理请求

  • Node的服务器单线程的
    - Node处理请求时是单线程,但是在后台拥有一个I/O线程池

node中的js引擎使用的是chrome的v8引擎
node特点:
1.非阻塞、异步的I/O
2.事件和回调函数
3.单线程(主线程是单线程,后台I/O线程池)
4.跨平台
node为了对模块管理引入CommonJS规范
模块的引用:
使用 require()函数来引入一个模块
例如:var 变量 = require(“模块的标识”);
模块的定义:
- node中一个js文件就是一个模块
- 默认情况下在js文件中编写的内容,都是运行在一个独立的函数中,外部的模块无法访问
- 导出变量和函数
- 使用 exports
- 例子:
exports.属性 = 属性值;
exports.方法 = 函数;
- 使用module.exports
- 例子:
module.exports.属性 = 属性值;
module.exports.方法 = 函数;
module.exports = {};

模块的标识

模块的标识就是模块的名字或路径
node通过模块的标识来寻找模块的
对于核心模块(npm中下载的模块),直接使用模块的名字对其进行引入
var fs = require(“fs”);
var express = require(“express”);
对于自定义的文件模块,需要通过文件的路径来对模块进行引入
路径可以是绝对路径,如果是相对路径必须以./或 …/开头
var router = require(“./router”);

npm的命令

  • npm -v 查看npm的版本
  • npm version 查看所有模块的版本
  • npm search 包名 搜索包
  • npm install / i 包名 安装包
  • npm remove / r 包名 删除包
  • npm install 包名 --save 安装包并添加到依赖中
  • npm install 下载当前项目所依赖的包
  • npm install 包名 -g 全局安装包(全局安装的包一般都是一些工具)

node

包结构:

bin
	- 二进制的可执行文件,一般都是一些工具包中才有
lib
	- js文件
doc
	- 文档
test
	- 测试代码
package.json
	- 包的描述文件
package.json	
			- 它是一个json格式的文件,在它里面保存了包各种相关的信息
				name 包名
				version 版本
				dependencies 依赖
				main 包的主要的文件
				bin 可执行文件

npm node的包管理器

- 通过npm可以对node中的包进行上传、下载、搜索等操作
- npm会在安装完node以后,自动安装
- npm的常用指令
	npm -v 查看npm的版本
	npm version 查看所有模块的版本
	npm init 初始化项目(创建package.json)
	npm i/install 包名 安装指定的包
	npm i/install 包名 --save 安装指定的包并添加依赖
	npm i/install 包名 -g 全局安装(一般都是一些工具)
	npm i/install 安装当前项目所依赖的包
	npm s/search 包名 搜索包	
	npm r/remove 包名 删除一个包

文件系统

文件系统可以实现与硬盘的交互

- Buffer(缓冲区)
	- Buffer和数组的结构的非常类似,Buffer是用来存储二进制数据的
	- Buffer的方法
		- Buffer.from(字符串)
			- 将一个字符串中内容保存到一个buffer中
		- buf.toString()
			- 将buffer转换为一个字符串
		- Buffer.alloc(size)
			- 创建一个指定大小的buffer对象
		- Buffer.allocUnsafe(size)
			- 创建一个指定大小的buffer对象,可以包含敏感数据
			
			
- fs模块
	- 在Node通过fs模块来对系统中的文件进行操作,fs模块是node中已经继承好了,不需要在使用npm下载,直接引入即可
	- 引入fs
		var fs = require("fs");
	- fs模块中的大部分操作都提供了两种方法,同步方法和异步方法
		同步方法带sync
		异步方法没有sync,都需要回调函数
		
	- 写入文件
		1.同步写入
		2.异步写入
		3.简单写入
		4.流式写入
		
	- 读取文件
		1.同步读取
		2.异步读取
		3.简单读取
		4.流式读取
		
	- 方法
		- 打开文件
			fs.open(path, flags[, mode], callback)
			fs.openSync(path, flags[, mode])
			
		- 读写文件
			fs.write(fd, string[, position[, encoding]], callback)
			fs.writeSync(fd, string[, position[, encoding]])
			
			fs.read(fd, buffer, offset, length, position, callback)
			fs.readSync(fd, buffer, offset, length, position)
			
		- 关闭文件
			fs.close(fd,callback)
			fs.closeSync(fd);
			
		- 简单文件读取和写入
			//文件如果不存在会自动创建
			fs.writeFile(file, data[, options], callback)
			fs.writeFileSync(file, data[, options])
			
			fs.readFile(path[, options], callback)
			fs.readFileSync(path[, options])
			
			
		- 流式文件读取和写入
			- 流式读取和写入适用于一些比较大的文件
				fs.createWriteStream(path[, options])
				fs.createReadStream(path[, options])

简单的流式写入例子

const fs = require('fs');

// 创建一个可写流,指定要写入的文件路径
const writeStream = fs.createWriteStream('output.txt');

// 假设有一个大数据源,这里使用循环生成一些示例数据
for (let i = 0; i < 10000; i++) {
  // 写入数据到可写流
  writeStream.write(`这是第 ${i + 1} 行数据\n`);
}

// 在数据写入完成后,关闭可写流
writeStream.end();

// 监听可写流的 'finish' 事件,以便在写入完成后执行其他操作
writeStream.on('finish', () => {
  console.log('数据写入完成。');
});

// 监听可写流的 'error' 事件,以处理写入过程中的错误
writeStream.on('error', (err) => {
  console.error('写入错误:', err);
});

简单的流式读取的例子

const fs = require('fs');

// 创建一个可读流,指定要读取的文件路径
const readStream = fs.createReadStream('largefile.txt');

// 监听可读流的 'data' 事件,以处理读取到的数据块
readStream.on('data', (chunk) => {
  console.log(`读取到 ${chunk.length} 字节的数据块:`);
  console.log(chunk.toString()); // 处理数据块的逻辑,这里简单地打印出来
});

// 监听可读流的 'end' 事件,以处理读取结束的情况
readStream.on('end', () => {
  console.log('文件读取结束。');
});

// 监听可读流的 'error' 事件,以处理读取过程中的错误
readStream.on('error', (err) => {
  console.error('读取错误:', err);
});

文件的重命名和移动

const fs = require('fs');

// 定义原始文件路径和目标文件路径
const oldFilePath = 'oldfile.txt';
const newFilePath = 'newfile.txt';

// 执行文件重命名(移动)操作
fs.rename(oldFilePath, newFilePath, (err) => {
  if (err) {
    console.error('文件重命名失败:', err);
  } else {
    console.log('文件重命名成功。');
  }
});

文件的删除

const fs = require('fs');

const filePath = '要删除的文件路径.txt';

// 使用 fs.unlink() 方法删除文件
fs.unlink(filePath, (err) => {
  if (err) {
    console.error(`删除文件时发生错误: ${err}`);
  } else {
    console.log(`文件 ${filePath} 已成功删除`);
  }
});

//注意,再node14.1以后版本中也可以使用fs.rm(filePath, (err) => {})

fs模块文件夹操作

创建文件夹

const fs = require('fs');

const folderPath = '新文件夹';

fs.mkdir(folderPath, (err) => {
  if (err) {
    console.error(`创建文件夹时发生错误: ${err}`);
  } else {
    console.log(`文件夹 ${folderPath} 已成功创建`);
  }
});

//递归创建
fs.mkdir( './a/b/c', {recursive: true} ,err => {
	if(err) {
		console.log('创建失败~');
		return;
	}
	console.log('创建成功');
);


删除文件夹

const fs = require('fs');

const folderPath = '要删除的文件夹';

fs.rmdir(folderPath, (err) => {
  if (err) {
    console.error(`删除文件夹时发生错误: ${err}`);
  } else {
    console.log(`文件夹 ${folderPath} 已成功删除`);
  }
});

读取文件夹内容

const fs = require('fs');

const folderPath = '要读取的文件夹';

fs.readdir(folderPath, (err, files) => {
  if (err) {
    console.error(`读取文件夹内容时发生错误: ${err}`);
  } else {
    console.log(`文件夹 ${folderPath} 中的内容: ${files}`);
  }
});

检查文件夹是否存在

const fs = require('fs');

const folderPath = '要检查的文件夹';

if (fs.existsSync(folderPath)) {
  console.log(`文件夹 ${folderPath} 存在`);
} else {
  console.log(`文件夹 ${folderPath} 不存在`);
}

fs模块查看资源状态

const fs = require('fs');

const resourcePath = '要查看状态的资源路径';

fs.stat(resourcePath, (err, stats) => {
  if (err) {
    console.error(`获取资源状态时发生错误: ${err}`);
  } else {
    console.log('资源状态信息:');
    console.log(`是否为文件: ${stats.isFile()}`);
    console.log(`是否为文件夹: ${stats.isDirectory()}`);
    console.log(`文件大小(字节): ${stats.size}`);
    console.log(`创建时间: ${stats.ctime}`);
    console.log(`最后修改时间: ${stats.mtime}`);
  }
});

__dirname 是 Node.js 中的一个特殊变量,它表示当前执行脚本所在的目录的绝对路径

path模块

Node.js 中的 path 模块是用于处理文件路径的核心模块之一。它提供了一组方法,用于执行跨平台的路径操作,使你能够轻松地处理文件和目录路径,而不必担心不同操作系统的差异。以下是一些 path 模块的常见用法和方法:

  1. path.join(...paths) 这个方法将多个路径片段连接起来,并返回一个标准化的路径。它会自动处理斜杠(/\)以及不同操作系统下的路径分隔符问题。

    const path = require('path');
    
    const fullPath = path.join('目录', '子目录', '文件.txt');
    console.log(fullPath); // 输出: 目录/子目录/文件.txt(Unix系统)或目录\子目录\文件.txt(Windows系统)
    
  2. path.resolve(...paths) 这个方法从右到左解析路径,直到构建出一个绝对路径。通常用于构建文件的绝对路径。

    const path = require('path');
    
    const absolutePath = path.resolve('相对路径', '到文件.txt');
    console.log(absolutePath); // 输出: /绝对路径/到文件.txt(Unix系统)或 C:\绝对路径\到文件.txt(Windows系统)
    
  3. path.dirname(path) 返回指定路径的目录名部分。

    const path = require('path');
    
    const dirName = path.dirname('/目录/子目录/文件.txt');
    console.log(dirName); // 输出: /目录/子目录
    
  4. path.basename(path, ext) 返回指定路径的文件名部分,可以选择是否包含文件扩展名。

    const path = require('path');
    
    const fileName = path.basename('/目录/子目录/文件.txt');
    console.log(fileName); // 输出: 文件.txt
    
    const baseNameWithoutExt = path.basename('/目录/子目录/文件.txt', '.txt');
    console.log(baseNameWithoutExt); // 输出: 文件
    
  5. path.extname(path) 返回指定路径的文件扩展名部分。

    const path = require('path');
    
    const extName = path.extname('/目录/子目录/文件.txt');
    console.log(extName); // 输出: .txt
    

path 模块还包括其他方法,用于处理路径、规范化路径、检查路径的绝对性等等。这些方法使得在处理文件和目录路径时更加方便和可靠,尤其在跨不同操作系统的开发中非常有用。

node环境中的顶级对象是global

buffer

buffer就是一段长度的内存区域

创建buffer

//1. alloc
Let buf = Buffer.alloc(10);//console.log(buf);
//2. allocUnsafe
Let buf_2 = Buffer.allocUnsafe(10);//console.log(buf_2);
//3. from
Let buf_3 = Buffer.from('hello');
Let buf_4 = Buffer.from([ 105,108111118101121,111,117]);//console.log(buf_4);

HTTP协议

请求行
请求头
空行
请求体

//请求行
GET /path/to/resource HTTP/1.1
//请求头
Host: example.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64)
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
//空行

//请求体

请求行:
包含了请求的方法、目标URL和HTTP版本

POST /api/users/login HTTP/1.1

请求头:
包含了关于请求的元信息,例如主机、用户代理、接受的内容类型等

Host: example.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64)
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8

如何获取请求行、请求头和请求体

const http = require('http');

// 创建HTTP服务器
const server = http.createServer((req, res) => {
  // 获取请求行
  const requestLine = req.method + ' ' + req.url + ' ' + req.httpVersion;
  console.log('请求行:', requestLine);

  // 获取请求头部
  const requestHeaders = req.headers;
  console.log('请求头部:', requestHeaders);

  // 定义一个变量来存储请求体数据
  let requestBody = '';

  // 监听请求的数据事件,以获取请求体数据
  req.on('data', (chunk) => {
    requestBody += chunk.toString();
  });

  // 监听请求结束事件,处理请求体数据
  req.on('end', () => {
    console.log('请求体:', requestBody);

    // 响应客户端
    res.writeHead(200, { 'Content-Type': 'text/plain' });
    res.end('请求已处理\n');
  });
});

// 监听端口
server.listen(3000, () => {
  console.log(`服务器运行在 http://localhost:${port}/`);
});

获取路径和查询字符串(方法1)

因为使用req.url返回的是包含路径和查询字符串的一个整体,可以使用url模块进一步拆分出路径和查询字符串

const http = require('http');
const url = require('url'); // 引入url模块

// 创建HTTP服务器
const server = http.createServer((req, res) => {
  // 获取请求的完整URL
  const requestUrl = req.url;

  // 使用url模块来解析URL
  const parsedUrl = url.parse(requestUrl, true);//true表示将查询字符串转换为对象

  // 获取路径和查询字符串
  const path = parsedUrl.pathname;
  const query = parsedUrl.query;

  // 打印路径和查询字符串
  console.log('路径:', path);
  console.log('查询字符串:', query);

  // 响应客户端
  res.writeHead(200, { 'Content-Type': 'text/plain' });
  res.end('URL已解析\n');
});

// 监听端口
const port = 3000;
server.listen(port, () => {
  console.log(`服务器运行在 http://localhost:${port}/`);
});

获取路径和查询字符串(方法2)

const http = require('http');

// 创建HTTP服务器
const server = http.createServer((req, res) => {
  // 获取请求的完整URL
  const requestUrl = req.url;

  // 使用URL构造函数来解析URL
  const parsedUrl = new URL(requestUrl, 'http://127.0.0.1');

  // 获取路径和查询字符串
  const path = parsedUrl.pathname;
  const query = parsedUrl.searchParams;

  res.end('URL已解析\n');
});

// 监听端口
server.listen(3000, () => {
  console.log(`服务器运行在 http://localhost:3000/`);
});

设置HTTP响应报文

const http = require('http');

// 创建HTTP服务器
const server = http.createServer((req, res) => {
  // 设置响应行
  res.writeHead(200, { 'Content-Type': 'text/plain' });

  // 设置响应头部
  res.setHeader('Custom-Header', 'Hello, Custom Header');

  // 设置响应体
  res.write('Hello, World!\n');

  // 结束响应
  res.end();
});

// 监听端口
const port = 3000;
server.listen(port, () => {
  console.log(`服务器运行在 http://localhost:${port}/`);
});

nodejs模块化

在Node.js中,一个文件就是一个模块,每个模块具有自己的作用域,可以独立开发、测试和维护。Node.js使用CommonJS模块系统来实现模块化。

创建模块

要创建一个模块,只需在文件中定义变量、函数或对象,然后使用module.exports将它们导出,以便其他文件可以访问它们。例如,创建一个名为myModule.js的模块:

// myModule.js

// 定义一个变量
const message = "Hello, World!";

// 定义一个函数
function greet(name) {
  return `Hello, ${name}!`;
}

// 导出变量和函数
module.exports.message = message;
module.exports.greet = greet;

引入模块

要在其他文件中使用模块,可以使用require函数引入它。引入模块后,你可以访问模块中导出的变量、函数或对象。例如,在另一个文件中使用上面的模块:

// main.js

// 引入模块
const myModule = require('./myModule');

// 使用导出的变量和函数
console.log(myModule.message); // 输出 "Hello, World!"
console.log(myModule.greet("Alice")); // 输出 "Hello, Alice!"

内置模块

Node.js还提供了一些内置模块,例如fs(文件系统)、http(HTTP服务器与客户端)、path(路径处理)等。这些内置模块可以直接引入和使用,无需额外安装。例如:

const fs = require('fs');
const http = require('http');
const path = require('path');

第三方模块

除了内置模块外,Node.js社区还开发了大量第三方模块,可以通过npm(Node.js包管理器)安装和使用。要使用第三方模块,首先需要安装它,然后可以使用require函数引入它。例如,安装并使用lodash模块:

// 安装lodash模块
// npm install lodash

// 在代码中引入lodash模块
const _ = require('lodash');

// 使用lodash的函数
const result = _.sum([1, 2, 3, 4, 5]);
console.log(result); // 输出 15

这些是Node.js模块化的基本概念和示例。模块化是Node.js开发中的核心概念,它有助于组织和管理代码,提高可维护性和可重用性。

npm

使用require导入npm下载的包的基本流程和内部流程

基本流程:

  1. **安装包:例如,安装lodash包:

    npm install lodash
    

    这将在项目的node_modules目录下安装lodash包,并将其添加到package.json文件的dependencies中。

  2. 导入包: 使用require来导入已安装的包。例如:

    const _ = require('lodash');
    

    这将导入lodash包并将其赋值给变量_,以便你可以在代码中使用它。

  3. 使用包: 例如,使用lodashmap函数:

    const numbers = [1, 2, 3, 4, 5];
    const squaredNumbers = _.map(numbers, (num) => num * num);
    console.log(squaredNumbers);
    

    在这个示例中,我们使用lodash包中的map函数来对数组中的每个元素进行平方运算。

  4. 运行代码: 最后,运行你的Node.js代码。你可以使用node命令来执行你的脚本,例如:

    node yourScript.js
    

    这将运行你的代码,并在控制台中输出结果。

内部流程:

当你使用require导入一个包时,Node.js会按以下顺序查找和加载模块:

  • 首先,Node.js会尝试查找内置模块(例如fshttp等)或核心模块,如果找到匹配的模块,它将被加载。

  • 如果没有找到匹配的核心模块,Node.js会查找node_modules目录。它会从当前模块的目录开始,逐级向上查找,直到找到匹配的模块或到达文件系统的根目录。

  • node_modules目录中,Node.js会查找并加载匹配模块名的目录,然后尝试加载该目录中的package.json文件。如果找到package.json文件,Node.js会读取其中的main字段,该字段指定了模块的入口文件(通常是一个JavaScript文件),然后加载入口文件。

  • 如果没有找到package.json文件或main字段,Node.js将默认尝试加载包目录中的index.js文件。

  • 最终,Node.js会将加载的模块缓存起来,以避免重复加载相同的模块。

Nodemon 是一个Node.js开发的热重载工具,它有助于提高Node.js应用程序的开发效率。Nodemon监视你的Node.js应用程序文件的更改,并在文件发生更改时自动重新启动应用程序,无需手动停止和启动。这对于在开发过程中进行实时调试和测试非常有用,因为它可以减少手动重启应用程序的需求。

为什么要安装或设置环境变量

设置环境变量是为了在操作系统中存储和访问全局配置信息,以供不同应用程序和系统组件共享和使用。

你可能感兴趣的:(前端技术未分类,node.js)