diff --git "a/\346\235\216\351\233\250\347\277\224/20260306-\345\210\235\350\257\206Nodejs.md" "b/\346\235\216\351\233\250\347\277\224/20260306-\345\210\235\350\257\206Nodejs.md" new file mode 100644 index 0000000000000000000000000000000000000000..5a300e040e4aae93640672b6eb059246cd092db2 --- /dev/null +++ "b/\346\235\216\351\233\250\347\277\224/20260306-\345\210\235\350\257\206Nodejs.md" @@ -0,0 +1,77 @@ +## 初识Node.js + +### Node.js核心特性 +#### 单线程(Single Thread) +Node.js使用单线程执行代码,不像传统服务器(如Java、PHP)那样为每个请求创建新线程。 + + - 优点: + + - 节省内存资源 + - 不存在线程切换开销 + - 编程模型简单 + - 缺点: + + - 无法利用多核CPU + - 计算密集型任务会阻塞 + +#### 非阻塞I/O(Non-blocking I/O) +当程序需要读取文件、查询数据库时,Node.js不会等待结果,而是继续执行其他代码 + +对比示例: +``` +// 阻塞式(传统方式) +const data = fs.readFileSync('file.txt'); // 等待完成! +console.log(data); + +// 非阻塞式(Node.js方式) +fs.readFile('file.txt', (err, data) => { + console.log(data); // 文件就绪后执行 +}); +console.log('继续执行其他代码'); // 这行先执行! +``` + +#### 事件驱动(Event-driven) +Node.js通过事件和回调函数来处理异步操作。 + +### 练习 +Node.js是基于哪个JavaScript引擎开发的? +V8 + +以下哪个不是Node.js的核心特性? +多线程 + +Node.js最适合开发以下哪种应用? +实时聊天系统 + +以下哪个是Node.js的创始人? +Ryan Dahl + +Node.js中的"I/O"主要指什么? + Input/Output(输入/输出) + +什么是Node.js?请用一句话概括。 +基于Chrome V8引擎的JavaScript运行时,让JavaScript可以脱离浏览器在服务器端运行。 + +请解释"非阻塞I/O"是什么意思,它有什么优点? + 运行这段代码可以不进行等待直接执行下一步功能,有点性能可以完全释放加快运行速度 + +为什么Node.js适合开发实时聊天应用? +Node.js 因其速度、 可扩展性 和可靠性 + +请列举Node.js的3个应用场景。 +1. 实时聊天应用 +2. 全栈开发 +3. 快速实现功能 + +Node.js和传统后端语言(如Java、PHP)相比,有什么优势? +实现简单,学习成本低,易上手 + +访问Node.js官网(https://nodejs.org),截图当前页面上的LTS版本号。![alt text](img/image.png) + +查找并记录3个使用Node.js开发的知名网站或应用。 +1. Uber +2. GitHub +3. 淘宝 + +如果你要开发一个"在线考试系统",考虑是否适合使用Node.js?说明理由 +适合,因为适合个人独立开发并且学习速度快易上手 diff --git "a/\346\235\216\351\233\250\347\277\224/20260309-npm\344\270\216\345\214\205\347\256\241\347\220\206.md" "b/\346\235\216\351\233\250\347\277\224/20260309-npm\344\270\216\345\214\205\347\256\241\347\220\206.md" new file mode 100644 index 0000000000000000000000000000000000000000..57fa696125163ff4592ca7fcd43b19c838feffe5 --- /dev/null +++ "b/\346\235\216\351\233\250\347\277\224/20260309-npm\344\270\216\345\214\205\347\256\241\347\220\206.md" @@ -0,0 +1,369 @@ +## npm与包管理 + +```cmd +# 初始化项目 +$ npm init -y + +# 安装express框架 +$ npm install express + +# 安装开发依赖 +$ npm install --save-dev nodemon + +# 查看已安装的包 +$ npm list + +# 运行项目 +$ npm start +``` +```json +// package.json +{ + "name": "my-app", + "version": "1.0.0", + "dependencies": { + "express": "^4.18.0" + }, + "devDependencies": { + "nodemon": "^3.0.0" + } +} +``` + + +### package.json详解 +#### 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常用命令 +#### npm常用命令 +```cmd +# 交互式初始化(会询问项目信息) +npm init + +# 使用默认配置初始化(快速) +npm init -y + +# 指定项目信息初始化 +npm init --yes +``` +#### 安装包 +``` +# 安装到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 +``` +#### 管理和查看 +``` +# 查看已安装的包 +npm list + +# 查看已安装的包(显示顶层) +npm list --depth=0 + +# 查看某个包的版本信息 +npm view express version + +# 查看某个包的所有版本 +npm view express versions + +# 查看包的信息 +npm view express +``` + +#### 更新和卸载 +``` +# 更新包 +npm update <包名> + +# 更新所有依赖 +npm update + +# 卸载包 +npm uninstall <包名> +npm remove <包名> +``` + +#### npm脚本 +``` +# 运行package.json中定义的脚本 +npm run <脚本名> + +# 常用简写 +npm start # npm run start +npm test # npm run test +npm stop # npm run stop +``` + + +### Yarn与pnpm +#### Yarn是由Facebook开发的包管理器,特点是速度快、离线安装、确定性安装。 +``` +# 安装Yarn +npm install -g yarn + +# 初始化项目 +yarn init + +# 安装依赖 +yarn add <包名> # 生产依赖 +yarn add <包名> --dev # 开发依赖 +yarn add <包名> -D # 简写 + +# 全局安装 +yarn global add <包名> + +# 卸载 +yarn remove <包名> + +# 运行脚本 +yarn <脚本名> +yarn start + +# 查看依赖 +yarn list +yarn outdated + +``` + +#### pnpm是由pnpm公司开发的包管理器,特点是节省磁盘空间、更快、更安全。 +``` +# 安装pnpm +npm install -g pnpm + +# 初始化项目 +pnpm init + +# 安装依赖 +pnpm add <包名> # 生产依赖 +pnpm add -D <包名> # 开发依赖 + +# 全局安装 +pnpm add -g <包名> + +# 卸载 +pnpm remove <包名> + +# 运行脚本 +pnpm <脚本名> +pnpm start + +# 查看依赖 +pnpm list +pnpm outdated +``` + + +### 使用淘宝镜像 + +``` +# 方式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 - 镜像源管理工具 +nrm可以快速切换不同的镜像源: +``` +# 全局安装nrm +npm install -g nrm + +# 查看可用镜像源 +nrm ls + +# 切换到淘宝镜像 +nrm use taobao + +# 切换到官方镜像 +nrm use npm +``` + + +## 练习 +package.json中,哪个字段用于记录项目运行必需的依赖? +dependencies + +版本号"^4.18.0"表示安装什么版本? +安装4.x.x最新版本 + +下面哪个命令可以查看npm的镜像源设置? +npm config get registry + +安装全局包的参数是? +--global -g + +npm install 和 npm ci 有什么区别? + npm ci更快,适合CI/CD环境 + +yarn相比npm有什么特点? +支持离线安装 + +pnpm的主要特点是什么? +节省磁盘空间 + +请解释dependencies和devDependencies的区别。 + +dependencies是生产环境 +devDependencies是开发环境 +什么是语义化版本号?请举例说明 "^1.2.3" 的含义。 +^,~,*等版本符号的含义,^1.2.3包含1.x.x的最新版本 + +为什么国内使用npm需要配置镜像源? +因为初始下载的是国外的镜像源会因为下载的镜像源在国外而下载缓慢,所以要配置镜像源 + +请描述npm install命令的执行过程。 +执行npm install 命令后会在镜像那下载npm的包 + +全局安装和本地安装有什么区别? +全局安装是将依赖或工具安装到计算机的全局环境中,本地安装是将依赖安装到当前项目node_modules 文件夹中 + +yarn和npm相比有什么优势? +下载速度快,可以在无网时安装 + +pnpm的node_modules结构有什么特点?为什么能节省空间? +pnpm 是一种高效的包管理工具,它通过独特的 node_modules 结构来解决传统 npm 和 Yarn 的一些问题,采用了一种虚拟存储目录的方式所以节省空间 + + + +创建项目:使用npm init创建一个新项目,添加项目名称为"my-blog",作者为你的名字。 +``` +{ + "name": "my-blog", + "version": "1.0.0", + "main": "index.js", + "scripts": { + "dev": "nodemon index.js", + "test": "echo \"Error: no test specified\" && exit 1" + }, + "keywords": [], + "author": "李雨翔", + "license": "ISC", + "description": "", + "dependencies": { + "express": "^5.2.1", + "nodemon": "^3.1.14" + } +} +``` +安装依赖:安装express框架作为生产依赖,安装nodemon作为开发依赖。 +``` +npm i 生产环境 +npm i -D 开发环境 +``` +查看信息:使用npm view命令查看express的最新版本和所有版本。 + +``` +npm view express + +express@5.2.1 | MIT | deps: 28 | versions: 287 +Fast, unopinionated, minimalist web framework +https://expressjs.com/ + +keywords: express, framework, sinatra, web, http, rest, restful, router, app, api + +dist +.tarball: https://registry.npmmirror.com/express/-/express-5.2.1.tgz +.shasum: 8f21d15b6d327f92b4794ecf8cb08a72f956ac04 +.integrity: sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw== +.unpackedSize: 75.4 kB + +dependencies: +accepts: ^2.0.0 fresh: ^2.0.0 +body-parser: ^2.2.1 http-errors: ^2.0.0 +content-disposition: ^1.0.0 merge-descriptors: ^2.0.0 +content-type: ^1.0.5 mime-types: ^3.0.0 +cookie-signature: ^1.2.1 on-finished: ^2.4.1 +cookie: ^0.7.1 once: ^1.4.0 +debug: ^4.4.0 parseurl: ^1.3.3 +depd: ^2.0.0 proxy-addr: ^2.0.7 +encodeurl: ^2.0.0 qs: ^6.14.0 +escape-html: ^1.0.3 range-parser: ^1.2.1 +etag: ^1.8.1 router: ^2.2.0 +finalhandler: ^2.1.0 send: ^1.1.0 +(...and 4 more.) + +maintainers: +- wesleytodd +- ulisesgascon +- jonchurch +- ctcpip +- sheplu + +dist-tags: +latest-4: 4.22.1 latest: 5.2.1 + +published 3 months ago by jonchurch +``` + + +配置脚本:在package.json中添加一个"dev"脚本,使用nodemon运行index.js。 + +``` +npm run dev + +> my-blog@1.0.0 dev +> nodemon index.js + +[nodemon] 3.1.14 +[nodemon] to restart at any time, enter `rs` +[nodemon] watching path(s): *.* +[nodemon] watching extensions: js,mjs,cjs,json +[nodemon] starting `node index.js` +[nodemon] clean exit - waiting for changes before restart +``` + +切换镜像:将npm镜像切换为淘宝镜像,然后安装一个包验证速度。 +``` +npm config set registry https://registry.npmmirror.com +``` +安装yarn:全局安装yarn,并使用yarn安装一个包体验速度。 +``` +npm i -g yarn +``` +安装pnpm:全局安装pnpm,并使用pnpm安装一个包,观察node_modules结构。 +``` +npm i -g pnpm +``` \ No newline at end of file diff --git "a/\346\235\216\351\233\250\347\277\224/20260311-\346\250\241\345\235\227\347\263\273\347\273\237.md" "b/\346\235\216\351\233\250\347\277\224/20260311-\346\250\241\345\235\227\347\263\273\347\273\237.md" new file mode 100644 index 0000000000000000000000000000000000000000..80c265454e504077d3efb0be3cfaa8a853d1d375 --- /dev/null +++ "b/\346\235\216\351\233\250\347\277\224/20260311-\346\250\241\345\235\227\347\263\273\347\273\237.md" @@ -0,0 +1,133 @@ +## 模块系统 +### CommonJs推荐使用 +``` +// 导出模块 - math.js +module.exports = { + add: (a, b) => a + b, + subtract: (a, b) => a - b +}; + +// 引入模块 - app.js +const math = require('./math'); +console.log(math.add(2, 3)); // 5 +``` + +### ES Modules推荐使用 +``` + // ES Modules - math.mjs + export const add = (a, b) => a + b; + + // ES Modules - app.mjs + import { add } from './math.mjs'; + console.log(add(2, 3)); // 5 +``` + +### 默认模块 +``` +export default function() { + console.log('默认导出'); +} +``` + + + +## 练习 +在CommonJS模块系统中,引入模块使用哪个关键字? +require + +以下哪个是正确的CommonJS导出方式? +module.exports = ... + +ES Modules需要什么配置才能在Node.js中使用? +设置 "type": "module" + +下面的代码有什么问题? +``` +exports = function() { console.log('hello'); }; +``` +应该是 module.exports + +以下哪个不是模块化的好处? +变量名冲突 + +什么是模块?为什么要使用模块? +模块:拆分成独立的文件类型,因为适合复用和维护 + +请解释module.exports和exports的区别。 +exports只是module.exports的引用 + +CommonJS和ES Modules有什么区别? +CommonJS: Node.js默认模块系统,使用require/module.exports +ES Modules: JavaScript官方模块系统,使用import/export + +Node.js加载模块的顺序是怎样的? +先加载内置模块 → 文件模块 → npm模块 + +什么是模块作用域?它有什么作用? +变量、函数等名字在模块中的可见性 + + +1. 创建模块:创建一个 stringUtils.js 模块,导出以下函数: + + - capitalize(str) - 首字母大写 + - reverse(str) - 反转字符串 + - trim(str) - 去除两端空格 + +### 操作题 +操作题 +创建模块:创建一个 stringUtils.js 模块,导出以下函数: + +capitalize(str) - 首字母大写 +reverse(str) - 反转字符串 +trim(str) - 去除两端空格 + +```js +export const capitalize = (str) => str[0].toUpperCase() + str.slice(1); + +export const reverse = (str) => { + let res = ''; + for(let i = str.length - 1;i >= 0;i--){ + res += str[i]; + } + return res; + +}; +export const trim = (str) => str.trim(); + + + + + +``` + +使用模块:创建 index.js,引入并测试 stringUtils.js 的所有函数。 +```js +console.log(capitalize('ab')); +console.log(reverse('ab')); +console.log(trim(' aa ')); +``` +模块封装:创建一个 Person 类,包含name、age属性和introduce方法,并在另一个文件中使用。 +```js +export default class Person{ + introduce(name,age){ + return `我的名字:${name}年龄:${age}` + } +} + +let p = new Person(); +console.log(p.introduce('a','a')); + +``` +模块加载实验:创建一个有循环引用的模块对,观察Node.js如何处理。 +```js +export const tes = () => { + let s = 0; + for(let i = 0;i <= 10;i++){ + s += i; + } + return s +} + +console.log(tes()); +``` +ES Modules尝试(选做):将项目改为使用ES Modules,创建 .mjs 文件并测试import/export。 diff --git "a/\346\235\216\351\233\250\347\277\224/20260312-\345\221\275\344\273\244\350\241\214\345\267\245\345\205\267.md" "b/\346\235\216\351\233\250\347\277\224/20260312-\345\221\275\344\273\244\350\241\214\345\267\245\345\205\267.md" new file mode 100644 index 0000000000000000000000000000000000000000..effecbdab99c51c0126f0c19018e2597bc1d157b --- /dev/null +++ "b/\346\235\216\351\233\250\347\277\224/20260312-\345\221\275\344\273\244\350\241\214\345\267\245\345\205\267.md" @@ -0,0 +1,372 @@ +## 综合实战:命令行工具 + - 命令行工具(CLI,Command Line Interface)是没有图形界面,通过终端输入命令来操作的程序。 + +### 为什么要开发命令行工具? +- 自动化:批量处理文件、数据 +- 提高效率:常用操作一键完成 +- 部署便捷:服务器上也能轻松使用 +- 技能锻炼:综合运用Node.js基础知识 + + +### 命令行参数处理 +```js +process.argv +获取命令行参数 +``` +读取文件 +```js +// 同步读取 +const data = fs.readFileSync('data.json', 'utf8'); + +// 异步读取 +fs.readFile('data.json', 'utf8', (err, data) => { + if (err) { + console.error('读取失败:', err); + return; + } + console.log('数据:', data); +}); +``` +写入文件 +```js +// 同步写入 +fs.writeFileSync('data.json', JSON.stringify({name: '张三'})); + +// 异步写入 +fs.writeFile('data.json', JSON.stringify({name: '张三'}), (err) => { + if (err) throw err; + console.log('写入成功'); +}); +``` + + + +Node.js中,获取命令行参数的属性是? +process.params + +以下哪个命令可以读取文件内容? +fs.readFile + +__dirname 表示什么? +当前文件所在目录 + +package.json中,哪个字段用于配置全局命令? + scripts + +下面哪个不是命令行工具的优点? +图形界面更美观 + +请解释什么是CLI工具?它和GUI有什么区别? +CIL 命令行工具,是没有图形化界面,通过终端输入命令来操作的程序 +GUI 图形化工具,通过界面图标点击来快速操作程序 + +process.argv返回的数组包含哪些内容? +返回的是我终端输入的内容 + +请说明fs.readFileSync和fs.readFile的区别。 +fs.readFileSync 同步读取内容 +fs.readFile 异步读取内容 + +为什么要使用JSON文件存储数据?有什么优缺点? +符合现代标准,优点:结构清晰,构造简单 缺点:不适合大规模数据 + +如何让开发的CLI工具可以全局使用? +以管理员运行CLI功能就可以全局使用 + +完善待办工具:完成本任务中的todo.js开发,并测试所有功能。 + + +完成本任务中的todo.js开发,并测试所有功能。 +```js + +#!/usr/bin/env node + +const fs = require('fs'); +const path = require('path'); + +// 数据文件路径 +const DATA_FILE = path.join(__dirname, 'todos.json'); + +// 获取命令行参数 +const args = process.argv.slice(2); +const command = args[0]; +const param = args[1]; + +// 读取数据 +function loadTodos() { + if (!fs.existsSync(DATA_FILE)) { + return []; + } + const data = fs.readFileSync(DATA_FILE, 'utf8'); + return JSON.parse(data || '[]'); +} + +// 保存数据 +function saveTodos(todos) { + fs.writeFileSync(DATA_FILE, JSON.stringify(todos, null, 2)); +} + +// 显示帮助 +function showHelp() { + console.log(` +用法: node todo.js <命令> [参数] + +命令: + add <内容> 添加待办事项 + list 列出所有待办 + done <编号> 标记完成 + delete <编号> 删除待办 + clear 清空所有待办 + help 显示帮助 + `); +} + +// function hotol(){ +// console.log('优先级功能'); +// if(command == 'add'){ + +// } +// console.log(command); + +// } + +// 主逻辑 +switch (command) { + case 'add': + // 添加待办(后面实现) + hotol() + if (!param) { + console.log('❌ 请输入待办内容'); + process.exit(1); + } + const todos = loadTodos(); + todos.push({ + id: Date.now(), + content: param, + done: false, + createdAt: new Date().toLocaleString() + }); + saveTodos(todos); + console.log('✅ 已添加:' + param); + break; + case 'list': + // 列出待办(后面实现) + const allTodos = loadTodos(); + if (allTodos.length === 0) { + console.log('📝 暂无待办事项'); + } else { + console.log('📋 待办清单:'); + allTodos.forEach((todo, index) => { + const status = todo.done ? '✅' : '☐'; + console.log(`${index + 1}. [${status}] ${todo.content}`); + }); + } + break; + case 'done': + // 标记完成(后面实现) + const id = parseInt(param); + const doneTodos = loadTodos(); + const index = doneTodos.findIndex(t => t.id === id); + if (index === -1) { + console.log('❌ 找不到该待办'); + } else { + doneTodos[index].done = true; + saveTodos(doneTodos); + console.log('✅ 已完成:' + doneTodos[index].content); + } + break; + case 'delete': + // 删除待办(后面实现) + const delIndex = parseInt(param) - 1; + const delTodos = loadTodos(); + if (delIndex < 0 || delIndex >= delTodos.length) { + console.log('❌ 找不到该待办'); + } else { + const deleted = delTodos.splice(delIndex, 1)[0]; + saveTodos(delTodos); + console.log('🗑️ 已删除:' + deleted.content); + } + break; + case 'clear': + // 清空待办(后面实现) + saveTodos([]); + console.log('🧹 已清空所有待办'); + break; + case 'help': + default: + showHelp(); +} +``` + +扩展功能:为待办工具添加"优先级"功能,支持高/中/低优先级。 +```js + +function getPriorityText(priority) { + switch (priority) { + case 'high': return '高'; + case 'medium': return '中'; + case 'low': return '低'; + default: return '中'; + } + } + + + function sortByPriority(todos) { + const order = { high: 3, medium: 2, low: 1 }; + return [...todos].sort((a, b) => order[b.priority] - order[a.priority]); + } + + +``` + +笔记工具:开发一个简单的笔记CLI工具,支持: + +add <标题> <内容> - 添加笔记 +list - 列出所有笔记 +search <关键词> - 搜索笔记 +```js +import fs from 'fs'; + +const content = process.argv[2]; +const params = process.argv[3]; +const conts = process.argv[4]; + +if (content == 'list') { + console.log('获取数据'); + let fileData = readFile(); + console.log(fileData); + +} else if (content == 'add') { + console.log('新增'); + let arr = readFile(); + arr.push({ 'title': params, 'conts': conts }); + writeFile(arr); + let newArr = readFile(); + console.log(newArr); + +} else if (content == 'del') { + console.log('删除'); + let idx = parseInt(params); + let delArr = readFile(); + delArr.splice(idx - 1, 1); + writeFile(delArr) + console.log(delArr); + +} else if (content == 'search') { + console.log('搜索笔记'); + let allNodes = readFile(); + + for (let i = 0; i < allNodes.length; i++) { + // console.log(allNodes[i].title); + if (allNodes[i].title == params) { + console.log(allNodes[i]); + } + } + +} else { + console.log('未知'); +} + + +function readFile(filePath) { + filePath = filePath || './nodes.json' + if (fs.existsSync(filePath)) { + let data = fs.readFileSync(filePath, 'utf-8'); + return JSON.parse(data) || []; + } + return [] +} + +function writeFile(fileContent, filePath) { + filePath = filePath || './nodes.json'; + let jsonString = JSON.stringify(fileContent) + fs.writeFileSync(filePath, jsonString) +} +``` + +计算器工具:开发一个命令行计算器,支持: + +add - 加法 +sub - 减法 +mul - 乘法 +div - 除法 + +```js +import fs from 'fs' +const content = process.argv[2]; +let a = process.argv[3]; +let b = process.argv[4]; + +if (content == 'add') { + console.log(parseInt(a) + parseInt(b)); +} else if (content == 'sub') { + console.log(parseInt(a) - parseInt(b)); + +} else if (content == 'mul') { + console.log(parseInt(a) * parseInt(b)); + +} else if (content == 'div') { + if(a <= 0){ + throw new Error('a不能小于等于0'); + } + console.log(parseInt(a) / parseInt(b)); + +} else { + console.log('未知'); +} +``` + +文件处理工具:开发一个文件处理工具,支持: + +count <文件名> - 统计文件行数 +upper <文件名> - 转为大写 +lower <文件名> - 转为小写 + +```js +import fs from 'fs' +const content = process.argv[2]; + +if(content == 'count'){ + console.log('统计文件行数'); + let arr = readFile(); + console.log(arr.length); + + +}else if(content == 'upper'){ + console.log('转为大写'); + let arr = readFile(); + console.log(arr); + let arrUper = arr.toUpperCase(arr).trim(); + writeFile(arrUper); + let newArr = readFile(); + console.log(newArr); + + + +}else if(content == 'lower'){ + console.log('转为小写'); + let arr = readFile(); + console.log(arr); + let arrLow = arr.toLowerCase(); + writeFile(arrLow); + let newArr = readFile(); + console.log(newArr); + + +} + +function readFile(filePath){ + filePath = filePath || './todos.txt'; + if(fs.existsSync(filePath)){ + let data = fs.readFileSync(filePath,'utf-8'); + return data || []; + } + return []; +} + +function writeFile(content,filePath){ + filePath = filePath || './todos.txt'; + //let jsonString = JSON.stringify(content); + fs.writeFileSync(filePath,content); +} +``` \ No newline at end of file diff --git "a/\346\235\216\351\233\250\347\277\224/20260313-\346\240\270\345\277\203\347\237\245\350\257\206\347\202\271.md" "b/\346\235\216\351\233\250\347\277\224/20260313-\346\240\270\345\277\203\347\237\245\350\257\206\347\202\271.md" new file mode 100644 index 0000000000000000000000000000000000000000..a3024d423a373886a90f0022ababceac9ae3c7d2 --- /dev/null +++ "b/\346\235\216\351\233\250\347\277\224/20260313-\346\240\270\345\277\203\347\237\245\350\257\206\347\202\271.md" @@ -0,0 +1,7 @@ +## 核心知识点 +知识点 关键内容 +命令行参数 process.argv获取命令行参数 +文件操作 fs模块读写文件 +路径处理 path模块处理文件路径 +命令解析 switch或commander解析命令 +数据存储 JSON文件持久化数据 \ No newline at end of file diff --git "a/\346\235\216\351\233\250\347\277\224/img/image.png" "b/\346\235\216\351\233\250\347\277\224/img/image.png" new file mode 100644 index 0000000000000000000000000000000000000000..e48519026723a81b187691c72ebce27aad77d979 Binary files /dev/null and "b/\346\235\216\351\233\250\347\277\224/img/image.png" differ