nodeJS
学习方法
-
掌握思想
编程思想很重要,语言只是工具。不仅仅只是记住了API。
-
查资料的方式
API文档
1、搭建服务器
2、mongodb 用 注册和登录增删改查新闻(bootstrap)
3、api server 注册和登录增删改查新闻(bootstrap)
4、bcrypt加密 注册和登录
5、session 登录和其它需要验证身份的模块(如:添加,删除)
6、token 登录,其它需要验证身份的模块(如:添加,删除)
7、上传图片:添加新闻
8、socket 用聊天室
服务器
什么是服务器
服务器就是提供服务的,有web服务器,数据库服务器等等…………
服务器构成
- 机器: 电脑
- web服务器需要安装的软件:apache | nodejs(管理前后端工程文件),
- 数据库服务器需要安装的软件:mysql | sqlserver | mongoDB | oracle
- 数据库存的是: 数字|字符
- 磁盘(硬盘) 文件本身(图,视频,PDF) 文件服务器
web服务端保存的资源:
静态资源
xx.css
xx.html
xx.js
xx.图片
xx.json
xx.字体
… 等等在前端使用的文件。这些文件的内容每次打开时,都是一样的,所以叫静态资源。
动态资源(也有接口)
后端的程序,如:二阶段学习的php文件
web服务器(软件)的作用:
1、接收前端请求
2、查找文件
3、执行服务器端代码
4、响应
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-u2txsSSJ-1615277071201)(C:\Users\31759\AppData\Roaming\Typora\typora-user-images\1608469841837.png)]
node完成了二阶段中apache和php的功能
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OWGZ2fBJ-1615277071213)(C:\Users\31759\AppData\Roaming\Typora\typora-user-images\1608469861652.png)]
nodeJS
介绍
后端的编程语言,与之类似有 php .net java ,python,go。不但是后端的编程语言,还可以搭建服务器,如:apche等。
nodeJS就是ECMAScirpt。在原来学习的ES的基础上增加了后端相关的API,如:HTTP,fs,URL等等。让javascript既可以做后端的开发,即一门语言搞定前后端,即全栈。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ECtE80Y2-1615277071218)(C:\Users\31759\AppData\Roaming\Typora\typora-user-images\1588329336678.png)]
前后端交互流程
后端渲染
用户 - > 地址栏(http[s]请求) -> web服务器(收到) - > nodejs处理请求(返回静态、动态)->请求数据库服务(返回结果)->nodejs(接收)->node渲染页面->浏览器(接收页面,完成最终渲染)
前端渲染
用户 - > http[s]请求 -> web服务器(收到) - > nodejs处理请求(返回静态、动态)->请求数据库服务(返回结果)->nodejs(接收)->返回给前端(渲染)->浏览器(接收页面,完成最终渲染)
目标
数据服务:连接数据库
文件服务:文件上传等等。
web服务:web服务器(如:apache)
优势
性能高,方便、对于前端人员来说入门难度低、大公司都在用(BAT)。
坊间传说:一台node的服务器顶得上86台php服务器。
劣势
- 服务器提供的相对较少
- 相对其他语言,能用的上的学习资料少
- 对程序员的要求高了
特点:
单线程:nodeJS是单线程的,那么如何面对并发,靠的是事件循环。
https://blog.csdn.net/jiang7701037/article/details/95887439
非阻塞 :
NodeJS在访问高IO操作后不会等待其完成,而是立即去执行其他代码,操作完成后会使用回调函数返回,保证高效的利用当前线程的cpu 不造成硬件浪费。
事件驱动:
通过事件来驱动整个程序的进行, 由于是单线程,所以把高IO的操作 就会移动到事件队列中等待完成,完成后通过回调函数的方式返回给线程来进行处理。这个循环处理的过程称之为:事件循环
环境安装
测试环境: win+r->命令行(运行->cmd)->node -v
版本
Vx(主).x(子).x(修正)
主版本: 变化了,1/3的API发生巨变 , 使用方式变化了
子版本: API没有删减,使用方式没变化,内部实现发生了变化
修正版: 什么都没变,处理一下bug
V6.8.0 稳定
V6.9.1 非稳定版
beta 测试
rc 、alpha测试稳定
开发工具介绍
IDE偏重,对机器要求高,功能齐全,
编辑器,轻便,速度快,功能后期补装插件
IDE
Hbuild WebStorm HbuildX Eclipse
编辑器
Atom Visual Studio Code Sublime Text
node命令行
node 回车
运行
window
a. 找到目标目录-》地址栏输入cmd-》node 文件名.js | node 文件名
b. 当前目录->右键->git bash-> node 文件名
苹果
终端->cd 目录-> node 文件名.js | node 文件名
vscode
新建终端->cd 目录->node 文件名.js | node 文件名
调试->运行
webstrom
terminal| run
注意
nodejs
使用的是ECMA
语法,不可使用DOM
,BOM
因为后端开发没有浏览器。
即:前端js代码在浏览器上运行;后端js代码在node环境里运行的。
web服务器的开发
(回顾二阶段)
1、搭建服务器 (http模块)
搭建服务器要使用http模块
1)、引入http模块
let http = require('http')
2)、创建web服务 返回http对象
let app = http.createServer((req,res)=>{
req 请求体(请求对象) 浏览器->服务器
req.url 地址 提取地址栏数据
req.on('data') 提取非地址栏数据 所有的http[s]都会触发end事件
req.on('end')
res 响应体(响应对象) 服务器->浏览器
res.writeHead(200,{'Content-Type':'text/html;charset=utf-8'});响应头设置
res.write(字符/数据<string><buffer>) 返回数据
res.end() 结束响应 必须
})
3)、监听服务器
app.listen(端口,[地址],[回调])
监听成功,回调一次
端口: 1-65535 1024以下系统占用
虚拟地址localhost 真实域名xx.duapp.com
4)、启动服务器的命令:
node 文件名
热部署和启动命令
由于,每次更新代码后, 需要重新启动服务器,很麻烦
推荐命令行工具:
supervisor
或者nodemon
安装方式:
npm install supervisor -g
或者npm install nodemon -g
启动服务器 nodemon 文件名
2、静态资源托管(fs模块)
fs:fileSystem; 这个模块可以读取文件的内容,给文件写内容,创建文件夹,删除文件夹等等有关文件和文件夹的一切操作。
一般来说,前端的如下代码都会请求一个静态资源
<a href=".."></a>
<img src="..."/>
location.href="..."
body{
background:url(....)
}
后端资源读取静态资源文件就要使用fs模块
fs.readFile(文件名,[编码方式],回调(err,data));
2.1 fs模块
磁盘操作,文件操作
读取
异步的方式:fs.readFile('文件路径',[编码方式],(err,data)=>{})
[^err ]: err 错误 ,null没有错误
同步的方式: let data = fs.readFileSync('文件路径')
处理错误
try{要排错的代码}catch(e){}
更名
fs.renameSync('改前','改后');
删除
fs.unlinkSync('文件路径')
2.2 path模块
path系统模块
操作系统磁盘路径
windows: c:\user\admin
磁盘的路径的分割是: \ 网络上的路径分割是 /
mac: ~/desktop/1901
API
磁盘路径解析 parse
path.parse('c:\\wamp\\xx.png') // string -> object
//返回
{
root: 'c:\\', 盘符
dir: 'c:\\wamp', 目录
base: 'xx.png', 文件名
ext: '.png', 扩展名
name: 'xx' 文件,不含扩展名
}
片段合并join
path.join('磁盘路径1','磁盘路径2','磁盘路径n')
__dirname 魔术变量 返回当前文件所在的磁盘路径
片段合并 resolve
path.resolve('磁盘路径1','磁盘路径n')
合并磁盘片段,右到左找,如果找到了根,那就不再朝前找了;拼接时,是从左到右拼接,如果没有给根路径,以当前文件路径为根(即默认:加上 __dirname)。
3、动态资源(接口实现)
前端
表单:get/post/put/delete/…
js: ajax/jsonp
后端(如同二阶段的php)
处理方式:http[s]
地址栏上的数据: req.url
抓取 get请求的数据 切字符 | url模块
非地址栏的数据 : req.on('data',(chunk)=>{CHUNK==每次收到的数据buffer})
req.on('end',()=>{ 接收完毕 切字符 querystring })
postman 一个不用写前端,就可以发出各种请求的软件 下载
3.1 url模块
作用
处理 url型的字符串
用法
url.parse(str,true) 返回 对象 true处理query为对象
str -> obj 返回 对象 true
protocol: ‘http:’, 协议
slashes: true, 双斜杠
auth: null, 作者
host: ‘localhost:8002’, 主机
port: ‘8002’, 端口
hostname: ‘localhost’, baidu
hash: ‘#title’, 哈希(锚)
search: ‘?username=sdfsdf&content=234234’, 查询字符串
query: ‘username=sdfsdf&content=234234’, 数据
pathname: ‘/aaa’, 文件路径
path: ‘/aaa?username=sdfsdf&content=234234’, 文件路径
href: ‘http://localhost:8002/aaa?username=sdfsdf&content=234234#title’
url.format(obj) 返回字符
obj -> str 返回str
3.2 querystring 模块
作用
处理查询字符串 如:?key=value&key2=value2
用法
querystring.parse(str) 返回对象
querystring.stringify(obj) 返回字符串
3.3 获取非地址栏的数据:
如:前端使用post发来的数据
使用:
req('data',(chunk)=>{
})
req('end',(err)=>{
})
模块化规范 commonJS
1、模块化的作用
1)、防止全局变量和全局函数重名,不污染全局变量。
2)、隐藏了细节
3)、js文件引用js文件。如果说前端还可以用html引入js文件的话,那么后端就不可能了,因为后端代码里没有html。
2、常见的模块化
前端模块化规范:CMD,AMD,ES6
后端的模块化规范:commonJS,ES6
3、规范是什么
如:
AMD是个规范,requireJS是AMD规范的体现
CMD是个规范,seaJS是CMD规范的体现
commonJS是个规范,node和webpack是commonJS规范的体现
ECMA是个规范,JS/AS是ECMA实现了它
4、commonJS的模块:
系统模块
http
fs
querystring
url
第三方模块:
gulp
自定义模块:
5、commonJS模块化格式:
1)、导入(引入)
let 变量名 = require('模块名') // 得到的是个对象
let 变量名 = require('模块名').xx 按需引用 //得到的是对象的某个属性
不指定路径:先找系统模块-> 再从项目环境找node_modules|bower_components (依赖模块)->not found
指定路径 : 找指定路径 -> not found
支持任何类型
所以:系统模块和第三方模块不需要写路径。而我们 的自定义模块需要写路径。
2)、导出(输出,对外开放)
exports.自定义属性 = 值( 任意类型)
可输出多次
如:exports.name = “张三疯”;
exports.sex = “男”;
exports.person= {
}
module.exports = 值( 任意类型)
只能输出一次,输出的为任意类型的数据,或者类。
如:
module.exports = {
}
module.exports = class Person{
constructor(){
}
}
第三方模块化的管理工具
1、NPM
作用
帮助你安装模块(包),并且自动安装所有的依赖,管理包(增,删,更新,项目所有包)。
npm服务器上放置了50多万的包,进行统一管理。
安装到全局(操作系统)环境
- 安装到电脑系统环境下(相当于给操作系统安装了一个软件,只不过,此时用的是npm安装而已)
- 使用时在任何位置都可以使用(因为,默认配置了环境变量)
- 被全局安装的通常是:命令行工具,脚手架
npm install 包名 -g 安装
npm uninstall 包名 -g 卸载
安装到项目环境
只能在当前目录使用,需要使用npm 代 运行
初始化项目环境
npm init //会自动产生package.json文件
package.json文件示例
{
"name": "npm", //项目名称
"version": "0.0.1", //版本
"description": "test and play", //描述
"main": "index.js", //入口文件
"dependencies": { //项目依赖(生产依赖) 上线也要用
"jquery": "^3.2.1"
},
"devDependencies": { //开发依赖 上线就不用
"gulp": "^3.5.2"
},
"scripts": { //命令行
"test": "命令行",
},
"repository": { //仓库信息
"type": "git",
"url": "git+https://github.com/tianwater.github.io/2017-8-28.git"
},
"keywords": [ //关键词,github上搜索时,可以使用该关键字
"test",'xx','oo'
],
"author": "tianwater",
"license": "ISC", //认证
"bugs": {
"url": "https://github.com/alexwa9.github.io/2017-8-28/issues"//问题提交
},
"homepage": "https://github.com/alexwa9.github.io/2017-8-28#readme"//首页
}
项目依赖(生产依赖)
不但在当前项目下需要使用,上线了,也需要这个依赖 --save
//安装
npm i 包名 --save //安装最新版本的包
npm install 包名 -S // --save可以简写为 -S
npm install 包名@x.x.x -S //安装指定版本的包
//卸载
npm uninstall 包名 --save
npm uninstall 包名 -S
安装了项目依赖后,会产生一个package-lock.json,这个文件千万不要删除
{
"name": "nodetest",
"version": "1.0.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
"jquery": { //报名
"version": "3.5.0", //版本号
"resolved": "https://registry.npm.taobao.org/jquery/download/jquery-3.5.0.tgz?cache=0&sync_timestamp=1586533502771&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fjquery%2Fdownload%2Fjquery-3.5.0.tgz", //安装来源
"integrity": "sha1-mYC5fZ5BlGEcNlMOfcRqWNc0D8k=" //迭代的id
}
}
}
package-lock.json文件的产生(这个可以以后再理解):
Node.js v8.0 后,npm 也升级到了5.0,其中package-lock.json文件就是npm5开始有的。
- package.json文件下载到的依赖包可能在不同的情况下,各库包的版本语义可能并不相同,有的库包开发者并不严格遵守这一原则:相同大版本号的同一个库包,其接口符合兼容要求。所以说,在不同时间或者不同npm下载源之下,下载的各依赖包版本可能有所不同,因此其依赖库包行为特征也不同,有时候甚至完全不兼容。
- package-lock.json文件所标识的具体版本下载依赖库包(包的安装来源),就能确保到一个新的机器上所有库包与上次的安装完全一样。
- npm的下载源改为私服地址,这样产生的package-lock.json文件的版本号是这个私服上设置好的版本号
场景:
如果在git上下载了别人的代码,或者你的代码拷贝到其它机子上,一般不会拷贝node_modules文件夹。在新的机子上执行命令: npm i 。那么npm会根据package.json里的配置安装所有的依赖,具体的包来自哪个来源,在package-lock.json里。
开发依赖
只能在当前项目下使用 上线了,依赖不需要了 --save-dev
npm install 包名 --save-dev
npm install 包名 -D
npm代运行
即:使用npm执行 package.json文件里的scripts属性里的内容(叫作 npm脚本)
如:
package.json里这样写:
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "node ./app.js",
"n":"node" //全局
"j":"jQuery" //项目依赖
},
命令行执行 npm run start 就相当于执行 node ./app.js
另外,start属性可以不用加run,其它属性需要加run。即:npm start 就相当于npm run start
命令行执行 npm run n 就相当于执行 node
命令行执行 npm run j 就相当于执行 jQuery
查看包
npm list 列出项目里所有已装包
npm outdated 版本对比(安装过得包),查看项目中安装的包和npm服务器上的包有没有版本上的不同
npm info 包名 查看当前包概要信息
npm view 包名 versions 查看包历史版本,如果想知道jQuery都有哪些版本:npm view jquery versions
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cpr0mCHp-1615277071223)(C:\Users\31759\AppData\Roaming\Typora\typora-user-images\1588393896079.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CIJFc16p-1615277071226)(C:\Users\31759\AppData\Roaming\Typora\typora-user-images\1588394040179.png)]
current:当前项目中安装的版本号;
wanted:在你安装的当前主版本号里,推荐你使用的子版本号
latest:最新版本号
安装所有依赖
npm install
安装package.json里面指定的所有包
版本约束
^x.x.x 约束主版本,重新安装时,后面两位找最新
~x.x.x 保持前两位不变,重新安装时,最后一位找最新
* 重新安装时,永远装最新的版本
x.x.x 定死了一个版本
选择源(选择最快的源进行安装)
npm install nrm -g 安装选择源的工具包
nrm ls 查看所有源
nrm test 测试所有源,可以看到当前哪个源的速度快
nrm use 切换源名 ,切换到最快的源
安装卡顿时
ctrl+c -> npm uninstall 包名 -> npm cache clean 清除npm的缓存 -> 换移动数据(开热点)-> npm install 包名
发布包
-
官网 注册
-
登录(用命令行)
- 在项目目录下输入:npm login (注意:一定把源切换到npm,不要用其它的镜像)
- 输入 user/password/email
-
创建包(写项目)
npm init -y
- 创建入口index.js
- 编写,输出
-
发布
-
npm publish
注意:发布前,首先需要确定 包名(package.json里的name属性)是否在npm的服务器上存在。进入 npm 官网,搜索一下包名:[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sLPkjDXk-1615277071228)(C:\Users\31759\AppData\Roaming\Typora\typora-user-images\1588408182571.png)]
把目前切换到当前项目下,然后,输入npm publish。
-
-
迭代
- 修改版本号
npm publish
-
删除
npm unpublish
包的发布、迭代、删除,需要在包目录下进行
删除包,有时需要发送邮件
2、YARN
安装
注意:为省事,不要用npm i yarn -g,去安装yarn,而是去下载压缩包,保证注册表和环境变量的硬写入,后期通过yarn安装全局包时方便(否则,可能会装不上)
使用
初始化一个新项目
yarn init
添加依赖包
yarn add [package]
yarn add [package]@[version]
yarn add [package]@[tag]
将依赖项添加到不同依赖项类别中
分别添加到 dependencies
,devDependencies
、peerDependencies
和 optionalDependencies
类别中:
yarn add [package] --save | -S
yarn add [package] --dev | -D
yarn add [package] --peer
yarn add [package] --optional
升级依赖包
yarn upgrade [package]
yarn upgrade [package]@[version]
yarn upgrade [package]@[tag]
移除依赖包
yarn remove [package]
安装项目的全部依赖
yarn
或者
yarn install
安装到全局
yarn global add [package] //global的位置测试不能变,global不能写在最后
yarn global remove [package]
3、BOWER
安装bower
npm install -g bower
安装包到全局环境
bower i 包名 -g 安装
bower uninstall 包名 -g 卸载
安装包到项目环境
初始化项目环境
bower init
bower.json 第三方包管理配置文件
项目依赖
只能在当前项目下使用,上线了,也需要这个依赖 --save
//安装
同npm
bower install 包名#x.x.x -S 指定版本使用#
//卸载
同npm
开发依赖
只能在当前项目下使用 ,上线了,依赖不需要了 --save-dev
同npm
EXPRESS框架
nodejs库,不用基础做起,工作简单化,点击进入官网,类似的还有 koa
特点
二次封装,非侵入式,增强形
二次封装:保留了原来的功能,做了进一步的增加。
安装
1、全局安装
npm install express -g
npm install express-generator -g(mac系统中一般没有问题,windows系统下建议安装)
express -h 测试是否安装成功
2、搭建项目,局部安装
1)、新建项目目录
2)、初始化项目:npm init -y
3)、本地安装express:npm i express --save
搭建web服务
let express=require('express')
let app=express(