Node.js课程知识讲解大全(一)

一. 了解Node.js

1.1 Node.js 介绍

Node.js是一个基于Chrome V8引擎的 JavaScript 运行时。

关于Node.js的几个讨论:

Node肯定是几个前端工程师瞎鼓捣出来的。

啥?让JavaScript开发后端?要逆天吗?

怎么又发明了一门新语言?

前端工程师要逆袭了!

回溯JavaScript和浏览器大战

1995年,美国网景公司发布了导航者浏览器(Netscape Navigator)2.0,同时发布的还有LiveScript(后来更名为JavaScript),后来微软推出了Internet Explorer(鼎鼎大名的IE)并几乎同时发布了JScript,伴随着这两个网页浏览器的流行,脚本语言开始奔向统一,一直到ECMA国际标准组织成立。

很长一段时间,开发人员都默认把JavaScript当做前端脚本语言来对待,而且天然的认为它的性能极其低下,无法胜任大型任务(因为IE内核在性能上的长期拖后腿)。

直到谷歌(Google)公司发布了基于Webkit内核的Chrome浏览器,并重新编写了JavaScript虚拟机引擎,命名为v8。从此JavaScript的运行速度与IE的时代将不再同日而语。

Node.js 发布

一个叫Ryan Dahl的资深C++程序员,日常工作主要是开发高性能的Web服务器,他需要的高性能服务器需要具备几大特征:

基于事件驱动,可实现异步。

非阻塞IO,不占用资源。

简单易用,可以快速开发。

与此同时,恰好,Chome浏览器的JavaScript的引擎V8摘得了性能桂冠,同时它还是开源的(基于BSD开源协议发布),而浏览器端语言JavaScript天生就是基于事件而且可以轻松的实现回调数据,正好契合了Ryan Dahl的需求,而且JavaScript在后端的开发领域几乎是空白,可以大展宏图。就这样,短短的四个月内,从想法到实现。

之所以起名Node,是因为当时的作者希望它可以构建大型分布式可扩展可伸缩的平台,每一个线程、进程甚至服务器都作为整个平台的节点,而Node正是节点的意思。

1.2 Node.js 特点

Ryan Dahl选择JavaScript很大程度上是源于Chrome v8内核,而JavaScript又是运行在Chrome内核上的,这一切就变得顺理成章了,Node.js完全采用了v8作为JavaScript解释引擎,但抛弃了Chrome内部的Webkit渲染引擎(因为它是服务器端的JavaScript,不需要渲染)。

Node.js的特点:

异步非阻塞IO

同步和异步:

+ 同步指的是在请求资源或者查询数据库或者在进行大量运算时,需要等待操作完成才能进行下一步动作,同步的代码都是按照串行顺序完成的,中间某一个环节的错误有可能会导致整个程序的退出。

+ 异步是相对同步而言,异步仅仅是对于上面提到的动作发送一个请求,但不需要等待请求完成,即可继续进行后续的操作,而请求的结果执行是在回调函数中完成的。

在专业术语中,同步也叫串行;异步也叫并行。

Node.js中大多数操作都支持异步操作进行(同时也支持同步操作进行),无论是文件读取还是网络请求亦或是数据库访问,都支持并行的异步IO操作。

由于异步非阻塞IO的特性,Node.js非常适合做高并发服务器。

基于事件的回调

Node.js中仿照浏览器事件的原理针对大部分异步操作都采用了事件处理,在事件中监听变化并把结果返回给回调函数。

因此我们代码编写的顺序未必就是实际的执行顺序,这有可能会造成代码阅读上的障碍。

在学习Node.js的过程中,注意:事件回调函数的第一个形参一般都指代error(即异步处理可能发生的错误),并且应该优先处理error。

constfs=require('fs')

fs.readFile('hello.txt', (err)=>{

if(err) {

// 这里发生了错误

console.error(err)

return

   }

// 如果没有错误发生,err约定是null.

})

单线程

因为浏览器内核运行JavaScript都是在单线程环境下执行的,因此Node.js继承了JavaScript的单线程特性,但是目前已经拥有了实现多线程的方法:

通过Web Workers创建工作线程来实现多线程,并通过window.postMessage实现线程通信。

通过child_process实现和Web Workers类似的方式,该特性只有Node.js提供。

跨平台

Node非常引入关注的特点还有具有跨平台特性,兼容Window、Linux和Unix(Mac的OSX基于Unix),底层的架构是借助libuv实现的跨平台兼容,此外libuv不仅用于Node.js,也成为了许多跨平台的基础组件。

1.3 Node.js 应用领域

虽然Node.js是为了高性能服务器而开发,但它并非适用于所有领域。在当前的后端开发领域,它主要适用于以下场景:

IO密集型业务

天然的异步IO特性让Node.js非常适合大量的IO请求、读写,它可以快速的处理请求并返回数据。但Node.js不适合计算密集型(例如人工智能算法),这种操作通常交给C++来处理。

分布式应用

由于高效的IO操作,Node.js非常适合开发数据库集群。数据库的访问可以是大量IO请求,只不过请求的处理需要进行密集的计算(数据库引擎来完成)。阿里巴巴利用Node.js开发了NodeFox。

1.4 为什么学Node.js

浏览器的HTML5才是JavaScript最广泛的应用领域,后端的语言很多还是采用如Java、PHP、ASP.NET、Python等后端语言的正规军,Node.js也并没有大规模的应用,那么我们为何需要学习Node.js ?

了解前后端交互流程

作为一个资深的前端菜鸟,除了知道如何使用ajax获取数据外,还应该知道后端的数据是怎么生成和传递过来的。

熟悉API产生的过程

深入数据库操作,解开数据存储和使用的神秘面纱。

不依赖于后端开发而测试前端应用

有时候前后端开发是彻底分离的,这样就会产生开发进度不同步的情况,可以自己先用Node.js实现模仿的接口来测试数据(Mock data)。

全栈工程师

Node.js本身就是一门垂直的学科,如果学的足够深入,单独用Node.js开发后台服务完全不成问题(很多公司,如滴滴、阿里都采用Node.js处理并发)

为构建工具的使用打基础

Webpack、Gulp等都是基于Node.js构建的。

1.5 Node.js 安装

Node.js会定期发布新版本,Node.js的版本分为LTS(长期稳定版)和Current(最新特性版),安装时建议安装最新的LTS版本,截止目前,Node.js已经发布到v12.13.0。

本地开发可以直接下载安装包或者在Mac或Linux通过软件管理工具安装(brew、apt-get等)。

如果希望在本地安装多个版本的Node.js,可以使用nvm。

如果需要使用虚拟机快速安装镜像,可以使用docker。

1.6 Node.js 运行时

安装完毕Node.js之后,可以在终端(Windows CMD命令行或者*nix终端)输入: node -v,查看node版本。

输入: node会进入REPL环境(Read Eval Print Loop:交互式解释器) ,类似 Window 系统的终端或 Unix/Linux shell,我们可以在终端中输入命令,并接收系统的响应。

REPL可以执行:

读取用户输入或者JavaScript变量声明

执行JavaScript代码

多行表达式(如 for循环)会自动通过... 来换行

打印结果

执行完毕后:

ctrl + c - 退出当前终端。

ctrl + c 按下两次 - 退出 Node REPL。

1.7 了解NPM

Node.js安装完毕后,会随同它一起安装了一个NPM工具,该工具作为npm命令单独使用。

NPM是一个包管理工具,它能够辅助用户远程安装其他的依赖包,用途如下:

用户可以从NPM仓库下载第三方包到本地使用。

用户可以从NPM仓库下载安装第三方命令行工具到本地使用。

允许用户发布自己的包或命令行工具到NPM仓库中。

Node.js默认是集成NPM的,只需要在终端输入:npm -v即可打印版本号

$ npm-v

6.4.1

下面列出了npm常用的命令:

1.npminstall[-args][<@scope>/][@]

安装第三方依赖包,例如:npminstall--global@babel/[email protected]

2.npmuninstall[-args][<@scope>/][@]:

卸载模块,例如:npmuninstalljquery--save-optional,卸载可选阶段的依赖里的jquery

3.npmupdate[-g][]

更新模块。

4.npmoutdated[[<@scope>/]]

检查模块是否已经过时。

5.npmls[[<@scope>/]...]

查看安装的模块。

6.npminit[-f|--force|-y|--yes]

在项目中引导创建一个package.json文件。

安装包的信息可保存到项目的package.json文件中,以便后续的其它的项目开发或者他人合作使用。

7.npmroot[-g]

查看包的安装路径

8.管理npm的配置路径有关的命令

npmconfigset[-g|--global]

npmconfigget

npmconfigdelete

npmconfiglist

npmconfigedit

npmget

npmset[-g|--global]

9.npmcacheverify:清理缓存,如果安装莫名报错可以考虑清空缓存。

10.npmstart[--args]:启动某个脚本指令

该命令写在package.json文件scripts的start字段中:

"scripts":{

"start":"gulp -ws"

}

可以自定义命令来配置一个服务器环境和安装一系列的必要程序,如

此时在cmd中输入npmstart命令相当于执行gulpfile.js文件自定义的watch和server命令。

11.npmstop[--args]:停止脚本。

12.npmrestart:重启脚本。

13.npmpublish:发布自己的模块到仓库。

14.npmversion:查看版本。

1.7.1 详解npm install

npm install主要功能是在当前目录下安装所需的依赖,安装的依赖包可以通过引入库的方式随意的使用。正规格式如下:其中[]中是可选的<>中表示的是自定义名称。

npm install 安装的依赖包默认存储在项目目录(需要具有package.json)的node_modules目录下。

引入依赖包时,会通过一级一级查找node_modules目录,直到找到该包。

npm install [args] [<@scope>/][@]

npminstall:需要保证当前目录下存在package.json文件,基于package.json自动安装全部依赖。

npminstall[args][<@scope>/][@]中的可选参数args:

--save或-S:安装包信息将加到dependencies(生产阶段的依赖),开发阶段和部署阶段都会使用它。

--save-dev或-D:安装包信息将加到devDependencies(开发阶段的依赖),只有开发阶段会使用它。

-O,–save-optional:安装包信息将加入到optionalDependencies(可选阶段的依赖)。

-E,–save-exact:精确安装指定模块版本。

npm安装包的几种依赖方式:

depedencies:指定应用依赖的外部包,这些依赖是应用正常发布后正常执行所需要的,**但不包含测试时和本地打包时所使用的包**

devDependencies:**只用于开发环境的包**,不用于生产环境,这些包通常是单元测试或者打包工具等,例如gulp, grunt, webpack, moca, coffee等。

peerDependencies:同等依赖,用于指定自己写的包兼容的宿主版本。

*试想一下,我们编写一个gulp的插件,而gulp却有多个主版本,我们只想兼容最新的版本,此时就可以用同等依赖(peerDependencies)来指定:*

{

    "name": "gulp-my-plugin",

    "version": "0.0.1",

    "peerDependencies": {

        "gulp": "3.x"

    }

}

*当别人使用我们的插件时,peerDependencies就会告诉明确告诉使用方,你需要安装该插件哪个宿主版本。

通常情况下,我们会在一个项目里使用一个宿主(比如gulp)的很多插件,如果相互之间存在宿主不兼容,在执行npm install时,cli会抛出错误信息来告诉我们,比如:*

```

npm ERR! peerinvalid The package gulp does not satisfy its siblings' peerDependencies requirements!

npm ERR! peerinvalid Peer [email protected] wants gulp@~3.1.9

npm ERR! peerinvalid Peer [email protected] wants gulp@~2.3.0

```

但是,假如运行命令npm install gulp-my-plugin –save-dev来安装自己写的包,会出现以下依赖图谱:

├── [email protected]

└── [email protected]

optionalDependencies:可选依赖,如果有一些依赖包即使安装失败,项目仍然能够运行或者希望npm继续运行,就可以使用optionalDependencies。**另外optionalDependencies会覆盖dependencies中的同名依赖包,所以不要在两个地方都写。**

bundledDependencies / bundleDependencies:打包依赖,bundledDependencies是一个包含依赖包名的数组对象,在发布时会将这个对象中的包打包到最终的发布包里。**但是值得注意的是,这两个包必须先在devDependencies或dependencies声明过,否则打包会报错。**

1.7.2 package.json文件介绍

package.json描述了npm模块或者自定义项目的一些基本信息,如果自定义项目需要安装第三方依赖或者自己发布模块到npm仓库,都需要在项目的根目录下面加入package.json文件,文件格式如下:

{

// 作者

"author": {

"name":"Aseem Kishore",

"email":"[email protected]"

  },

// 命令行文件路径

"bin": {

"json5":"lib/cli.js"

  },

// 构建依赖

"dependencies": {

"minimist":"^1.2.0"

  },

// 简介,用于npm 搜索

"description":"JSON for humans.",

// 开发依赖

"devDependencies": {

// 版本号介绍

// version 必须完全和version一致

// >version 必须比version大

// >=version 同上

//

// <=version 同上

// ~version 大约一样,见semver(7)

// 1.2.x 1.2.0, 1.2.1, 等,但不包括1.3.0

"core-js":"^2.6.5",

"eslint":"^5.15.3",

"eslint-config-standard":"^12.0.0",

"eslint-plugin-import":"^2.16.0",

"eslint-plugin-node":"^8.0.1",

"eslint-plugin-promise":"^4.0.1",

"eslint-plugin-standard":"^4.0.0",

"regenerate":"^1.4.0",

"rollup":"^0.64.1",

"rollup-plugin-buble":"^0.19.6",

"rollup-plugin-commonjs":"^9.2.1",

"rollup-plugin-node-resolve":"^3.4.0",

"rollup-plugin-terser":"^1.0.1",

"sinon":"^6.3.5",

"tap":"^12.6.0",

"unicode-10.0.0":"^0.7.5"

  },

// 项目官网

"homepage":"http://json5.org/",

// 关键字,用于npm 搜索

"keywords": [

"json",

"json5",

"es5",

"es2015",

"ecmascript"

  ],

// 许可证

"license":"MIT",

// 程序入口,import导入默认就加载这个入口

"main":"lib/index.js",

"module":"dist/index.mjs",

// 包名,npm install 就依赖于这个

"name":"json5",

// 源码地址

"repository": {

"type":"git",

"url":"git+https://github.com/json5/json5.git"

  },

// 可用于npm start的命令。

"scripts": {

"build":"rollup -c",

"build-package":"node build/package.js",

"build-unicode":"node build/unicode.js",

"coverage":"tap --coverage-report html test",

"lint":"eslint --fix .",

"prepublishOnly":"npm run production",

"preversion":"npm run production",

"production":"npm run lint && npm test && npm run build",

"test":"tap -Rspec --100 test",

"version":"npm run build-package && git add package.json5"

  },

// 版本号

"version":"2.1.1"

}

使用npm之前最好设置下npm的仓库镜像,以便提高访问速度:

npm config set registry https://registry.npm.taobao.org

下面命令验证配置是否成功:

npm config get registry

不推荐:全局安装cnpm

npm install -g cnpm --registry=https://registry.npm.taobao.org,

cnpm安装的包依赖结构混乱,而且无法和npm混用

推荐:全局安装yarn

yarn是Facebook官方发布的可以取代npm的的工具,使用命令的方式和npm类似(可选参数不同),能够显著提高安装依赖的速度,同时还能和npm兼容。

yarn[global][-D]add:安装依赖包。

你可能感兴趣的:(Node.js课程知识讲解大全(一))