nodejs

1,511 阅读13分钟

1、nodejs基本概念

什么是nodejs

  • 就是一个服务器端的JS运行环境,可以让程序员通过JS做后台服务器编程开发

electronjs 基于html,css,js搭建的桌面应用

系统环境变量介绍

  • 在桌面打开终端工具,直接输入node -v 能够显示node的版本号,
    • 直接输入命令能够运行的原因
      • 是因为程序会先在当前目录中查找node,如果当前目录中没有,默认会去系统环境变量中查找,如果系统环境变量中并没有配置此程序,这时终端会报错
  • 环境变量的作用
    • 通过终端输入命令的形式,快速启动应用程序,路径的查找规则

通过node直接运行js文件

在终端中打开要运行的js文件,输入node 要执行的js文件名称 回车

小技巧

  1. 在终端中,使用键盘上箭头,可以快速定位到上一次执行的命令
  2. 在终端中,使用键盘的tab键能够快速不全路径
  3. windows系统上,在终端中输入cls可以清屏

REPL环境

  1. **如何进入REPL环境:**打开任意终端,直接输入node并回车,就会进入到REPL环境中
  2. **如何离开REPL环境:**按两次ctrl+c就能退出REPL环境
  3. REPL中,每个字母代表的意思:
    • **R:**Read,每当我们输入代码完毕之后,只要敲击回车,Node环境就会读取用户输入的代码
    • **E:**Evaluate的意思,表示把Read进来的用户代码,调用类似于Eval的函数,去解析执行
    • **P:**Print,把第二步中解析执行的结果,输出给用户
    • **L:**Loop,表示当输出完毕之后,进入下一次的REP循环

启动vscode终端的命令

ctrl+\ 启动终端

2、ES6常用语法

Let与Const

  1. var关键字有如下优缺点:
    • 存在变量提升问题,降低js代码的可阅读性
    • 没有块级作用域,容易造成变量污染
  2. let主要特性:
    • 不存在变量提升问题,只有定义之后才能使用此变量
    • {}作用域
  3. const主要特性:
    • 不存在变量提升问题,只有定义之后才能使用
    • const定义的常量,无法被重新赋值
    • 定义常量的时候,必须定义且初始化,否则会报语法错误
    • const定义的常量也有块级作用域

解构赋值

3、模块和包

自定义模块

一个js文件,就能称为一个模块

  • 在js中向外导出成员
    • 方法一:
      • exports.属性名 = 属性值;
    • 方法二:
      • module.exports = 属性值;一个模块中只能有一个module.exports
  • 在一个js文件中引入另外一个js文件
    • 方法一:
      • let 变量名 = require('./xx.js');

3.1、 核心模块(内置模块)

  1. 什么是核心模块:
    • 随着Node.js的安装包,一同安装到本地的模块,叫做核心模块;
    • 例如:fspath等模块,都是由Node.js官方提供的核心模块;
    • 只要大家在计算机中,安装了Node这个应用程序,那么,我们的计算机中就已经安装了所有的 核心模块;
  2. 如何使用核心模块require('核心模块标识符')

3.2 第三方模块

  1. 什么是第三方模块:
    • 一些非官方提供的模块,叫做第三方模块;
    • 注意,第三方模块,并不在我们的计算机上;
    • 如果大家需要使用某些第三方模块,必须去一个叫做 NPM 的网站上搜索并下载才能使用;
  2. 如何使用第三方模块:
    • 先从 npm 官网上下载指定的第三方模块
    • 使用 require('第三方模块的名称标识符')来导入这个模块
    • 根据 第三方模块的 官方文档,尝试使用

3.3 用户自定义模块

  1. 什么是用户模块:
    • 程序员在自己项目中写的 Javascript 文件,就叫做 用户自定义模块;
  2. 如何使用用户模块:require('路径标识符')

模块化定义

可以认为是一种明文的规定,大家都按照相同的约定写代码,减少了不必要的沟通成本,极大的方便了各个模块之间的调用,方便了自己,同时也方便了别人

模块作用域和全局作用域

模块作用域

每个JS文件,都是一个单独的模块,每个模块都有自己独立的作用域,因此:模块中的成员,默认无法被其它模块访问

全局作用域

全局作用域使用global来访问,类似于浏览器中的window

使用 global 全局作用域在模块之间共享成员
  1. 如果在某个模块内部,想为 全局的 global 作用域挂载一些属性,需要显示的调用global.***来挂载;
  2. 注意:在开发中,一般情况下,不推荐使用global全局作用域来共享成员,会存在全局变量污染问题;

module.exports和exports的关系

  • module.exports

    module.exports = a;
    
  • exports

    exports = a;
    
    1. module.exportsexports 默认引用了同一个空对象;

    2. module.exportsexports 作用一致,都可以向外暴露成员;

    3. 一个模块作用域中,向外暴露私有成员时,永远以 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 核心模块

  1. 什么是核心模块:
    • 随着Node.js的安装包,一同安装到本地的模块,叫做核心模块;
    • 例如:fspath等模块,都是由Node.js官方提供的核心模块;
    • 只要大家在计算机中,安装了Node这个应用程序,那么,我们的计算机中就已经安装了所有的 核心模块;
  2. 如何使用核心模块require('核心模块标识符')

4、浏览器端AMD和CMD模块化规范

注意:浏览器端不能使用CommonJs规范,因为CommonJS下模块是同步的,浏览器端都是异步的

AMD/CMD可以理解为commonjs在浏览器端的解决方案,AMD/CMD下,模块都是异步加载的

  1. AMD模块化规范代表:RequireJs
    • 特征一:对于依赖的模块,AMD都是提前执行
    • 特征二:推崇依赖前置
  2. CMD模块化规范代表:SeaJs
    • 对于依赖的模块,延迟执行
    • 推崇依赖就近

5、文件介绍

  • package.json
    • name 包名
    • version 版本号
    • main 指定包入口文件
  • bin目录存放二进制文件
  • lib目录 所有的js文件都放到lib目录

6、安装和卸载本地包

  1. **什么是本地的包:**跟着项目安装的包,叫做本地包;本地包都会被安装到 node_modules 目录下;
  2. **注意:**如果拿到一个空项目,必须在当前项目根目录中,先运行 npm init或者npm init -y 命令,初始化一个package.json的配置文件,否则包无法安装到本地项目中;
  3. **如何安装本地包:**运行npm i 包名 --save 即可安装本地包;都安装到了当前项目的 node_modules目录下;
    • 如果大家用的是npm 5.x的版本,可以不指定--save命令,如果用的是 npm 3.x 的版本,则需要手动指定 --save
  4. package-lock.json文件中记录了曾经装过的包的下载地址,方便下次直接下载包,能够加快装包的速度,提升装包的体验;
  5. **如何卸载本地包:**使用 npm uninstall/remove 包名 -S/-D即可卸载指定的本地包;

7、其它常用命令

  1. --save 的缩写是 -S
  2. --save-dev的缩写是 -D
  3. install 的缩写是 i
  4. 注意:dependencies 节点,表示项目上线部署时候需要的依赖项;devDependencies节点,表示项目在开发阶段需要的依赖项,但是当项目要部署上线了,devDependencies节点中的包,就不再需要了!
  5. 注意:当使用 npm i快速装包的时候,npm会检查package.json文件中,所有的依赖项,然后都为我们安装到项目中
  6. --production 表示只安装 dependencies 节点下,记录的包,不安装devDependencies节点下的包;当项目要上线了,才会使用--production命令

8、使用Node构建web应用

8.1 实现一个类似于Apache的 静态资源服务器

使用http核心模块,创建最基本的web服务器

  1. 创建最基本的web服务器

    • **创建服务器:**使用 const server = http.createServer() 创建服务器;
    • **绑定监听事件:**通过 server.on('request', function(req, res) { 请求的处理函数 }) 绑定事件 并 指定 处理函数;
    • **启动服务器:**通过 server.listen(端口, IP地址, 启动成功的回调函数) 来启动服务器;
  2. 防止响应内容中文乱码问题

    • 通过 设置响应报文头的 Content-Type,来指定响应内容的编码类型,从而防止乱码:

      res.writeHeader(200, { 
      	'Content-Type': 'text/plain; charset=utf-8'
      })
      
  3. 根据不同的URL返回不同的文本内容

    • 使用 req.url 获取客户端请求的URL地址
  4. 根据不同的URL返回不同的HTML页面

    • 主要思路:使用 fs 模块 读取URL对应的HTML页面内容,并使用 res.end() 响应给客户端即可;
  5. 处理并返回css样式表

  6. 处理并返回Javascript文件

  7. 优化

  8. 1564218803416

8.2 可以端以不同的格式解析服务器返回的内容
  • text/plain 文本
  • text/html html标签
  • image/jpg image/png image/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框架的特点

  1. 基于Node.js平台之上,进一步封装了 http 模块,从而提供了更好用,更友好的 API
  2. 使用Express创建网站,比使用原生的http模块更加方便;
  3. Express 并没有覆盖 原生 http 模块中的方法,而是基于 原生方法之上,做了更友好的封装,让用户体验更好

10.2、 express 框架的安装和基本使用

  1. **安装:**运行 npm i express -S 即可安装
  2. 创建基本的 express 服务器:
    • 导入 express 第三方模块;
    • **创建服务器的实例:**调用 const app = express() 方法;
    • 通过 app.get()app.post() 方法,来监听客户端的 getpost 请求,具体语法:
      • 监听 GET 请求:app.get('请求地址', (req, res) => { 处理函数 })
      • 监听 POST 请求: app.post('请求地址', (req, res) => { 处理函数 })
    • **启动 express 服务器:**通过 app.listen(端口, IP地址, 启动成功后的回调函数) 启动服务器;

10.3、使用 express.static() 快速托管静态资源

如果我们网站中,有很多静态资源需要被外界访问,此时,使用 res.sendFile 就有点力不从心了;

这时候,express 框架,为我们提供了 express.static('静态资源目录')

来快速托管指定目录下的所有静态资源文件;

  1. 语法1: app.use(express.static('public'));
    • app.use()方法,是专门用来注册 中间件;
    • express.static 是express的内置中间件;
  2. 语法2:app.use('/虚拟目录', express.static('public'))

10.4、 为 express 框架配置模板引擎渲染动态页面

  1. 安装 ejs 模板引擎npm i ejs -S
  2. 使用 app.set() 配置默认的模板引擎 app.set('view engine', 'ejs')
  3. 使用 app.set() 配置默认模板页面的存放路径 app.set('views', '模板页面的具体存放路径')
  4. 使用 res.render() 来渲染模板页面res.render('index.ejs', { 要渲染的数据对象 }),注意,模板页面的 后缀名,可以省略不写!

1565668323019

ejs_pages/index.ejs

  • index.ejs 类似与 index.html 只不过二者的后缀名不同
  • 在index.ejs中使用动态变量<%= name %> = 代表输出的意思 如果不写= 表示是一个语句

1565668339843

10.5 、在 express 中配置 art-template

  1. 安装 两个包 cnpm i art-template express-art-template -S
  2. 自定义一个模板引擎 app.engine('自定义模板引擎的名称', 渲染函数)
  3. 将自定义的模板引擎,配置为 express 的默认模板引擎 app.set('view engine', '具体模板引擎的名称')
  4. 配置 模板页面得存放路径 app.set('views', '路径')

使用 express 框架中提供的路由来分发请求

路由就是请求地址到处理函数之间的对应关系

  1. **什么是路由:**路由就是对应关系;
  2. **什么叫做后端路由:**前端请求的URL地址,都要对应一个后端的处理函数,那么 这种URL地址到 处理函数之间的对应关系,就叫做后端路由;
  3. 在Express中,路由的主要职责 就是 把请求分发到对应的处理函数中
  4. 在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
  1. express 创建的 app 服务器,如何使用 路由模块呢?
  // 导入自己的路由模块
  const router = require('./router.js')
  // 使用 app.use() 来注册路由
  app.use(router)

Express 框架里 中间件的概念

1.1、什么是中间件

在应用程序开发中,每一个处理环节,都是中间件

中间件之间要共享数据,有先后的调用顺序

定义:中间件就是一个处理函数;只不过这个函数比较特殊,包含了三个参数,分别是 reqresnext

注意:中间件方法中的三个参数:

  • req:请求对象;
  • res:响应对象;
  • next:next()可以被调用,表示调用下一个中间件方法;

模块加载机制

1、核心模块的加载机制

  • 先查找缓存:如果缓存中没有,再去加载核心模块

2、用户模块的加载机制

  • 先查找缓存

  • 如果缓存中没有则尝试加载用户模块

  • 如果在加载用户模块时,省略了后缀名,则

    首先按照严格指定的名称去查找
    其次 ==》.js ==》.json ==》.node
    

node搭建项目

基本搭建

  • npm init -y 初始化一个项目
  • npm i express -S 安装express
  • npm 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的用法

  • 映射

    • 一个对一个
    • 1567919491309
  • 汇总

    • 求数组中每一项相加得到的和
    • 1567922374992
  • 过滤器

    • 对数组中的元素进行筛选,返回符合条件的

    • 1567923205628

es6字符串

  • startsWithendsWith

    • 1567923762825
  • 模板字符串

    • let s = 9;
      let result = `aaa${s}mmm`; ==> aaa9mmm
      

es6中的json

  • json的标准写法

    1. 只能用双引号,不能出现单引号
    2. 所有的名字都必须用引号包起来
  • 将json格式的数据变为字符串

     let json = {a:1,b:2}
     console.log(JSON.stringify(json)); // 将json格式的数据变为字符串