一、nodejs概述
1、nodejs用js语言做服务器端开发,用js做类似PHP的活,节省开发成本。
2、nodejs支持es6语法
3、nodejs==>运行在服务器端的js
服务器端的js和客户端的js区别==》一个运行在服务器端,一个运行在浏览器
PHP可以处理请求(get, post),读写文件,操作数据库,nodejs就是用js的语言操作这些文件,网络,请求。而客户端的js是操作DOM
4、npm==>强大的包管理工具(安装、卸载等)
cd\ ==》 根目录
cd.. ==》返回上一级目录
退出终端==》exit 全称==》process.exit()
清屏:cls
查看当前文件下有什么目录 dir
新建文件夹 mkdir +文件夹名字
注:把node的目录设置到环境变量里 所以任何文件夹下输入node -v都可以显示出版本号
安装node后 node文件夹里有个bin目录,里边有node.exe,实际上是把这个路径添 加到系统环境变量里了
5、编译安装==》特指在linux系统下才编译安装,从网络下载nodejs源码进行编译
linux系统下#代表管理员 $代表一般用户
编译安装==》1、下载 2、解压
3、$ ./configure ->检查依赖关系
$ make ->编译
$ sudo make install ->安装
二、commonJS
1、概述
有多人协助或者大量的js文件批量引入一个页面时,很容易产生变量名冲突被覆盖掉或者方法被重写,特别是当有一些依赖关系的时候,页面特别容易出错,这是因为js天生就缺少一种模块管理机制来隔离实现不同功能的js片段。
Node程序由许多个模块组成,每个模块就是一个文件。Node模块采用了CommonJS规范
根据CommonJS规范,一个单独的文件就是一个模块。每一个模块都是一个单独的作用域,也就是说,在一个文件定义的变量(还包括函数和类),都是私有的,对其他文件是不可见的。
CommonJS规定,每个文件的对外接口是module.exports对象。这个对象的所有属性和方法,都可以被其他文件导入。
require方法用于在其他文件加载这个接口
2、CommonJS模块的特点如下
所有代码都运行在模块作用域,不会污染全局作用域。
模块可以多次加载,但是只会在第一次加载时运行一次,然后运行结果就被缓存了,以后再加载,就直接读取缓存结果。要想让模块再次运行,必须清除缓存。
模块加载的顺序,按照其在代码中出现的顺序。
3、了解的js模块化 有amd cmd
amd 是指异步模块加载 预加载 衍生物 ==》 requirejs
写法:
AMD就只有一个接口:define(id?,dependencies?,factory);
cmd 是指按需加载 衍生物 ==》 seajs
define(function(require,exports,module){...});
4、AMD规范与CommonJS规范的兼容性
CommonJS规范加载模块是同步的,也就是说,只有加载完成,才能执行后面的操作。AMD规范则是非同步加载模块,允许指定回调函数。由于Node.js主要用于服务器编程,模块文件一般都已经存在于本地硬盘,所以加载起来比较快,不用考虑非同步加载的方式,所以CommonJS规范比较适用。但是,如果是浏览器环境,要从服务器端加载模块,这时就必须采用非同步模式,因此浏览器端一般采用AMD规范。
三、require命令
1、基本用法
Node使用CommonJS模块规范,内置的require命令用于加载模块文件。
require命令的基本功能是,读入并执行一个JavaScript文件,然后返回该模块的exports对象。如果没有发现指定模块,会报错。
如果指定的模块文件没有发现,Node会尝试为文件名添加.js、.json、.node后缀,再去搜索。.js件会以文本格式的JavaScript脚本文件解析,.json文件会以JSON格式的文本文件解析,.node文件会以编译后的二进制文件解析。
四、module对象
Node内部提供一个Module构建函数。所有模块都是Module的实例。
每个模块内部,都有一个module对象,代表当前模块。
module.exports 初始值为一个空对象 {}。
五、目录的加载规则
通常,我们会把相关的文件会放在一个目录里面,便于组织。这时,最好为该目录设置一个入口文件,让require方法可以通过这个入口文件,加载整个目录。
六、模块的缓存
第一次加载某个模块时,Node会缓存该模块。以后再加载该模块,就直接从缓存取出该模块的module.exports属性。
七、下载第三方包命令行
npm install jquery --save-dev 简写==>-D dev是下载到本地,作为本地开发使用
(生成devDependencies依赖)
npm install jquery --save(生成dependencies依赖)
八、部分内置模块
Path HTTP fs url
url是配合http用的 可以操作客户端访问的url请求 可以对url 进行操作 例入将url转为对象,也可以获取url的HASH值
九、npm init 生成==>package.json 初始化
十、module.exports exports
exports是对象 因为他是对象 所以对外抛出的时候 它可以直接定义key值 他是唯一对外输出的途径
module相当于exports父级 ,改变抛出的当前内容的形式
十一、
在标准js里 window是全局对象,在node里 全局对象是global。process
十二、输入,输出流
process.stdout.write('\033[0f');
process.stdout.write('\033[2J');
输入流process.stdin.write('\033[2J');
std ==>标准的
process.stdout
一个指向标准输出流(stdout)的 可写的流(Writable Stream)
Process.stdin
一个指向 标准输入流(stdin) 的可读流(Readable Stream)。
设置编码 ==》process.stdin.setEncoding('utf8');
暂停 ==》process.stdin.pause(); 不暂停将一直循环
退出当前进程==》process.abort()
终止当前进程==》process.exit()
打印命令行数组==》process.argv 数组
十三、ES6
1、箭头函数 ()=>
不能代替普通函数,只能作为回调函数使用
2、反引号 ``
在反引号中的字符串可以${变量名}的形式识别变量
十四、安装命令行程序 npm install +程序名
- 配置npm账号 npm adduser 密码不回显 npm publish(--tag 0.0.1==》指定版本号)==>发布帐号信息 www.npmjs.com==》查看网址
- 修改package文件必需字段发布代码 (package.json里的name字段不能重名)
- Set node_path
十四、模块文件查找(版本号 密码登录)
十六、版本名:(1.0.0==》表名就这一个版本且没做任何修改)
如果版本升级以后只是修复了上一个版本的bug的话,修改的是最后一个版本号
如果是新增了一些新功能,且这些新功能还兼容上一个版本,升级的是第二个版本号
如果是新增了一些新功能,但这些新功能不兼容上一个版本,升级的是第一个版本号
安装命令行程序
写一个js文件,里面有我们封装的指令=》同级建一个后缀名为.cmd的命令行程序(这个文件中输入node +js文件所在的绝对路径+ %*)=》找到Path环境变量=》将js文件所在路径添加到该环境变量中=》运行指令(即:命令行输入后缀名为.cmd的命令行程序的名称)
NODE_PATH配置
新建一个名为node_path的环境变量,值是所要引入模块的绝对路径,这个模块即可被任意文件引入
工程目录
- /home/user/workspace/node-echo/ # 工程目录
- bin/ # 存放命令行相关代码
node-echo
+ doc/ # 存放文档
- lib/ # 存放API相关代码
echo.js
- node_modules/ # 存放三方包
+ argv/
+ tests/ # 存放测试用例
package.json # 元数据文件
README.md # 说明文件
文件操作
1、前言:让前端觉得如获神器的不是NodeJS能做网络编程,而是NodeJS能够操作文件。小至文件查找,大至代码编译,几乎没有一个前端工具不操作文件。换个角度讲,几乎也只需要一些数据处理逻辑,再加上一些文件操作,就能够编写出大多数前端工具。
2、小文件、大文件拷贝
大文件拷贝=》一次性把所有文件内容都读取到内存中后再一次性写入磁盘的方式不适合拷贝大文件,内存会爆仓。对于大文件,我们只能读一点写一点,直到完成拷贝。
大文件拷贝==》fs.createReadStream(src).pipe(fs.createWriteStream(dst))
fs.createReadStream创建一个源文件的只读数据流
fs.createWriteStream创建一个目标文件的只写数据流
pipe方法把两个数据流连接了起来。连接起来后发生的事情,说得抽象点的话,水顺着水管从一个桶流到了另一个桶。
3、Buffer(数据块)
所有的流组成一个数据块
4、Stream(数据流)
当内存中无法一次装下需要处理的数据时,或者一边读取一边处理更加高效时,我们就需要用到数据流
在处理数据前暂停数据读取,并在处理数据后继续读取数据。
注:drain事件来判断什么时候只写数据流已经将缓存中的数据写入目标,可以传入下一个待写数据
fs.open(path, flags, [mode], [callback(err,fd)])=》以异步的方式打开文件
path 文件路径
mode 用于创建文件时给文件制定权限,默认0666
flags 可以是以下的值
'r' - 以读取模式打开文件。
'r+' - 以读写模式打开文件。
'rs' - 使用同步模式打开并读取文件。指示操作系统忽略本地文件系统缓存。
'rs+' - 以同步的方式打开,读取 并 写入文件。
注意:这不是让fs.open变成同步模式的阻塞操作。如果想要同步模式请使用fs.openSync()。
'w' - 以读取模式打开文件,如果文件不存在则创建
'wx' - 和 ' w ' 模式一样,如果文件存在则返回失败
'w+' - 以读写模式打开文件,如果文件不存在则创建
'wx+' - 和 ' w+ ' 模式一样,如果文件存在则返回失败
'a' - 以追加模式打开文件,如果文件不存在则创建
'ax' - 和 ' a ' 模式一样,如果文件存在则返回失败
'a+' - 以读取追加模式打开文件,如果文件不存在则创建
'ax+' - 和 ' a+ ' 模式一样,如果文件存在则返回失败
File System(文件系统)
NodeJS通过fs内置模块提供对文件的操作。fs模块提供的API基本上可以分为以下三类:
文件属性读写。
其中常用的有fs.stat、fs.chmod、fs.chown等等。
fs.chmod方法说明:
该方法以异步的方式来改写文件的读写权限。
操作完成后的回调只接收一个参数,可能会出现异常信息。
语法:
fs.chmod(path, mode, callback)
fs.chown方法说明:
更改文件所有权。
语法:
fs.chown(path, uid, gid, [callback(err)])
接收参数:
path 目录路径
uid 用户ID
gid 群体身份 (指共享资源系统使用者的身份)
callback 回调 ,传递异常参数 err
文件内容读写
其中常用的有fs.readFile、fs.readdir、fs.writeFile、fs.mkdir等等。
底层文件操作
其中常用的有fs.open、fs.read、fs.write、fs.close等等。
NodeJS最精华的异步IO模型在fs模块里有着充分的体现,例如上边提到的这些API都通过回调函数传递结果。
基本上所有fs模块API的回调参数都有两个。第一个参数在有错误发生时等于异常对象,第二个参数始终用于返回API方法执行结果。
fs模块的所有异步API都有对应的同步版本,用于无法使用异步操作时,或者同步操作更方便时的情况。同步API除了方法名的末尾多了一个Sync之外,异常对象与执行结果的传递方式也有相应变化。
Path(路径)
简言:操作文件时难免不与文件路径打交道。NodeJS提供了path内置模块来简化路径相关操作,并提升代码可读性。
1、Path.normalize(输出规范格式的path字符串)
说明:将传入的路径转换为标准路径,具体讲的话,除了解析路径中的.与..外,还能去掉多余的斜杠。如果有程序需要使用路径作为某些数据的索引,但又允许用户随意输入路径时,就需要使用该方法保证路径的唯一性。
2、Path.join
将传入的多个路径拼接为标准路径。该方法可避免手工拼接路径字符串的繁琐,并且能在不同系统下正确使用相应的路径分隔符
语法:path.join([path1], [path2], [...])
3、Path.extname
返回path路径文件扩展名,如果path以 ‘.' 为结尾,将返回 ‘.',如果无扩展名 又 不以'.'结尾,将返回空值。
4、Path.resolve
将参数 to 位置的字符解析到一个绝对路径里
path.resolve([from ...], to)
接收参数:
from 源路径
to 将被解析到绝对路径的字符串
遍历目录
试用场景:比如写一个程序,需要找到并处理指定目录下的所有JS文件时,就需要遍历整个目录。
遍历目录时一般使用递归算法
http网络模块
'http'模块提供两种使用方式:
作为服务端使用时,创建一个HTTP服务器,监听HTTP客户端请求并返回响应。
作为客户端使用时,发起一个HTTP客户端请求,获取服务端响应.
HTTP请求本质上是一个数据流,由请求头(headers)和请求体(body)组成。
Req:请求的相关对象
Res:回应的相关对象
Zlib模块(压缩 / 解压文件)
zlib.createGzip(); 创建一个压缩流
zlib.createGunzip() 创建一个解压流
Gzip是什么?
GZIP是网站压缩加速的一种技术,对于开启后可以加快我们网站的打开速度,原理是经过服务器压缩,客户端浏览器快速解压的,可以大大减少了网站的流量。
.gz的文件就是GZIP格式的
accept-encoding ==》编码类型
浏览器通过HTTP请求头部里加上Accept-Encoding,告诉服务器,“你可以用gzip,或者defalte算法压缩资源”。
querystring模块(格式化参数)
此类一共包括4个方法:
querystring.stringify(obj,[sep],[eq])==》要转化的对象、分隔符、分配符
//将JSON对象格式化为查询字符串格式的字符串,默认的分隔符为:“&”和“=”
querystring.parse(str, [sep], [eq])
根据“&”和“=”将字符串进行分割,反序列化为JSON对象。
querystring.escape 参数编码
querystring.unescape 参数解码
Cul
curl可以帮你完成你所有在浏览器上的操作,
比如登录(这就是传输数据),下载文件,上传文件等等功能。
Url模块
url一共提供了三个方法,分别是url.parse(); url.format(); url.resolve();
1 url.parse(urlString)
parse这个方法可以将一个url的字符串解析并返回一个url的对象
参数:urlString指传入一个url地址的字符串
解析后对象字段如下:
href: 解析前的完整原始 URL,协议名和主机名已转为小写
例如: 'http://user:[email protected]:8080/p/a/t/h?query=string#hash'
protocol: 请求协议,小写
例如: 'http:'
slashes: 协议的“:”号后是否有“/”
例如: true or false
host: URL主机名,包括端口信息,小写
例如: 'host.com:8080'
auth: URL中的认证信息
例如: 'user:pass'
hostname: 主机名,小写
例如: 'host.com'
port: 主机的端口号
例如: '8080'
pathname: URL中路径
例如: '/p/a/t/h'
search: 查询对象,即:queryString,包括之前的问号“?”
例如: '?query=string'
path: pathname 和 search的合集
例如: '/p/a/t/h?query=string'
query: 查询字符串中的参数部分(问号后面部分字符串),或者使用 querystring.parse()解析后返回的对象
例如: 'query=string' or {'query':'string'}
hash: 锚点部分(即:“#”及其后的部分)
例如: '#hash'
2 url.format(urlObj)
format这个方法是将传入的url对象编成一个url字符串并返回
参数:urlObj指一个url对象
3 url.resolve(from,to)
resolve这个方法用于处理URL路径,也可以用于处理锚点。返回一个格式为"from/to"的字符串,对传入的两个参数用"/"符号进行拼接,并返回
url.resolve('/one/two/three', 'four') // '/one/two/four'
url.resolve('http://example.com/', '/one') // 'http://example.com/one'
url.resolve('http://example.com/one', '/two') // 'http://example.com/two'
Curl -H “Accept-encoding:gzip” localhost:8081
Curl localhost:8081
curl是利用URL语法在命令行方式下工作的文件传输工具。
注:__dirname 当前执行文件所在的位置
nodejs之process进程
进程模块
process是一个全局内置对象,process模块允许你获得或者修改当前node进程的设置,不想其他的模块,process是一个全局进程(node主进程),你可以直接通过process变量直接访问它。
用处:使用process对象可以截获进程的异常、退出等事件,也可以获取进程的当前目录、环境变量、内存占用等信息,还可以执行进程退出、工作目录切换等操作。
// process几个属性
// process.pid
process.version(5.0.0最稳定)
process.title
process.argv返回一个数组 获取命令行参数
// process.installPrefix 包含安装路径
// process.platform:当前系统平台,比如Linux。
// process.execPath:运行当前进程的可执行文件的绝对路径。
方法
// process.stdout 指向标准输出
// process.stdin 指向标准输入
// process.stderr 指向错误输出
// process.stdin.emit=》派发一个事件
// process.stdin.read();// 监听输入的数据
// process.stdin.setEncoding('utf8');
// process.stdin.on('readable', function () {})// 监听一个可读的数据流
事件:
process是EventEmitter的一个实例,process主要包含退出事件、信号事件以及一些属性
1、 process.nextTick ==>将代码放在事件循环的前面
nextTick创建的回调函数具有隔离性,他们之间不会相互影响
2、Process的退出事件 ==》 (process全局监听的事件)
当退出当前进程时,会触发exit事件,exit事件的回调函数中只接受同步操作。因为进程退出之后将不再执行事件循环,所有只有那些没有回调函数的代码才会被执行
3、uncaughtException事件捕捉系统异常