1、nodejs基本概念
什么是nodejs
- 就是一个服务器端的JS运行环境,可以让程序员通过JS做后台服务器编程开发
electronjs 基于html,css,js搭建的桌面应用
系统环境变量介绍
- 在桌面打开终端工具,直接输入node -v 能够显示node的版本号,
- 直接输入命令能够运行的原因
- 是因为程序会先在当前目录中查找node,如果当前目录中没有,默认会去系统环境变量中查找,如果系统环境变量中并没有配置此程序,这时终端会报错
- 直接输入命令能够运行的原因
- 环境变量的作用
- 通过终端输入命令的形式,快速启动应用程序,路径的查找规则
通过node直接运行js文件
在终端中打开要运行的js文件,输入node 要执行的js文件名称 回车
小技巧
- 在终端中,使用键盘上箭头,可以快速定位到上一次执行的命令
- 在终端中,使用键盘的tab键能够快速不全路径
- windows系统上,在终端中输入
cls可以清屏
REPL环境
- **如何进入REPL环境:**打开任意终端,直接输入node并回车,就会进入到REPL环境中
- **如何离开REPL环境:**按两次
ctrl+c就能退出REPL环境 - REPL中,每个字母代表的意思:
- **R:**Read,每当我们输入代码完毕之后,只要敲击回车,Node环境就会读取用户输入的代码
- **E:**Evaluate的意思,表示把Read进来的用户代码,调用类似于Eval的函数,去解析执行
- **P:**Print,把第二步中解析执行的结果,输出给用户
- **L:**Loop,表示当输出完毕之后,进入下一次的REP循环
启动vscode终端的命令
ctrl+\ 启动终端
2、ES6常用语法
Let与Const
var关键字有如下优缺点:- 存在变量提升问题,降低js代码的可阅读性
- 没有块级作用域,容易造成变量污染
let主要特性:- 不存在变量提升问题,只有定义之后才能使用此变量
- 有
{}作用域
const主要特性:- 不存在变量提升问题,只有定义之后才能使用
- const定义的常量,无法被重新赋值
- 定义常量的时候,必须定义且初始化,否则会报语法错误
- const定义的常量也有块级作用域
解构赋值
3、模块和包
自定义模块
一个js文件,就能称为一个模块
- 在js中向外
导出成员- 方法一:
- exports.属性名 = 属性值;
- 方法二:
- module.exports = 属性值;
一个模块中只能有一个module.exports
- module.exports = 属性值;
- 方法一:
- 在一个js文件中引入另外一个js文件
- 方法一:
- let 变量名 = require('./xx.js');
- 方法一:
3.1、 核心模块(内置模块)
- 什么是核心模块:
- 随着Node.js的安装包,一同安装到本地的模块,叫做核心模块;
- 例如:
fs,path等模块,都是由Node.js官方提供的核心模块; - 只要大家在计算机中,安装了Node这个应用程序,那么,我们的计算机中就已经安装了所有的 核心模块;
- 如何使用核心模块:
require('核心模块标识符')
3.2 第三方模块
- 什么是第三方模块:
- 一些非官方提供的模块,叫做第三方模块;
- 注意,第三方模块,并不在我们的计算机上;
- 如果大家需要使用某些第三方模块,必须去一个叫做
NPM的网站上搜索并下载才能使用;
- 如何使用第三方模块:
- 先从 npm 官网上下载指定的第三方模块
- 使用
require('第三方模块的名称标识符')来导入这个模块 - 根据 第三方模块的 官方文档,尝试使用
3.3 用户自定义模块
- 什么是用户模块:
- 程序员在自己项目中写的 Javascript 文件,就叫做 用户自定义模块;
- 如何使用用户模块:
require('路径标识符')
模块化定义
可以认为是一种明文的规定,大家都按照相同的约定写代码,减少了不必要的沟通成本,极大的方便了各个模块之间的调用,方便了自己,同时也方便了别人
模块作用域和全局作用域
模块作用域
每个JS文件,都是一个单独的模块,每个模块都有自己独立的作用域,因此:模块中的成员,默认无法被其它模块访问
全局作用域
全局作用域使用global来访问,类似于浏览器中的window
使用 global 全局作用域在模块之间共享成员
- 如果在某个模块内部,想为 全局的 global 作用域挂载一些属性,需要显示的调用
global.***来挂载; - 注意:在开发中,一般情况下,不推荐使用
global全局作用域来共享成员,会存在全局变量污染问题;
module.exports和exports的关系
-
module.exports
module.exports = a; -
exports
exports = a;-
module.exports和exports默认引用了同一个空对象; -
module.exports和exports作用一致,都可以向外暴露成员; -
一个模块作用域中,向外暴露私有成员时,永远以
module.exports为准;// 1.js文件 let a = 10; let b = 20; exports = a; module.exports = b; // 2.js 文件 const A = require('1.js'); console.log(A); // 20 ==> 一个模块中向外暴露成员时,永远以module.exports为准
-
7.1.1 核心模块
- 什么是核心模块:
- 随着Node.js的安装包,一同安装到本地的模块,叫做核心模块;
- 例如:
fs,path等模块,都是由Node.js官方提供的核心模块; - 只要大家在计算机中,安装了Node这个应用程序,那么,我们的计算机中就已经安装了所有的 核心模块;
- 如何使用核心模块:
require('核心模块标识符')
4、浏览器端AMD和CMD模块化规范
注意:浏览器端不能使用CommonJs规范,因为CommonJS下模块是同步的,浏览器端都是异步的
AMD/CMD可以理解为commonjs在浏览器端的解决方案,AMD/CMD下,模块都是异步加载的
- AMD模块化规范代表:RequireJs
- 特征一:对于依赖的模块,AMD都是提前执行
- 特征二:推崇依赖前置
- CMD模块化规范代表:SeaJs
- 对于依赖的模块,延迟执行
- 推崇依赖就近
5、文件介绍
- package.json
name包名version版本号main指定包入口文件
- bin目录存放二进制文件
- lib目录 所有的js文件都放到lib目录
6、安装和卸载本地包
- **什么是本地的包:**跟着项目安装的包,叫做本地包;本地包都会被安装到 node_modules 目录下;
- **注意:**如果拿到一个空项目,必须在当前项目根目录中,先运行
npm init或者npm init -y命令,初始化一个package.json的配置文件,否则包无法安装到本地项目中; - **如何安装本地包:**运行
npm i 包名 --save即可安装本地包;都安装到了当前项目的node_modules目录下;- 如果大家用的是npm 5.x的版本,可以不指定
--save命令,如果用的是 npm 3.x 的版本,则需要手动指定--save;
- 如果大家用的是npm 5.x的版本,可以不指定
package-lock.json文件中记录了曾经装过的包的下载地址,方便下次直接下载包,能够加快装包的速度,提升装包的体验;- **如何卸载本地包:**使用
npm uninstall/remove 包名 -S/-D即可卸载指定的本地包;
7、其它常用命令
--save的缩写是-S--save-dev的缩写是-Dinstall的缩写是i- 注意:
dependencies节点,表示项目上线部署时候需要的依赖项;devDependencies节点,表示项目在开发阶段需要的依赖项,但是当项目要部署上线了,devDependencies节点中的包,就不再需要了! - 注意:当使用
npm i快速装包的时候,npm会检查package.json文件中,所有的依赖项,然后都为我们安装到项目中 --production表示只安装dependencies节点下,记录的包,不安装devDependencies节点下的包;当项目要上线了,才会使用--production命令
8、使用Node构建web应用
8.1 实现一个类似于Apache的 静态资源服务器
使用
http核心模块,创建最基本的web服务器
-
创建最基本的web服务器
- **创建服务器:**使用
const server = http.createServer()创建服务器; - **绑定监听事件:**通过
server.on('request', function(req, res) { 请求的处理函数 })绑定事件 并 指定 处理函数; - **启动服务器:**通过
server.listen(端口, IP地址, 启动成功的回调函数)来启动服务器;
- **创建服务器:**使用
-
防止响应内容中文乱码问题
-
通过 设置响应报文头的
Content-Type,来指定响应内容的编码类型,从而防止乱码:res.writeHeader(200, { 'Content-Type': 'text/plain; charset=utf-8' })
-
-
根据不同的URL返回不同的文本内容
- 使用
req.url获取客户端请求的URL地址
- 使用
-
根据不同的URL返回不同的HTML页面
- 主要思路:使用
fs 模块读取URL对应的HTML页面内容,并使用res.end()响应给客户端即可;
- 主要思路:使用
-
处理并返回css样式表
-
处理并返回Javascript文件
-
优化
-
8.2 可以端以不同的格式解析服务器返回的内容
text/plain文本text/htmlhtml标签image/jpgimage/pngimage/gif
8.3 res.end()方法
res.end()方法接收两种数据类型,String,二进制类型的数据字符串在进行网络传输的时候,需要先转换为二进制文件,之后再传送给客户端
9、 使用 nodemon 工具来自动重启web服务器
- nodemon的作用:能够实时监听当前项目中,文件的变化;只要监听到了文件的变化,则 nodemon 工具,会自动重新启动 web 服务器,从而使最新的代码生效;免去了程序员手动重启服务器的困扰;
- **如何安装:**运行
npm i nodemon -g全局安装即可; - 如何使用:
- 之前使用
node 要执行的文件路径来运行 Node.js 代码; - 现在使用
nodemon 要执行的文件路径来运行 Node.js 代码;
- 之前使用
- **注意:**今后在开发Web项目的时候,推荐使用
nodemon来启动 web 服务器
10、express
10.1、express框架的特点
- 基于Node.js平台之上,进一步封装了
http模块,从而提供了更好用,更友好的 API - 使用Express创建网站,比使用原生的http模块更加方便;
- Express 并没有覆盖 原生 http 模块中的方法,而是基于 原生方法之上,做了更友好的封装,让用户体验更好
10.2、 express 框架的安装和基本使用
- **安装:**运行
npm i express -S即可安装 - 创建基本的
express服务器:- 导入
express第三方模块; - **创建服务器的实例:**调用
const app = express()方法; - 通过
app.get()或app.post()方法,来监听客户端的get或post请求,具体语法:- 监听
GET请求:app.get('请求地址', (req, res) => { 处理函数 }) - 监听
POST请求:app.post('请求地址', (req, res) => { 处理函数 })
- 监听
- **启动 express 服务器:**通过
app.listen(端口, IP地址, 启动成功后的回调函数)启动服务器;
- 导入
10.3、使用 express.static() 快速托管静态资源
如果我们网站中,有很多静态资源需要被外界访问,此时,使用 res.sendFile 就有点力不从心了;
这时候,express 框架,为我们提供了
express.static('静态资源目录')来快速托管指定目录下的所有静态资源文件;
- 语法1:
app.use(express.static('public'));app.use()方法,是专门用来注册 中间件;express.static是express的内置中间件;
- 语法2:
app.use('/虚拟目录', express.static('public'))
10.4、 为 express 框架配置模板引擎渲染动态页面
- 安装 ejs 模板引擎
npm i ejs -S - 使用 app.set() 配置默认的模板引擎
app.set('view engine', 'ejs') - 使用 app.set() 配置默认模板页面的存放路径
app.set('views', '模板页面的具体存放路径') - 使用 res.render() 来渲染模板页面
res.render('index.ejs', { 要渲染的数据对象 }),注意,模板页面的 后缀名,可以省略不写!
ejs_pages/index.ejs
index.ejs类似与index.html只不过二者的后缀名不同- 在index.ejs中使用动态变量
<%= name %>=代表输出的意思 如果不写=表示是一个语句
10.5 、在 express 中配置 art-template
- 安装 两个包
cnpm i art-template express-art-template -S - 自定义一个模板引擎
app.engine('自定义模板引擎的名称', 渲染函数) - 将自定义的模板引擎,配置为 express 的默认模板引擎
app.set('view engine', '具体模板引擎的名称') - 配置 模板页面得存放路径
app.set('views', '路径')
使用 express 框架中提供的路由来分发请求
路由就是请求地址到处理函数之间的对应关系
- **什么是路由:**路由就是对应关系;
- **什么叫做后端路由:**前端请求的URL地址,都要对应一个后端的处理函数,那么 这种URL地址到 处理函数之间的对应关系,就叫做后端路由;
- 在Express中,路由的主要职责 就是 把请求分发到对应的处理函数中;
- 在Express中,如何 定义并使用路由呢?
// 1. 封装单独的 router.js 路由模块文件
const express = require('express')
// 创建路由对象
const router = express.Router()
router.get('/', (req, res)=>{})
router.get('/movie', (req, res)=>{})
router.get('/about', (req, res)=>{})
// 导出路由对象
module.exports = router
- express 创建的 app 服务器,如何使用 路由模块呢?
// 导入自己的路由模块
const router = require('./router.js')
// 使用 app.use() 来注册路由
app.use(router)
Express 框架里 中间件的概念
1.1、什么是中间件
在应用程序开发中,每一个处理环节,都是中间件
中间件之间要共享数据,有先后的调用顺序
定义:中间件就是一个处理函数;只不过这个函数比较特殊,包含了三个参数,分别是
req,res,next注意:中间件方法中的三个参数:
- req:请求对象;
- res:响应对象;
- next:next()可以被调用,表示调用下一个中间件方法;
模块加载机制
1、核心模块的加载机制
- 先查找缓存:如果缓存中没有,再去加载核心模块
2、用户模块的加载机制
-
先查找缓存
-
如果缓存中没有则尝试加载用户模块
-
如果在加载用户模块时,省略了后缀名,则
首先按照严格指定的名称去查找 其次 ==》.js ==》.json ==》.node
node搭建项目
基本搭建
npm init -y初始化一个项目npm i express -S安装expressnpm i mysql -S安装数据库npm i cors -S解决node端的跨域 与ajax中的jsonp类似
es6解构赋值
- 左右两边结构必须一样
- 右边必须是个东西
- 声明和赋值不能分开,必须在一句话里完成
let [a,b,c] = [1,2,3];
console.log(a,b,c); // 1,2,3
let {a,b,c} = {4,5,6};
console.log(a,b,c); // 4,5,6
es6函数
-
调用函数传递的参数不固定(收集剩余的参数)
-
function test(a,b, ...args){} test(1,2,3,4);
-
-
展开数组
-
展开后的效果,跟直接把数组的内容写在这是是一样的let arr = [1,2,4,5]; ...arr ==> 1,2,4,5
-
map的用法
-
映射
一个对一个
-
汇总
求数组中每一项相加得到的和
-
过滤器
-
对数组中的元素进行筛选,返回符合条件的 -
-
es6字符串
-
startsWith与endsWith -
模板字符串
-
let s = 9; let result = `aaa${s}mmm`; ==> aaa9mmm
-
es6中的json
-
json的标准写法- 只能用双引号,不能出现单引号
- 所有的名字都必须用引号包起来
-
将json格式的数据变为字符串let json = {a:1,b:2} console.log(JSON.stringify(json)); // 将json格式的数据变为字符串