NodeJS 介绍

NodeJS 是什么

  • Node.js is a JavaScript runtime built on Chrome’s V8 (不可以使用JS 全集)
  • Node.js uses an event-driveb, non-blocking I/O model

非阻塞I/O

  • 阻塞:I/O时进程休眠等待I/O 完成后进行下一步
  • 非阻塞:I/O时函数立即返回, 进程不等待I/O完成

事件驱动

  • I/O等异步操作结束后的通知
  • 观察者模式

为什么偏爱NodeJs

  • 前端职责范围变大, 统一开发体验
  • 在处理高并发、I/O 密集场景性能优势明显

CPU密集 VS I/O密集

  • CPU密集: 大部分时间在做计算、逻辑判断等CPU动作 (压缩、解压、加密、解密)
  • I/O密集: 大部分时间在做存取设备、网络设施的读取操作(文件操作、网络操作、数据库)
    • web常见场景
      • 静态资源读取
      • 数据库操作
      • 渲染页面

高并发应对之道

  • 增加机器数
  • 增加每台机器的CPU数——多核(运算能力增强)

相关基础知识

  • 进程
    • 计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位
    • 多进程:启动多个进程,多个进程可以一块执行多个任务
    • 单台CPU同时可以运行多进程的原因
      • 类似于动画片原理,以人肉眼感知不到打速度在多个任务(进程)之间来回切换
  • 线程
    • 进程内一个相对独立、可调度的执行单元,与同属一个进程的线程共享进程的资源
    • 启动一个进程可以在进程内启动多个线程,多个线程可以一块执行多个任务
  • I/O分类及详细解释
  • NodeJs 工作模型
    NodeJs工作模型
    • 单线程只开一个进程, 一个进程只开一个线程(即一个CPU上只开一个进程, 一个进程里只有一个线程)
      • 单线程只是针对主进程,I/O操作系统底层多线程调度(异步操作属于I/O操作系统底层多线程操作和NodeJS没有关系,NodeJS[主进程]发起一个请求,发起请求后交给I/O)
    • 单线程并不是单进程(CPU起几个核起几个进程)
  • 常用场景
    • web场景,高并发、I/O密集
    • web server
    • 本地代码构建
    • 实用工具开发

调试项目&初始化

环境

  • CommonJS (模块规范)
    • 每个文件是一个模块,有自己作用域(模块被加载后不会再被加载,而是直接拿模块加载后的结果)
    • 在模块内部modeule变量代表模块本身
    • module.exports 属性代表模块对外接口
  • global (没有BOM、DOM、window)
    • 类似于window
    • Buffer(二进制数据处理)、process.console
    • timer
  • process
    • process.nextTick 微任务

      调试

  • Inspector
  • VS Code

基础API

path

  • _dirname, _filename 总是返回文件的绝对路径
  • process.cwd() 总是返回执行node命令所在文件夹

./

  • require方法中总是相对当前文件所在文件夹
  • 在其它地方和process.cwd()一样,相对node启动文件夹

Buffer(直接被挂载在global)

  • Buffer 用于处理二进制数据流
  • 实例类似整数数组,大小固定(默认十六进制, 不能修改长度)
  • C++ 代码在V8 堆外分配物理内存

简单Web Server

使用了supervisor监听文件改变
使用了handlebars模板引擎
使用了curl模拟请求web服务器(mac 自带)
使用commander或者yargs获取命令行参数列表

实现一个静态资源服务器

执行命令可以把本地的当前目录变成一个静态资源服务器的根目录,可以通过url访问文件anywhere

基本步骤

  • 实现对文件的读写,并在对应的Host:port 打开
  • 设置npm 配置并上传到npm 生成npm cli

.gitignore

  • 匹配模式前/: 代表项目根目录
  • 匹配模式最后加/: 代表是目录
  • 匹配模式前加!: 代表取反
  • *: 代表任意个字符
  • ?: 匹配任意一个字符
  • **: 匹配多级目录

.npmignore

.npmignore详细说明

EditorConfig

对文件设置range

  • requestHeader设置
    • range: bytes=[start]-[end]
  • responseHeader设置
    • Accept-Range: bytes
    • Content-Range: bytes start-end/total

缓存header

  • responseHeader
    • expirse(返回绝对时间)
    • cache-control(返回上次请求的相对时间max-age)
  • If-Modified-Since / Last-Modified(一对)
    • requestHeader: If-Modified-Since
    • responseHeader: Last-Modified
  • if-None-Match / ETag
    浏览器请求缓存流程

语义化版本号 x.y.z

  • 升级z位: bug fix
  • 升级y位: 有新增功能并且和之前兼容同时bug fix
  • 升级x位: 不保证兼容(一般偶数为稳定版)
  • x.y.*:
    • 如1.2.*:自动更新z位,bug fix为最新 与 ~1.2.0相同
    • x/y固定
  • x.x 如: 2.x 与 ^2.0.0

linux系统需要给文件添加操作权限

本地构建

超简易版本地构建

  • 压缩
  • less/scss等构建为css、ES5/ES6构建为浏览器可识别的版本等

gulp

babel

webpack

单元测试 & 发布

断言库

Mocha

NodeJS 爬虫示例

简单爬取百度图片

  • 按照一定规则自动抓取网络信息的程序(搜索引擎)
    • 爬取到HTML
    • cheerio 把HTML转换成一个类似JQ的对象(获取信息时可以使用JQ操作)
  • 反爬虫
    • User-Agent, Referer, 验证码
    • 单位之间访问次数,访问量
    • 关键信息图片混淆
    • 异步加载