Nodejs(所有的知识点都可以去nodejs官网查看详细文档)!
一. Nodejs可以用来做什么?
- 具有复杂逻辑的动态网站
- WebSocket服务器
- 命令行工具
- 带有图形界面的本地应用程序
二. 终端基本使用
- 打开应用
notepad打开记事本
mspaint打开画图
calc打开计算机
write写字板
sysdm.cpl打开环境变量设置窗口 - 常用命令
md创建目录
rmdir(rd)删除目录,目录内没有文档
echo on a.txt创建空文件夹
del删除文件
rm 文件名 -->删除文件
cat 文件名 —>查看文件内容
cat > 文件名 -->向文件中写上内容
三. Nodejs开发环境准备
- 普通安装方式–>官方网站
- 多版本安装方式
卸载已有的nodejs
下载nvm
在C盘创建目录dev,并且把nvm包解压进去
配置nvm环境变量
配置nodejs环境变量
三. nvm常用的命令
nvm list 查看当前安装的Nodejs所有版本
nvm install 版本号 安装指定版本的Nodejs
nvm uninstall 版本号 卸载指定版本的Nodejs
nvm use 版本号 选择指定版本的Nodejs
四. Nodejs之Hello World
- 命令行方式REPL
– REPL read-eval-print-loop 读取代码-执行-打印结果-循环这个过程
– 在REPL环境中,_表示最后一次执行结果
–退出REPL环境:.exit - 运行文件方式
- 全局对象概览
五. 模块化
模块化开发
传统非模块化开发有如下缺点
1. 命名冲突(变量的冲突,人多提交时会被覆盖)
2. 文件依赖
前端-标准的模块化规范
1. AMD - requirejs (国外用的比较多)
2. CMD - seajs (国产的,阿里巴巴的)
服务器端(后端)-模块化规范
1. CommonJs - Node.js
模块化相关的规则:
1. 如何定义模块:一个js文件就是一个模块,模块与模块内部的成员都是相互独立的
2. 模块成员的导出和引入
六. ES6语法(后续加上)
七. 核心模块API
-
路径操作
– 路径基本操作API(详情看github上nodejs_express/02_day/02.js) -
文件操作
– 文件信息获取(通过fs.stat() || fs.statSync())/* 文件操作(查看文件信息)*/ // console.log(1); // const fs = require('fs'); // fs.stat('./data.txt',(err,stats)=>{ // // 一般回调函数的第一个参数是错误对象。如果err为null,表示没有错误,否则表示报错,应该终止进程 // if(err) return; // // console.log(stats); // /* // atime 文件访问时间 // ctime 文件修改时间(文件的状态信息发生变化的时间,比如:文件的权限) // mtime 文件数据发生变化的时间 // birthtime 文件创建的时间 // */ // if(stats.isFile()){ // console.log('文件'); // } else if(stats.isDirectory()) { // console.log('目录'); // } // console.log(2); // }) // console.log(3); // 同步操作(API) // console.log(1); // let ret = fs.statSync('./data.txt'); // console.log(ret); // console.log(2);
– 读文件操作
/*读文件操作(读取文件) */ const fs = require('fs'); const path = require('path'); let strpath = path.join(__dirname,'data.txt'); fs.readFile(strpath,(err,data)=>{ if(err) return; console.log(data.toString()); }) // 另一种简便的方式 // 第二个参数加上格式。就不需要用.toString()这个方法来转换了 // 如果没有第二个参数,那么得到的就是一个Buffer实例对象 fs.readFile(strpath,'utf8',(err,data)=>{ if(err) return; console.log(data); }) // 同步操作 let ret = fs.readFileSync(strpath,'utf8'); console.log(ret);
– 写文件操作
/* 写文件操作 */ const fs = require('fs'); const path = require('path'); let strpath = path.join(__dirname,'./data.txt'); // fs.writeFile(strpath,'哈哈哈哈哈我写完了!','utf8',(err)=>{ // if(!err) { // console.log('写入成功!'); // }; // }) // let str=Buffer.from('hi!'); // fs.writeFile(strpath,str,'utf8',(err)=>{ // if(!err) { // console.log('写入成功!'); // }; // }) // 同步操作 fs.writeFileSync(strpath,'tom and jerry');
– 大文件操作
/* 大文件操作(流式操作) */ let fs = require('fs'); let path = require('path'); let spath = path.join(__dirname,'./JsMath.zip'); let dpath = path.join(__dirname,'./temp','JsMath.zip'); // let readStream = fs.createReadStream(spath); // let writeStream = fs.createWriteStream(dpath); // 基于事件的处理 // let num = 1; // readStream.on('data',(chunk)=>{ // 文件读取的时候会触发 // num++; // writeStream.write(chunk); // }) // readStream.on('end',()=>{ // 文件处理完毕事件 // console.log('文件处理完成'+num); // }) // -------------------------------------------------------------- // 另一种方式--->pipe()的作用直接链接输入流和输出流 // readStream.pipe(writeStream) fs.createReadStream(spath).pipe(fs.createWriteStream(dpath));
– 目录操作
/** * 目录操作 * 1. 创建目录 * fs.mkdir(path[,mode],callback) * fs.mkdirSync(path[,mode]) * 2. 读取目录 * fs.readdir(path[,options],callback) * fs.readdirSync(path[,options]) * 3. 删除目录 * fs.rmdir(path,callback) * fs.rmdirSync(path) */ let fs = require('fs'); let path = require('path'); // fs.mkdir(path.join(__dirname,'./temp/abc'),(err)=>{ // 创建目录abc // console.log(err); // }) // fs.mkdirSync(path.join(__dirname,'./temp/bcd')); // 同步方式 // -------------------------------------------------------------------- // 读取目录 // fs.readdir(path.join(__dirname),(err,files)=>{ // // console.log(files); // files.forEach((item)=>{ // fs.stat(path.join(__dirname,item),(err,stat)=>{ // if(stat.isFile()){ // console.log(item,'----------文件'); // }else if(stat.isDirectory()){ // console.log(item,'----------目录'); // } // }) // }) // }) // 同步方式(不建议使用) // let files = fs.readdirSync(__dirname); // files.forEach((item)=>{ // fs.stat(path.join(__dirname,item),(err,stat)=>{ // if(stat.isFile()){ // console.log(item,'----------文件'); // }else if(stat.isDirectory()){ // console.log(item,'----------目录'); // } // }) // }) // -------------------------------------------------------------- // 删除目录 // fs.rmdir(path.join(__dirname,'./temp/bcd'),(err)=>{ // console.log(err); // }); fs.rmdirSync(path.join(__dirname,'./temp/abc'));
-
文件操作案例
/* 文件操作案例(初始化目录结构)*/ const path=require('path'); // 模块 const fs=require('fs'); // 模块 let root='F:\\demo\\nodejs_express\\01_day'; // 初始化目录 let fileContent = `<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <body> <div>hello world!</div> </body> </html>`; // 初始化数据 let initData = { projectName:'mydemo', data:[{ name:'img', type:'dir' },{ name:'js', type:'dir' },{ name:'css', type:'dir' },{ name:'index.html', type:'file' }] } // 创建项目根路径----path.join(root,initData.projectName);在root根目录下创建initData.projectName fs.mkdir(path.join(root,initData.projectName),(err)=>{ if(err) return; // 如果报错,直接终结 // 创建子目录 initData.data.forEach((item)=>{ if(item.type == 'dir'){ // 创建子目录 fs.mkdirSync(path.join(root,initData.projectName,item.name)) }else if(item.type == 'file'){ // 创建文件并写入内容 fs.writeFileSync(path.join(root,initData.projectName,item.name),fileContent); } }) })
八. Buffer基本操作(Buffer不是模块,是一个全局成员–>02_day/01.js)
- Buffer对象是node处理二进制数据的一个接口,它是node原生提供的全局对象,可以直接使用,不需要require(‘Buffer’)
- 实例化:
– Buffer.from(array)
– Buffer.alloc(size) - 功能方法:
– Buffer.isEncodeing() 判断是否支持该编码
– Buffer.isBuffer() 判断是否为Buffer
– Buffer.byteLength() 返回指定编码的字节长度,默认uft8
– Buffer.concat() 将一组Buffer对象合并为一个Buffer对象 - 实例方法
– write() 向Buffer对象中写入内容
– slice() 截取新的Buffer对象
– toString() 把Buffer对象转成字符串
– toJson() 把Buffer对象转成json形式的字符串(不需要显式调用,当调用JSON.stringify时,会自动调用toJSON方法)
九. Node.js基础-异步编程概念分析
异步处理(node当中叫 异步I/O input/output)
- 文件操作 (查看文件信息、读取文件、写入文件)
- 网络操作
在浏览器中也存在异步操作
- 定时任务
- 事件处理
- ajax回调处理
js的运行是单线程的(node当中也是一样)
- 解决的办法:引入事件队列机制
Node.js中的事件模型与浏览器中的事件明模型类似
- 都是采用单线程+事件队列
Node.js中异步执行的任务:
- 文件I/O
- 网络I/O
基于回调函数的编码风格
十. 包
-
npm
-
npm安装方式
– 本地安装
– 全局安装/** * 全局安装 -g * 本地安装 * npm常用的命令 * 1. 安装包:npm install -g 包名称 (全局安装) * npm install 包名称 (本地安装) * 2. 卸载包:npm uninstall -g 包名称 (全局卸载) * npm uninstall 包名称 (本地卸载) * 3. 更新包:npm update -g 包名称 (会更新到最新的版本) * * 开发环境(开发的时候用的环境) --save-dev 添加到了devDependencies * 生产环境(项目部署上线到服务器的环境) --save 添加到了dependencies */
十一. yarn工具的基本使用
/**
* yarn工具的基本使用
* 安装yarn工具:npm install -g yarn
* 1. 初始化包:npm init -y--------yarn init
* 2. 安装包(生产环境):npm install xxx -S---------yarn add xxx
* 3. 卸载包:npm uninstall xxx----------yarn remove xxx
* 4. 更新包:npm update xxx-------------yarn upgrade xxx
* 5. 安装包(开发环境):npm install xxx -D---------yarn add xxx --dev
* 6. 全局安装:npm install -g xxx----------------yarn global add xxx
* 7. 设置下载镜像:npm config set registry url ------- yarn config set registry url
* 8. 安装依赖:npm install -------- yarn install
* 9. 执行包:npm run ------- yarn run
*/
十二. 自定义包
- 包的规范
– package.json 必须在包的顶层目录下
– 二进制文件应该在bin目录下
– javascript代码应该在lib目录下
– 文档应该doc目录下
– 单元测试应该在test目录下 - package.json字段分析