node3
node
1.0CommonJS规范
1.0nodejs与commonjs之间的关系:
nodejs是一种服务器语言。
commonjs是nodejs的规范。
2.0commonjs规范的意义:
虽然nodejs的语法层面是用js来写的,但是js的标准ECMAScript存在太多的缺陷,它只是规范了javascript中的词法、类型、表达式、方法、对象等基本要素,所以javascript本身是存在的缺点:
1)没有模块系统(不方便扩展)
2)标准库较少,对于文件系统,I/O流等常见的需求没有标准的API
3)没有标准接口,缺少如:WEB胳器,数据库的统一接口
。。。。。。
而nodejs作为一门后台语言,它必须有自己的很多基本功能,而这些功能需要有人来规范有,commonjs就是起的这样一个规范,它规范了:
1)javascript必须像后台语言一样具有拥有开发大型web服务器的有能力
2)commonjs覆盖了:二进制、字符集编码、I/O流、web服务器.....
3)规范了模块与模块之间的引用关系
所以commonjs是nodejs的一个规范,它的规范使得nodejs具有的开发服务器的可能。
2.0核心模块
什么叫核心模块:commonjs规定的好的功能在nodejs实现了,这样的一些模块我们叫做核心模块。也就是说nodejs中所有文档中给出的api都是核心模块,而我自己写的模块我们称为用户模块
2.1核心模块Path
作用:用于帮助程序员来操作硬盘上的路径。
核心模块注意点:当引用核心模块的时候直接require('模块名'),不需要加任何路径或者后缀。
Path中的常用API:
dirname(路径):
//获取传入路径中文件的路径
basename(路径):
//如果不传入任何参数:直接获取到传入路径中文件的全名称(文件名+扩展名)
//如果传入文件对应的后缀,会将后缀名去掉(传错与不传相同)
extname(路径):
//获取传入路径中文件的扩展名
join():
//将多个路径组装成一个路径,不管路径是否标准,路径中存在../这个方法也可以识别。
parse(路径)
//返回值是一个对象
//将传入的路径进行拆分,将路径的各个部分以对象属性的形式返回
format(路径对象);
//返回一个字符串
//将一个路径对象传入,返回一个路径的字符串
注意:win下的路径最好加上反斜杠,max系统下不用关注。
Path中的非常用API:
delimiter:
//分隔符:如果在win系统下为';',在其它系统下为':'
isAbsolute(路径):
//判断一个路径是否是一个绝对路径
normalize(路径):
//将一个非标准路径转换成一个标准路径
relative(form路径,to路径):
//form路径到to路径要的查找过程
sep:
//在win系统下得到'\'分隔符,在其它系统下面得到'/'分隔符
posix:
//所有的路径方法的一个集合
2.2核心模块url
作用:用于操作请求的路径
url常用API:
url.parse(路径);
url.format(路径对象)
2.3核心模块querystring
作用:对请求参数的处理
querystring常用API:
querystring.parse();
//将一个参数字符串转为对象
querystring.stringify();
//将一个对象转为字符串
querystring.escape(url)
//将url中的汉字进行转码
querystring.unescape(url)
//将url中被转码的汉字重新转为汉字
3.0文件模块:
3.1什么是文件模块:
nodejs中的核心模块都集成到了node.exe之中,将来不管是引用还是使用都非常方便,但是有node.exe之中给我们准备的模块有限,有很多功能没有被包含在核心模块之中。所以在实际开发过程中我们会根据自己的需求去开发一个自己模块。像这种模块没有集成到node中的自己开发的模块我们叫做文件模块,或者叫做用户模块,再或者是第三方包模块。
特点:核心模块的运行效率永远要高于文件模块,本质的原因是nodejs在运行起来以后核心模块就已经加载到内存中了,而文件模块还要先读取出来,再转成二进制数据去执行,速度自然会慢好多。
实用技巧:node有一个用户模块社区npmjs,我们可以去上面下载一些别人开发好的模块,或者将自己写好的模块放到npmjs之中.
3.2案例:如何自己开发一个文件模块(自己开发一个计算器)。
过程:
一版本:
直接开发一个js文件,开发出需要的计算功能,使用另一个js文件去引用,但是如果将来再次加入其它的功能,又需要再加入另一个文件,开发对应的功能,再次用使用的js文件去引用,太麻烦了,为了能够让结构代码更加的清晰,我们将所有的文件约定好放在同一个文件夹node_modules中
注意点:
1)nodejs是定义模块不需要关键字define,其它跟js中的模块化一样
2)引用文件模块可以时路径中可以不加后缀
二版本:
用一个node_modules文件夹将所有文件模块放入其中(注意:这个node_module文件夹非常重要,将来开发过程中所有的文件模块都是放到这个文件下的)。但是如果将来我们开发的内容不仅仅是限于一个计算功能,可能还会有其它功能,比如说登录注册功能,那么一个node_modules下面放的文件就相当于有两种类型的文件了,为了将这两种类型的文件区分开。我们给每个类型的功能单独建立一个文件夹,来管理对应的模块,并且为每个在每个文件夹中设置一个对面的文件(像这样 的一个文件在nodejs我们将它称作包,一个包是多个js文件或者说js模块组成的,并且具有一个统一的出口文件,并且出口文件一般情况下名称定义为index.js)(图解)。
三版本:
写好包以后如果要使用还要直接去引包的出口文件,这样改造后的出口文件一般情况下路径很长,为了操作方便。我们不会再去引全路径,而是会直接引用的require上面放上包名以此来导入包,虽然路径没有写全,但是运行以后发现文件还是正常的,说明nodejs在执行require('包名')是有自己的过程的
3.3 nodejs引包的过程
步骤一:当nodejs执行到require('包名')的时候会先将这个包名当作核心模块来识别,
步骤二:但是发现这个包并不是核心模块时,会自动去node_modules文件中查找文件名为这个包名的文件夹
步骤二点五:如果找到这个包,且包中有一个叫做package.json的文件,nodejs会根据package.json中的main属性去找到对应的入口文件
步骤三:如果没有package.json文件就直接去包中找一个名称为index.js的模块,并加载出来
步骤四:如果都没有找到,就报错
3.4package.js文件:
作用:给当前包设置一些重要参数。
生成package.js文件:关键指令npm init -y
在包文件夹下打开CMD,输入上面指令,会自动在这个目录下面生成一个package.json文件
文件内容:
{
"name": "js",
"version": "1.0.0",
"description": "",
"main": "abc.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC"
}
属性的作用:
name:设置当前包的名称(将来发布到npm上的名称)
下面是官方给出的一些建议:
名字里不要再包含"js"和"node",因为默认NPM包就是node.js程序,不过你可以通过engines字段来指定。
名字将会被作为url的一部分,所有要符合http url的一般命名规则,不能包含url非法字符,也不能以.和_开头。
名字也将作为require()命令的参数,所以应该尽量简明。
如果包要发布到NPM平台上的话,最好先检查下有没有重名, 并且字母只能全部小写。
version:设置当前包的版本,例:v2.0.0
name和version是package.json中最重要的两个字段,也是发布到NPM平台上的唯一标识,如果没有正确设置这两个字段,包就不能发布和被下载。
description:设置当前包的描述信息(方便将来其它用户在npm上能名搜索到已发布的包)
main:设置当前包的出口文件
script:这个设置可以使当前包调用NPM一些命令脚本,封装一些功能
keywords:设置当前包的关键字(方便将来其它用户在npm上能名搜索到已发布的包)
author:当前包的作者
license:设置当前包的许可证书版本(BSD-3-Clause,MIT,ISC)
这些许可证书规定了将来软件其它人得到以后是否可以做的一些操作:比如:使用,修改,转发, 以及使用项目的一部分出售。
注意:每一个包都必须要有一个json文件
3.5包:
什么是包:
就是将一组功能相似的文件模块统一放到一个文件夹下,并且为所有的文件模块设置一个统一的出口文件,这样的文件夹在nodejs中被称为包。
包的标准结构:
一个符合CommonJS规范的包应该是如下这种结构:
一个package.json文件应该存在于包顶级目录下
二进制文件应该包含在bin目录下。
JavaScript代码应该包含在lib目录下。
文档应该在doc目录下。
单元测试应该在test目录下。
使用说明放在README.md文件中
结构:
_包名
|
|__package.json
|
|__bin
| |
| |__二进制文件
| |
|__lib
| |
| |__JavaScript代码
|
|__doc
| |
| |__文档
|
|__text
| |
| |__单元测试
|
|__README.md
3.6通过npm安装和上传包:
1)上传:
步骤:
1)创建好一个包(注意:一定要满足包的要求),并且在package.json包中设置好一些参数。
2)去npmjs注册一个账号:jhon_j.登录之后点击图像会弹出下拉框,选择profile,会打开记录发布包的历史记录
3)在要发布的文件夹下打开CMD,执行发布指令:
a)npm adduser:根据引入,依次输入用户名,密码,以及注册邮箱就行了
b)npm publish:看到+ calcczboke3qi@1.0.0指令说明已经安装成功
2)撤销:
3)安装:
a. 本地安装
指令: npm install 包的本地路径
作用:解决无法发布到互联网上的包通过这个指令在公司内部自己使用
b. 联网安装
指令: npm install 包名
i.本项目安装:
npm install 包名
ii.全局包安装:
npm install 包名 -g
小技巧:由于npm是国外网站,在安装的时候速度可能比较慢。解决办法一:下载一个nrm,通过nrm将npm的登录从国外移动到国内,使用nrm use cnpm指令 解决办法二:安装一个cnpm工具,直接通过cnpm来安装
一般哪些包要被全局安装,哪些包要项目安装在npm中的README.md中有介绍,全局包的安装本质上将文件放到了当前使用的nodejs的目录下面
总结:在整个nodejs环境中(不管是什么项目)你都希望用到这个包,就需要安装一个全局包,但是如果只有本项目用到,安装一个本项目包。
3.7npm其它常用指令:
npm adduser :会引导输入用户名,密码以及注册邮箱(如果登录成功会显示:Logged in as jhon_j on https://registry.npmjs.org/.)
npm publish:发布包
npm uppublish 包名@版本号:撤销已经发布的包
npm install <name>安装nodejs的依赖包
例如npm install express 就会默认安装express的最新版本,也可以通过在后面加版本号的方式安装指定版本,如npm install express@3.0.6
npm install <name> -g 将包安装到全局环境中
但是代码中,直接通过require()的方式是没有办法调用全局安装的包的。全局的安装是供命令行使用的,就好像全局安装了vmarket后,就可以在命令行中直接运行vm命令
npm install <name> --save 安装的同时,将信息写入package.json中
项目路径中如果有package.json文件时,直接使用npm install方法就可以根据dependencies配置安装所有的依赖包
这样代码提交到github时,就不用提交node_modules这个文件夹了。
npm init 会引导你创建一个package.json文件,包括名称、版本、作者这些信息等
npm remove <name>移除
npm update <name>更新
npm ls 列出当前安装的了所有包
npm root 查看当前包的安装路径
npm root -g 查看全局的包的安装路径
npm help 帮助,如果要单独查看install命令的帮助,可以使用的npm help install
3.8require加载规则的总结:
1)require无论是核心模块还是文件模块都优先从缓存加载(可以解决一个文件多次引用一个文件模块而反复加载的问题)
2)在window中加载一个文件模块要使用./或者../开头(如果不加nodejs会当作用核心模块或者是包来解析)
3)在mac和linux中以/加载是加载一个绝对路径的文件模块,而在window下/表示当前require函数所在文件所在的目录的盘符(比如:c盘,没有意义)
4)一个文件模块可以不写扩展名,require()会自动依次按照.js .node .json的顺序进行补齐后加载,如果三个扩展名都没有,则当做目录或者包来加载。如果目录或者包都没有,则报错。
所以如果不加后缀,将来如果一个文件返回的是json,那么它的加载性能会慢一点。
5)加载一个包
-依次按照module.paths数组中的路径,加载传入的包名,如果有,就加载出业;如果没有,报错
-包加载完毕以后,如果有package.json文件,就去找其中main属性对应的出口文件
-如果没有,就找默认文件index.js
4.0调试nodejs
1)使用console.log()
使用麻烦,用了以后还要删除
2)nodejs的自带调试器
-node debug a.js
没有任何作用,一个玩具,将来有一天可以会变得强大的
3)使用visual stdio调试:
步骤:
a)安装vsCode,并且通过vscode打开要调试的文件所在的文件夹
b)点击F5,选择nodejs的打开方式,这时vsCode会打开一个lanuch.json,修改其中"program"属性,改为"${workspaceRoot}/文件名.js",
c)可以查看文件的五个全局对象以及添加监控文件中变量的值
4)使用webstorm调试