From dd85112f3421bd060f5eb80c325369ba2d4e6e51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E6=81=A9=E7=94=9F?= <2156286470@qq.com> Date: Sun, 15 Mar 2026 21:24:09 +0800 Subject: [PATCH] =?UTF-8?q?=E6=8F=90=E4=BA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...05\347\256\241\347\220\206\346\240\270.md" | 179 ++++++++++++ ...41\345\235\227\347\263\273\347\273\237.md" | 170 +++++++++++ ...44\350\241\214\345\267\245\345\205\267.md" | 132 +++++++++ ...0\345\260\217\351\241\271\347\233\256..md" | 270 ++++++++++++++++++ 4 files changed, 751 insertions(+) create mode 100644 "\351\231\210\346\201\251\347\224\237/20260309-NPM \344\270\216\345\214\205\347\256\241\347\220\206\346\240\270.md" create mode 100644 "\351\231\210\346\201\251\347\224\237/20260311-\346\250\241\345\235\227\347\263\273\347\273\237.md" create mode 100644 "\351\231\210\346\201\251\347\224\237/20260312-\345\221\275\344\273\244\350\241\214\345\267\245\345\205\267.md" create mode 100644 "\351\231\210\346\201\251\347\224\237/20260313-\345\221\275\344\273\244\350\241\214\345\267\245\345\205\267\345\256\236\346\210\230\345\260\217\351\241\271\347\233\256..md" diff --git "a/\351\231\210\346\201\251\347\224\237/20260309-NPM \344\270\216\345\214\205\347\256\241\347\220\206\346\240\270.md" "b/\351\231\210\346\201\251\347\224\237/20260309-NPM \344\270\216\345\214\205\347\256\241\347\220\206\346\240\270.md" new file mode 100644 index 00000000..c746ff17 --- /dev/null +++ "b/\351\231\210\346\201\251\347\224\237/20260309-NPM \344\270\216\345\214\205\347\256\241\347\220\206\346\240\270.md" @@ -0,0 +1,179 @@ +# 笔记部分 + +## 一、核心基础 + +### 1.1 什么是 NPM + +Node.js 内置包管理工具,全球最大开源包注册表,核心功能:管理依赖、标准化发布、简化构建、保障多环境一致。 + +* 验证安装:`npm -v`(版本)、`npm -h`(帮助) + +### 1.2 核心文件 / 目录 + +| 名称 | 核心作用 | +| -| -| +| `package.json` | 项目配置核心(元信息、依赖、脚本) | +| `package-lock.json` | 锁定依赖版本,禁止手动修改 | +| `node_modules/` | 存放依赖,需加入 `.gitignore` | +| `.npmrc` | 自定义镜像源、缓存等配置 | + +### 1.3 依赖类型 + +* **dependencies**(生产依赖):`npm i react` + +* **devDependencies**(开发依赖):`npm i webpack -D` + +* **peerDependencies**(对等依赖):需用户手动安装兼容版本 + +* **optionalDependencies**(可选依赖):安装失败不影响运行 + +## 二、常用命令(核心) + +### 2.1 项目与依赖 + +| 操作 | 命令 | +| - | - | +| 快速初始化 | `npm init -y` | +| 安装所有依赖 | `npm i` | +| 安装生产依赖 | `npm i 包名` | +| 安装开发依赖 | `npm i 包名 -D` | +| 安装指定版本 | `npm i 包名@版本` | +| 全局安装 | `npm i 包名 -g` | +| 卸载依赖 | `npm un 包名`(-D 卸载开发依赖) | +| 更新依赖 | `npm up 包名`(无包名更新所有) | + +### 2.2 脚本与发布 + +``` +// package.json 脚本示例 + +{ + + "scripts": { + + "start": "node index.js", + + "dev": "nodemon index.js", + + "build": "webpack --mode production" + +} + +} +``` + +* 运行脚本:`npm run 脚本名`(start/test 可简写:`npm start`) + +* 发布包:`npm login` → `npm publish`(测试版:`npm publish --tag beta`) + +* 版本递增:`npm version patch/minor/major`(补丁 / 次 / 主版本) + +## 三、语义化版本(SemVer) + +### 3.1 版本格式 + +`X.Y.Z`(主版本。次版本。补丁版本): + +* X:不兼容 API 变更 + +* Y:向后兼容功能新增 + +* Z:向后兼容问题修复 + +### 3.2 版本范围符号 + +| 符号 | 示例 | 允许范围 | +| - | - | - | +| ^ | ^1.2.3 | 1.x.x(次版 + 补丁版更新) | +| \~ | \~1.2.3 | 1.2.x(仅补丁版更新) | +| 无 | 1.2.3 | 固定版本 | +| \* | \* | 最新版本(不推荐) | + +## 四、优化与工具 + +### 4.1 NPM 优化 + +* 切换镜像源:`npm config set registry ``https://registry.npmmirror.com` + +* 清理缓存:`npm cache clean --force` + +### 4.2 其他工具对比 + +| 工具 | 核心优势 | 适用场景 | +| - | - | - | +| NPM | 内置、兼容好 | 基础项目、新手 | +| Yarn | 并行安装、稳定锁文件 | 中大型项目、团队协作 | +| PNPM | 速度最快、磁盘占用小 | 大型项目、Monorepo | + +## 五、常见问题 + +1. 安装失败:换镜像 → 清缓存 → 删除 `node_modules`+`package-lock.json` 重试 + +2. 版本冲突:`npm ls 包名` 查依赖树 → 锁定版本或用 `resolutions` 字段 + +3. 全局包不可用:`npm config get prefix` → 将路径添加到系统 PATH + + + +# 练习部分 + +## 简答题 + +### 1. 请解释 dependencies 和 devDependencies 的区别。 + +* **dependencies(生产依赖)**:项目运行时必需的依赖(如 React、Vue),打包发布后仍需存在。 + +* **devDependencies(开发依赖)**:仅开发 / 构建阶段使用的依赖(如 Webpack、ESLint),不影响项目运行,打包时可剔除。 + +### 2. 什么是语义化版本号?请举例说明 "^1.2.3" 的含义。 + +* 语义化版本号(SemVer)是规范的版本格式,格式为 `X.Y.Z`(主版本。次版本。补丁版本): + + * X:不兼容的 API 变更;Y:向后兼容的功能新增;Z:向后兼容的问题修复。 + +* `^1.2.3` 含义:允许次版本和补丁版本更新,即兼容 `1.x.x` 系列(如 1.2.4、1.5.0),不兼容 2.0.0 及以上。 + +### 3. 为什么国内使用 npm 需要配置镜像源? + +* NPM 默认镜像源([https://registry.np](https://registry.npmjs.org/)[mjs](https://registry.npmjs.org/)[.or](https://registry.npmjs.org/)[g/](https://registry.npmjs.org/))位于国外,国内访问时网络延迟高、下载速度慢,甚至出现连接超时; + +* 配置国内镜像源(如淘宝镜像 [https://registry.npm](https://registry.npmmirror.com)[mir](https://registry.npmmirror.com)[ror](https://registry.npmmirror.com)[.com](https://registry.npmmirror.com))可大幅提升依赖安装速度,保障安装稳定性。 + +### 4. 请描述 npm install 命令的执行过程。 + +1. 读取项目根目录的 `package.json`,获取依赖清单及版本范围; + +2. 结合 `package-lock.json` 锁定的精确版本,解析依赖树(含子依赖); + +3. 从配置的镜像源下载对应版本的依赖包; + +4. 将下载的依赖包解压到 `node_modules` 目录; + +5. 若不存在 `package-lock.json`,则自动生成(记录安装的精确版本、依赖树等信息)。 + +### 5. 全局安装和本地安装有什么区别? + +* **本地安装**:依赖安装到当前项目的 `node_modules` 目录,仅当前项目可用,命令需通过 `npm run` 调用,适用于项目专属依赖; + +* **全局安装**:依赖安装到系统全局目录(通过 `npm config get prefix` 查看),所有项目可共用,可直接在命令行调用(如 nodemon),适用于工具类依赖(如脚手架、编译器)。 + +### 6. yarn 和 npm 相比有什么优势? + +* 安装速度更快:支持并行下载依赖,减少等待时间; + +* 依赖一致性更强:锁文件(yarn.lock)格式更稳定,跨环境安装时能保证依赖版本完全一致; + +* 支持离线缓存:已下载的依赖会缓存到本地,再次安装无需重复下载; + +* 命令更简洁:如 `yarn add` 等价于 `npm install`,`yarn dev` 等价于 `npm run dev`。 + +### 7. pnpm 的 node\_modules 结构有什么特点?为什么能节省空间? + +* **结构特点**:采用 “硬链接 + 符号链接” 的存储方式,全局维护一个共享的依赖存储池,项目的 `node_modules` 中仅存放符号链接,指向共享存储池中的实际依赖文件; + +* **节省空间原因**:相同版本的依赖在全局仅存储一份,多个项目共用时无需重复复制,大幅减少磁盘占用(尤其多项目依赖相同包时,优势更明显)。 + + + + + diff --git "a/\351\231\210\346\201\251\347\224\237/20260311-\346\250\241\345\235\227\347\263\273\347\273\237.md" "b/\351\231\210\346\201\251\347\224\237/20260311-\346\250\241\345\235\227\347\263\273\347\273\237.md" new file mode 100644 index 00000000..0ff4ae92 --- /dev/null +++ "b/\351\231\210\346\201\251\347\224\237/20260311-\346\250\241\345\235\227\347\263\273\347\273\237.md" @@ -0,0 +1,170 @@ +# 笔记部分 + +## Node.js模块系统基础知识 + +### 一、模块系统核心概念 + +Node.js 中**每个文件就是一个独立模块**,模块内的变量、函数默认私有,需通过 “导出” 暴露,其他模块通过 “导入” 使用,核心目的是: + +* 避免全局变量污染 + +* 拆分代码、提高复用性 + +### 二、核心操作:导出(模块暴露内容) + +模块通过 `module.exports` 或 `exports` 暴露内容,两者本质关联(`exports = module.exports`),推荐优先用 `module.exports` 避免混淆。 + +#### 1. 导出单个内容(函数 / 对象 / 变量) + +``` +// 模块文件:utils.js + +const add = (a, b) => a + b; + +module.exports = add; // 暴露单个函数 +``` + +#### 2. 导出多个内容(对象形式) + +``` +// 模块文件:tools.js + +const multiply = (a, b) => a \* b; + +const subtract = (a, b) => a - b; + +// 方式1:直接赋值对象 + +module.exports = { + + multiply, + + subtract + +}; + +// 方式2:通过exports逐个添加(等价于上面) + +// exports.multiply = multiply; + +// exports.subtract = subtract; +``` + +### 三、核心操作:导入(使用其他模块) + +通过 `require('模块路径')` 导入模块,路径规则: + +* 本地模块:写相对路径(`./` 同级,`../` 上级),可省略 `.js` 后缀 + +* 内置模块(如 `fs`、`path`):直接写模块名,无需路径 + +* 第三方模块(npm 安装):直接写模块名 + +#### 1. 导入单个内容 + +``` +// 导入utils.js的add函数 + +const add = require('./utils'); + +console.log(add(2, 3)); // 输出:5 +``` + +#### 2. 导入多个内容(解构赋值) + +``` +// 导入tools.js的多个方法 + +const { multiply, subtract } = require('./tools'); + +console.log(multiply(2, 3)); // 输出:6 + +console.log(subtract(5, 2)); // 输出:3 +``` + +#### 3. 导入内置模块示例 + +``` +// 导入Node.js内置模块fs(文件系统) + +const fs = require('fs'); + +// 简单使用:读取文件(同步) + +const content = fs.readFileSync('./test.txt', 'utf8'); + +console.log(content); +``` + +### 四、关键注意点 + +1. `exports`** 不能直接赋值对象**:因为 `exports` 是 `module.exports` 的引用,直接赋值会断开关联,导致导出失效: + +``` +// 错误写法:导出无效 + +exports = { multiply, subtract }; + +// 正确写法 + +module.exports = { multiply, subtract }; +``` + +1. **模块缓存**:同一模块被多次 `require` 时,仅首次执行并缓存结果,后续直接返回缓存,避免重复执行。 + +2. **路径规则**:本地模块必须带路径(`./` 或 `../`),否则 Node.js 会当作内置模块或第三方模块查找。 + + + +## 练习 + +### 选择题 + +1. 在CommonJS模块系统中,引入模块使用哪个关键字? + - A. import + - **B. require** + - C. include + - D. load + +2. 以下哪个是正确的CommonJS导出方式? + - A. export const add = ... + - B. exports = ... + - **C. module.exports = ...** + - D. export default ... + +3. ES Modules需要什么配置才能在Node.js中使用? + - A. 设置 "type": "commonjs" + - **B. 设置 "type": "module"** + - C. 安装es-modules包 + - D. 无需任何配置 + +4. 下面的代码有什么问题? + ```javascript + exports = function() { console.log('hello'); }; + ``` + - A. 没有问题 + - **B. 应该是 module.exports** + - C. 应该加括号 + - D. 应该是 export default + +5. 以下哪个不是模块化的好处? + - A. 代码复用 + - **B. 变量名冲突** + - C. 便于维护 + - D. 清晰结构 + +### 简答题 + +1. 什么是模块?为什么要使用模块? +**模块:Node.js 中每个文件是独立模块,内部成员默认私有,需导出才能被外部访问。使用原因:避免全局污染、拆分代码、提高复用性、便于维护。** +2. 请解释module.exports和exports的区别。 +**exports 是 module.exports 的引用,最终导出以 module.exports 为准;exports 不能直接赋值(会断关联),module.exports 可直接赋值或批量导出。** +3. CommonJS和ES Modules有什么区别? +**语法(CommonJS 用 require/module.exports,ESM 用 import/export);Node.js 启用(ESM 需设 "type": "module");加载机制(CommonJS 运行时同步,ESM 编译时异步)。** +4. Node.js加载模块的顺序是怎样的? +**先查缓存→加载内置模块(优先级最高)→第三方模块(递归查找 node_modules)→本地模块(按相对路径查找)→执行后缓存。** +5. 什么是模块作用域?它有什么作用? +**模块作用域:每个模块的独立作用域,内部成员默认仅自身可访问。作用:隔离变量污染、隐藏内部实现、明确模块职责。** + + + diff --git "a/\351\231\210\346\201\251\347\224\237/20260312-\345\221\275\344\273\244\350\241\214\345\267\245\345\205\267.md" "b/\351\231\210\346\201\251\347\224\237/20260312-\345\221\275\344\273\244\350\241\214\345\267\245\345\205\267.md" new file mode 100644 index 00000000..bebd3733 --- /dev/null +++ "b/\351\231\210\346\201\251\347\224\237/20260312-\345\221\275\344\273\244\350\241\214\345\267\245\345\205\267.md" @@ -0,0 +1,132 @@ +# 笔记部分 + +## Node.js 命令行工具基础(核心知识点) + +### 一、核心结构(2 个文件) + +``` +cli-tool/ + +├─ index.js # 命令行入口(参数解析) + +└─ utils.js # 功能逻辑封装 +``` + +### 二、基础实现 + +#### 1. 功能逻辑 `utils.js`(模块化封装) + +``` +// 示例功能(可替换) + +const doSomething = (param) => { + + return \`执行功能:\${param || '默认操作'}\`; + +}; + +module.exports = { doSomething }; // 导出方法 +``` + +#### 2. 入口文件 `index.js`(参数解析核心) + +``` +const { doSomething } = require('./utils'); + +const args = process.argv.slice(2); // 截取用户参数(跳过node和文件路径) + +const command = args\[0]; + +const params = args.slice(1); + +// 命令映射 + +switch (command) { + + case 'run': + + console.log(doSomething(params.join(' '))); + + break; + + case 'help': + + console.log('用法:node index.js run \[参数]'); + + break; + + default: + + console.log('未知命令,输入 node index.js help 查看用法'); + +} +``` + +### 三、核心知识点 + +1. **参数解析**:`process.argv` 获取命令行参数,`slice(2)` 过滤无用项; + +2. **模块化**:`module.exports` 导出功能,`require` 导入模块; + +3. **文件操作基础**(可选扩展):`fs.readFileSync`/`fs.writeFileSync` 同步读写文件; + +4. **JSON 处理**(可选扩展):`JSON.parse`/`JSON.stringify` 处理数据存储。 + +### 四、使用示例 + +``` +node index.js run "测试参数" + +node index.js help +``` + +# 练习 + +### 6.1 选择题 + +1. Node.js中,获取命令行参数的属性是? + + * A. process.args + * **B. process.argv** + * C. process.params + * D. process.args +2. 以下哪个命令可以读取文件内容? + + * A. fs.writeFile + * **B. fs.readFile** + * C. fs.appendFile + * D. fs.copyFile +3. `__dirname` 表示什么? + + * A. 当前文件的完整路径 + * **B. 当前文件所在目录** + * C. 脚本运行时目录 + * D. Node.js安装目录 +4. package.json中,哪个字段用于配置全局命令? + + * A. main + * B. scripts + * **C. bin** + * D. dependencies +5. 下面哪个不是命令行工具的优点? + + * A. 自动化批量处理 + * **B. 图形界面更美观** + * C. 部署便捷 + * D. 提高效率 + +### 6.2 简答题 + +1. 请解释什么是CLI工具?它和GUI有什么区别? + +2. process.argv返回的数组包含哪些内容? + +3. 请说明fs.readFileSync和fs.readFile的区别。 + +4. 为什么要使用JSON文件存储数据?有什么优缺点? + +5. 如何让开发的CLI工具可以全局使用? + + + + diff --git "a/\351\231\210\346\201\251\347\224\237/20260313-\345\221\275\344\273\244\350\241\214\345\267\245\345\205\267\345\256\236\346\210\230\345\260\217\351\241\271\347\233\256..md" "b/\351\231\210\346\201\251\347\224\237/20260313-\345\221\275\344\273\244\350\241\214\345\267\245\345\205\267\345\256\236\346\210\230\345\260\217\351\241\271\347\233\256..md" new file mode 100644 index 00000000..7c1d3faf --- /dev/null +++ "b/\351\231\210\346\201\251\347\224\237/20260313-\345\221\275\344\273\244\350\241\214\345\267\245\345\205\267\345\256\236\346\210\230\345\260\217\351\241\271\347\233\256..md" @@ -0,0 +1,270 @@ +```js +import fs from 'fs'; + +import readline from 'readline'; + +const file_name = 'tool.json'; + +const rl = readline.createInterface({ + + input: process.stdin, + + output: process.stdout + +}); + + +function loadtool() { + + if (!fs.existsSync(file_name)) { + + return []; + + } + + + + try { + + const data = fs.readFileSync(file_name, 'utf-8'); + + const parsed = JSON.parse(data); + + return Array.isArray(parsed) ? parsed : []; + + } catch (error) { + + console.error('读取数据文件时出错:', error.message); + + return []; + + } + +} + + +function savetool(tools) { + + fs.writeFileSync(file_name, JSON.stringify(tools, null, 2)) + +} + + + +function Menu() { + + console.log('\n--- 简易待办事项管理系统 ---'); + + console.log('1. 查看所有任务'); + + console.log('2. 添加新任务'); + + console.log('3. 标记任务为完成'); + + console.log('4. 删除任务'); + + console.log('5. 退出'); + + console.log('---------------------------'); + + rl.question('请选择操作 (1-5): ', handleMenuChoice); + +} + + + +function handleMenuChoice(choice) { + + const test = loadtool(); + + console.log(test); + + + + switch (choice.trim()) { + + case '1': + + listTool(test); + + break; + + + + case '2': + + addTool(test); + + break; + + + + case '3': + + completeTool(test); + + break; + + + + case '4': + + delTool(test); + + break; + + + + case '5': + + rl.close(); + + process.exit(0); + + break; + + default: + + Menu(); + + } + +} + + + +function listTool(test) { + + console.log('\n当前任务列表:'); + + test.forEach((todo, index) => { + + const status = todo.completed ? '[x]' : '[ ]'; + + console.log(`${index + 1}. ${status} ${todo.text}`); + + }); + + + + Menu(); + +} + + + +function addTool(test) { + + rl.question('请输入任务:', (text) => { + + const newTool = { + + text: text.trim(), + + completed: false, + + createdAt: new Date().toISOString() + + } + + + + test.push(newTool); + + savetool(test); + + console.log('任务已添加!'); + + Menu(); + + }); + +} + + + +function completeTool(test) { + + if (test.length === 0) { + + console.log("没有记录!"); + + Menu(); + + return; + + } + + + + rl.question('请输入编号:', (input) => { + + const index = parseInt(input) - 1; + + if (isNaN(index) || index < 0 || index >= test.length) { + + console.log('无效的编号!'); + + Menu(); + + return; + + } + + test[index].completed = true; + + savetool(test); + + console.log('任务已标记为完成!'); + + Menu(); + + }); + +} + + + +function delTool(test) { + + if (test.length === 0) { + + console.log("没有记录!"); + + Menu(); + + return; + + } + + + + rl.question('请输入编号:', (input) => { + + const index = parseInt(input) - 1; + + if (isNaN(index) || index < 0 || index >= test.length) { + + console.log('无效的编号!'); + + Menu(); + + return; + + } + + const del = test.splice(index, 1); + + savetool(test); + + console.log('任务已删除!'); + + Menu(); + + }); + +} + + +Menu(); +``` \ No newline at end of file -- Gitee