diff --git "a/\351\273\204\350\264\235\347\204\266/20260306-node.js\345\237\272\347\241\200.md" "b/\351\273\204\350\264\235\347\204\266/20260306-node.js\345\237\272\347\241\200.md" new file mode 100644 index 0000000000000000000000000000000000000000..c29d8561b6c84b59e5a722e85e6bdc4cd12df35a --- /dev/null +++ "b/\351\273\204\350\264\235\347\204\266/20260306-node.js\345\237\272\347\241\200.md" @@ -0,0 +1,87 @@ +# 笔记 + +1. Node.js概念 + +- Node.js是一个基于Chrome V8引擎的JavaScript运行时,让JavaScript可以脱离浏览器在服务器端运行。 + +2. Node.js特点 + +- 单线程 + - 优点: + - 节省内存资源 + - 不存在线程切换开销 + - 编程模型简单 + - 缺点: + - 无法利用多核CPU + - 计算密集型任务会阻塞 + +- 非阻塞 + +3. 阻塞与非阻塞I/O + +- 非阻塞:当程序需要读取文件、查询数据库时,Node.js不会等待结果,而是继续执行其他代码。 +- 阻塞:与上方相反 +- 示例 +```javascript +// 阻塞式(传统方式) +const data = fs.readFileSync('file.txt'); // 等待完成! +console.log(data); + +// 非阻塞式(Node.js方式) +fs.readFile('file.txt', (err, data) => { + console.log(data); // 文件就绪后执行 +}); +console.log('继续执行其他代码'); // 这行先执行! +``` + +4. 同步与异步I/O + +- 同步 I/O:应用程序自己等待并完成数据拷贝 +- 异步 I/O:你提交 I/O 请求后,内核自己做完全部操作,做完后内核主动通知你(信号 / 回调),你全程不用等、不用轮询、不用再读 + +# 作业 + +## 选择题 + +1. Node.js是基于哪个JavaScript引擎开发的? + - C. JavaScriptCore + +2. 以下哪个不是Node.js的核心特性? + - B. 多线程 + +3. Node.js最适合开发以下哪种应用? + - C. 实时聊天系统 + +4. 以下哪个是Node.js的创始人? + - B. Ryan Dahl + +5. Node.js中的"I/O"主要指什么? + - A. Input/Output(输入/输出)、 + +## 简答题 + +1. 什么是Node.js?请用一句话概括。 + + - Node.js是一个基于Chrome V8引擎的JavaScript运行时,让JavaScript可以脱离浏览器在服务器端运行。 + +2. 请解释"非阻塞I/O"是什么意思,它有什么优点? + + - 当程序需要读取文件、查询数据库时,Node.js不会等待结果,而是继续执行其他代码。 + - 优点:提升线程利用率、支撑高并发(适配 I/O 密集型场景)、减少上下文切换开销; + +3. 为什么Node.js适合开发实时聊天应用? + + - Node.js 的非阻塞 I/O + 事件驱动完美适配实时聊天的高并发、低延迟需求,能高效处理大量网络 I/O 连接; + - 对WebSocket 的良好支持实现了客户端 - 服务器的双向实时通信,是实时聊天的核心技术基础; + - 轻量高效、前后端同语言、丰富的生态进一步降低了开发和运维成本,适配实时聊天场景的特性需求 + +4. 请列举Node.js的3个应用场景。 + + - Web服务器 + - API服务 + - 前端构建工具 + +5. Node.js和传统后端语言(如Java、PHP)相比,有什么优势? + - 节省内存资源 + - 不存在线程切换开销 + - 编程模型简单 diff --git "a/\351\273\204\350\264\235\347\204\266/20260309-\345\214\205\347\256\241\347\220\206.md" "b/\351\273\204\350\264\235\347\204\266/20260309-\345\214\205\347\256\241\347\220\206.md" new file mode 100644 index 0000000000000000000000000000000000000000..de480f0f373da486e2f85fcfe1430d90f70fafdf --- /dev/null +++ "b/\351\273\204\350\264\235\347\204\266/20260309-\345\214\205\347\256\241\347\220\206.md" @@ -0,0 +1,314 @@ +# 笔记 + +- 指令 + +```bash +# 初始化项目 +$ npm init -y + +# 安装express框架 +$ npm install express + +# 安装开发依赖 +$ npm install --save-dev nodemon + +# 查看已安装的包 +$ npm list + +# 运行项目 +$ npm start +``` + +## 三大包管理器 + +Node.js生态中有三大主流包管理器: + +| 包管理器 | 简介 | 特点 | +|---------|------|------| +| **npm** | Node.js官方包管理器 | 历史最久、生态最大 | +| **yarn** | Facebook开发 | 速度快、离线安装、确定性安装 | +| **pnpm** | 公司开发 | 节省磁盘空间、更快、更安全 | + +### 三大包对比 + +| 特性 | npm | yarn | pnpm | +|------|-----|------|------| +| 安装速度 | 慢 | 快 | 最快 | +| 磁盘占用 | 大 | 中 | 小 | +| lock文件 | package-lock.json | yarn.lock | pnpm-lock.yaml | +| node_modules | 扁平 | 扁平 | 平铺+符号链接 | +| 离线安装 | 不支持 | 支持 | 支持 | + +### npm +- npm是Node.js的管理器,让安装跟管理第三方库变得非常简单 + +- npm常用指令 + +1. 项目初始化 + +```bash +# 交互式初始化(会询问项目信息) +npm init + +# 使用默认配置初始化(快速) +npm init -y + +# 指定项目信息初始化 +npm init --yes +``` + +2. 安装包 + +```bash +# 安装到dependencies(生产环境需要) +npm install <包名> +npm i <包名> + +# 安装到devDependencies(开发环境需要) +npm install --save-dev <包名> +npm i -D <包名> + +# 全局安装(所有项目可用) +npm install --global <包名> +npm i -g <包名> + +# 安装指定版本 +npm install express@4.18.0 + +# 安装多个包 +npm install express mysql2 cors +``` + +3. 管理和查看 + +```bash +# 查看已安装的包 +npm list + +# 查看已安装的包(显示顶层) +npm list --depth=0 + +# 查看某个包的版本信息 +npm view express version + +# 查看某个包的所有版本 +npm view express versions + +# 查看包的信息 +npm view express +``` + +4. 更新和卸载 + +```bash +# 更新包 +npm update <包名> + +# 更新所有依赖 +npm update + +# 卸载包 +npm uninstall <包名> +npm remove <包名> +``` + +5. npm脚本 + +```bash +# 运行package.json中定义的脚本 +npm run <脚本名> + +# 常用简写 +npm start # npm run start +npm test # npm run test +npm stop # npm run stop +``` + + +## package.json + +- `package.json` 是Node.js项目的"身份证",记录了项目的基本信息和依赖。 + +### package.json字段说明 + +```json +{ + "name": "my-blog", // 项目名称(必须,不能有大写) + "version": "1.0.0", // 版本号(语义化版本) + "description": "我的博客系统", // 项目描述 + "main": "index.js", // 入口文件 + "scripts": { // 自定义脚本命令 + "start": "node index.js", + "dev": "nodemon index.js", + "test": "jest" + }, + "keywords": ["blog", "node"], // 关键词 + "author": "张三", // 作者 + "license": "MIT", // 许可证 + "dependencies": { // 生产依赖(项目运行需要) + "express": "^4.18.2", + "mysql2": "^3.6.0" + }, + "devDependencies": { // 开发依赖(仅开发时需要) + "nodemon": "^3.0.0", + "jest": "^29.0.0" + } +} +``` + +## 镜像源管理 + +- npm默认从国外下载包,在国内访问速度很慢 + +### 使用淘宝镜像 + +```bash +# 方式1:临时使用镜像 +npm install express --registry=https://registry.npmmirror.com + +# 方式2:设置为默认镜像 +npm config set registry https://registry.npmmirror.com + +# 验证设置 +npm config get registry +# 输出:https://registry.npmmirror.com +``` + +### 镜像源管理工具 + +nrm可以快速切换不同的镜像源: + +```bash +# 全局安装nrm +npm install -g nrm + +# 查看可用镜像源 +nrm ls + +# 切换到淘宝镜像 +nrm use taobao + +# 切换到官方镜像 +nrm use npm +``` + +## 具体步骤 + +1. 新建文件夹,打开 + +2. 初始化项目:npm init -y + +3. 安装express框架:npm install express + +4. 安装开发依赖:npm install --save-dev nodemon + 若执行命令正确仍然报错,如网络报错问题,可切换npm镜像源 + - 临时切换镜像源安装 + npm install nodemon --save-dev --registry=https://registry.npmmirror.com + + - 或者永久切换淘宝镜像 + npm config set registry https://registry.npmmirror.com + +5. 配置 package.json 启动脚本: +打开项目里的 package.json 文件,在 scripts 字段中添加 start 脚本(用 nodemon 启动入口文件),修改后如下: +{ + "name": "你的文件夹名", + "version": "1.0.0", + "main": "index.js", + "scripts": { + "start": "nodemon index.js" // 新增:启动脚本,nodemon监控index.js + "dev": "nodemon index.js" + }, + "keywords": [], + "author": "", + "license": "ISC", + "dependencies": { + "express": "^5.2.1" // 安装后自动生成 + }, + "devDependencies": { + "nodemon": "^3.1.14" // 之前安装的nodemon + } +} + +6. 创建 Express 入口文件(index.js) +在项目文件夹根目录下新建 index.js 文件(和 package.json 同目录) + +7. npm start(start指的是你在package.json自定义的脚本名称) + + +start:node index.js 用原生 node 启动项目,代码修改后不会自动重启,需手动停止 / 重新执行 生产环境、简单测试 +dev:nodemon index.js 用 nodemon 启动项目,监控文件变化(如 index.js 改代码),自动重启服务 开发环境(日常写代码) + +用nodemon运行index.js:npm run dev + +## 关键知识 + +1. package.json:项目配置文件,记录依赖信息 +2. dependencies:生产依赖,项目运行必须的包 +3. devDependencies:开发依赖,仅开发时需要的包 + + +# 练习 + +## 选择题 + +1. package.json中,哪个字段用于记录项目运行必需的依赖? + - B. dependencies + +2. 版本号"^4.18.0"表示安装什么版本? + - B. 安装4.x.x最新版本 + +3. 下面哪个命令可以查看npm的镜像源设置? + - B. npm config get registry + +4. 安装全局包的参数是? + - C. --global + - D. -g + +6. yarn相比npm有什么特点? + - B. 支持离线安装 + +7. pnpm的主要特点是什么? + - B. 节省磁盘空间 + + +## 简答题 + +1. 请解释dependencies和devDependencies的区别。 + +- dependencies:生产依赖,项目运行必须的包 +- devDependencies:开发依赖,仅开发时需要的包 + +2. 什么是语义化版本号?请举例说明 "^1.2.3" 的含义。 + +- 语义化版本号是一种用于标识软件版本的标准化命名方式,它通过‌主版本号.次版本号.修订号的格式来明确表达软件的变更类型和兼容性 +- "^1.2.3"指的是安装1.x.x最新版本 + +3. 为什么国内使用npm需要配置镜像源? + +- 因为npm默认从国外下载,运行速度慢 + +4. 请描述npm install命令的执行过程。 + +- ‌读取依赖配置‌:npm 首先读取 package.json 文件,获取项目所需的依赖包及其版本信息。 + +- ‌解析依赖树‌:根据 package.json 和 package-lock.json(如果存在),npm 解析出完整的依赖关系树,确保版本兼容性。 + +- ‌下载并安装包‌:从 npm registry 下载所需的包,并将它们安装到 node_modules 目录中。若本地已有缓存,则直接使用缓存内容。 + +- ‌执行生命周期脚本‌:在安装过程中,会执行包中定义的 preinstall、install 和 postinstall 等脚本。 + +- ‌更新依赖锁文件‌:安装完成后,npm 会更新 package-lock.json 文件,确保依赖版本的一致性。 + +- ‌创建可执行链接‌:将包中的可执行文件链接到 node_modules/.bin/ 目录,方便在脚本中调用。 + +这个过程保证了项目依赖的正确安装和一致性。 + +5. 全局安装和本地安装有什么区别? + + + +6. yarn和npm相比有什么优势? + +7. pnpm的node_modules结构有什么特点?为什么能节省空间? +asstar-x.github.io + diff --git "a/\351\273\204\350\264\235\347\204\266/20260311-\346\250\241\345\235\227\347\256\241\347\220\206.md" "b/\351\273\204\350\264\235\347\204\266/20260311-\346\250\241\345\235\227\347\256\241\347\220\206.md" new file mode 100644 index 0000000000000000000000000000000000000000..6d92a4b32bbc974c672f62bb85555375587e9982 --- /dev/null +++ "b/\351\273\204\350\264\235\347\204\266/20260311-\346\250\241\345\235\227\347\256\241\347\220\206.md" @@ -0,0 +1,137 @@ +# 笔记 + +## 原因 + +- 在实际项目中,代码量会越来越大。如果把所有代码都写在一个文件中: + +- 代码难以阅读 +- 变量名容易冲突 +- 难以维护和修改 + +### 好处 + +在实际项目中,代码量会越来越大。如果把所有代码都写在一个文件中: + +- 代码复用 +- 便于维护 +- 命名空间 +- 清晰结构 + +## 模块系统 + +### CommonJs模块系统 + +- CommonJS是Node.js默认的模块系统,使用 `require()` 引入模块,使用 `module.exports` 导出模块。 + + +#### CommonJs导出方式 + +```javascript +// 方式1:导出单个函数或值 +module.exports = function() { + console.log('这是一个函数'); +}; + +// 方式2:导出对象(包含多个功能) +module.exports = { + add: function(a, b) { + return a + b; + }, + name: '张三', + PI: 3.14159 +}; + +// 方式3:直接给exports添加属性 +exports.add = function(a, b) { return a + b; }; +exports.subtract = function(a, b) { return a - b; }; +``` + +> **重要区别**: +> - `module.exports` 是真正的导出对象 +> - `exports` 只是 `module.exports` 的别名 +> - 不要直接给 `exports` 赋值,否则会切断引用关系! + + + +- 最好使用方法二 + +#### CommonJs引入方式 + +```javascript +// 引入自定义模块(相对路径或绝对路径) +const myModule = require('./myModule'); +const math = require('./math'); + +// 引入Node.js内置模块(直接写模块名) +const fs = require('fs'); +const path = require('path'); + +// 引入npm包(直接写包名) +const express = require('express'); +``` + +### ES Modules模块系统 + +- ES Modules(ESM)是JavaScript官方的模块系统,从ES6引入。需要在 `package.json` 中设置 `"type": "module"` 或者使用 `.mjs` 扩展名。 + +#### ES Modules导出方式 + +```javascript +// 方式1:命名导出(可导出多个) +export const name = '张三'; +export function add(a, b) { return a + b; } +export function subtract(a, b) { return a - b; } + +// 方式2:批量导出 +const multiply = (a, b) => a * b; +const divide = (a, b) => a / b; +export { multiply, divide }; + +// 方式3:默认导出(一个模块只能有一个) +export default function() { + console.log('默认导出'); +} +``` + +#### ES Modules引入方式 + +```javascript +// 引入命名导出 +import { add, subtract } from './math.mjs'; +console.log(add(2, 3)); // 5 + +// 引入并重命名 +import { add as sum } from './math.mjs'; +console.log(sum(1, 2)); // 3 + +// 引入默认导出 +import myFunc from './math.mjs'; +myFunc(); + +// 引入所有(作为对象属性) +import * as math from './math.mjs'; +console.log(math.add(1, 2)); // 3 +``` + +### 两种模块区别 + +| 特性 | CommonJS | ES Modules | +|------|----------|------------| +| 引入方式 | `require()` | `import` | +| 导出方式 | `module.exports` | `export` | +| 加载方式 | 同步加载 | 异步加载 | +| 解析时机 | 运行时解析 | 编译时确定 | +| 使用场景 | Node.js服务端 | 前端/现代Node.js | +| 扩展名 | `.js` | `.mjs` 或配置 | + +#### 使用建议 + +| 场景 | 推荐 | +|------|------| +| 新项目 | ES Modules | +| Node.js服务端 | CommonJS或ESM | +| 需要兼容旧代码 | CommonJS | +| 前端框架项目 | ES Modules | + +#### Node.js支持两种模块系统共存 + diff --git "a/\351\273\204\350\264\235\347\204\266/20260312-\346\267\273\345\212\240\350\267\237\345\210\240\351\231\244.md" "b/\351\273\204\350\264\235\347\204\266/20260312-\346\267\273\345\212\240\350\267\237\345\210\240\351\231\244.md" new file mode 100644 index 0000000000000000000000000000000000000000..279e777131c3a1ca70e3e9a3a2a8a8067b732177 --- /dev/null +++ "b/\351\273\204\350\264\235\347\204\266/20260312-\346\267\273\345\212\240\350\267\237\345\210\240\351\231\244.md" @@ -0,0 +1,83 @@ +# 笔记 + +```javascript + +/* + 待办事项是一个数组:[] + 最终会将其序列化后,写入一个文件,一个json文件 + 读取的时候,将其文件呢绒全部读出,并反序列化,又得到一个数组 +*/ + + +// 导入模块,前面的fs为自定义名字,后面的fs 是 Node.js 的内置文件系统模块(File System) + +import fs from 'fs' + + +// 取值,process.argv获取命令行参数 +/* + 如:你在终端输入node app.js add 吃饭睡觉打豆豆 + + process.argv的值为 + [ + 'node的路径', + 'app.js的路径', + 'add', + '吃饭睡觉打豆豆' + ] +*/ +let command = process.argv[2]; +let params = process.argv[3]; + +if (command == 'list') { + console.log('列表'); + let list = readFile(); + console.log(list); + +}else if(command == 'add'){ + console.log("添加"); + // 先将整个待办事项数组读出来 + let arr = readFile(); + + // 在那个数组中push一个待办事项 + arr.push({ 'title': params, 'isDone': false}); + // 将这个push后的数组写回文件 + writeFile(arr); + let newArr = readFile(); + console.log(newArr); +}else if (command == 'del') { + console.log('删除'); + let idx=parseInt(params); + let delArr = readFile(); + delArr.splice(idx-1,1); + writeFile(delArr); +} else if (command == 'done') { + console.log('标记完成'); +} else if (command == 'clear') { + console.log('清除'); +} else { + console.log('未知命令,请确认后重试'); + +} + +function readFile(filePath) { + // 调用你传的文件路径,否则默认为way + filePath = filePath || './way.json'; + if (fs.existsSync(filePath)) { + let data = fs.readFileSync(filePath, 'utf-8'); + + return JSON.parse(data) || []; + } + return []; +} + +function writeFile(fileContent, filePath) { + filePath = filePath || './way.json'; + let jsonString = JSON.stringify(fileContent); + fs.writeFileSync(filePath, jsonString); +} + +``` + + + diff --git "a/\351\273\204\350\264\235\347\204\266/20260913.md" "b/\351\273\204\350\264\235\347\204\266/20260913.md" new file mode 100644 index 0000000000000000000000000000000000000000..0734f4413057d2108729e2be2681602cacb92faf --- /dev/null +++ "b/\351\273\204\350\264\235\347\204\266/20260913.md" @@ -0,0 +1,8 @@ +```javascript +const readline = require('readline'); + +const rl = readline.createInterface({ + input: process.stdin, + output: process.stdout +}); +``` \ No newline at end of file