共计 14268 个字符,预计需要花费 36 分钟才能阅读完成。
nodeJs 基础篇整合
最近有朋友也想学习 nodeJs 相关方面的知识,如果你是后端想接近前端,node 作为一门跑在服务端的 JS 语言从这里入门再好不过了。如果你正好喜欢前端,想走的更高,走的更远。nodeJs 同样也是不二之选。node 的地位虽然在实战项目中运用的不是很多,但也不能否认它在处理高并发, 服务端渲染,前端自动化方面的优势。总而言之。如果你是个自学能力很强的人。请来到这里学习。让我们一起去打开 node 的世界,游走于前端与服务端之间。你如果能掌握如下知识那么你的 node 基础功底将会十分强大。
简介:Node.js 就是运行在服务端的 JavaScript。Node.js 是一个基于 Chrome JavaScript 运行时建立的一个平台。Node.js 是一个事件驱动 I / O 服务端 JavaScript 环境,基于 Google 的 V8 引擎,V8 引擎执行 Javascript 的速度非常快,性能非常好。底层选择用 c ++ 和 v8 来实现的
优势:1. RESTful API
这是 NodeJS 最理想的应用场景,可以处理数万条连接,本身没有太多的逻辑,只需要请求 API,组织数据进行返回即可。它本质上只是从某个数据库中查找一些值并将它们组成一个响应。由于响应是少量文本,入站请求也是少量的文本,因此流量不高,一台机器甚至也可以处理最繁忙的公司的 API 需求。
统一 Web 应用的 UI 层
目前 MVC 的架构,在某种意义上来说,Web 开发有两个 UI 层,一个是在浏览器里面我们最终看到的,另一个在 server 端,负责生成和拼接页面。不讨论这种架构是好是坏,但是有另外一种实践,面向服务的架构,更好的做前后端的依赖分离。如果所有的关键业务逻辑都封装成 REST 调用,就意味着在上层只需要考虑如何用这些 REST 接口构建具体的应用。那些后端程序员们根本不操心具体数据是如何从一个页面传递到另一个页面的,他们也不用管用户数据更新是通过 Ajax 异步获取的还是通过刷新页面。
大量 Ajax 请求的应用
例如个性化应用,每个用户看到的页面都不一样,缓存失效,需要在页面加载的时候发起 Ajax 请求,NodeJS 能响应大量的并发请求。4.Javascript 在 nosql 的应用 Javascript 在 nosql 数据库中大量应用,使得数据存储和管理使用的都是 javascript 语句,与 web 应用有了天然的结合;比如 mongoDB;5.Javascripte 运行从前台到后台
一门语言从前台后台,减少了开发客户端和服务端时,所需的语言切换,使得数据交互效率提升
特点:1. 单线程:
Nodejs 跟 Nginx 一样都是单线程为基础的,这里的单线程指主线程为单线程,所有的阻塞的全部放入一个线程池中,然后主线程通过队列的方式跟线程池来协作。我们写 js 部分不需要关心线程的问题,简单了解就可以了,主要由一堆 callback 回调构成的,然后主线程在循环过在适当场合调用。
2. 事件驱动 首先,解释下“事件驱动”这个概念。所谓事件驱动,是指在持续事务管理过程中,进行决策的一种策略,即跟随当前时间点上出现的事件,调动可用资源,执行相关任务,使不断出现的问题得以解决,防止事务堆积。Nodejs 设计思想中以事件驱动为核心,事件驱动在于异步回调,他提供的大多数 api 都是基于事件的、异步的风格。而事件驱动的优势在于充分利用系统资源,执行代码无须阻塞等待某种操作完成,有限的资源用于其他任务。事件驱动机制是通过内部单线程高效率地维护事件循环队列来实现的,没有多线程的资源占用和上下文的切换。
3. 异步、非阻塞 I /ONodejs 提供的很多模块中都是异步执行的。比如,文件操作的函数。一个异步 I / O 的大致流程:1. 发起 I / O 调用 :①用户通过 js 代码调用 nodejs 的核心模块,将回调函数和参数传入核心模块 ②将回调函数和参数封装成 2. 执行回调: ①操作完成将结果储存到请求对象的 result 属性上,并发出完成通知。②循环事件,如果有未完成的,就在进入对象请求 I / O 观察者队列,之后当做事件处理;
缺点:1. 不适合 CPU 密集型应用;CPU 密集型应用给 Node 带来的挑战主要是:由于 JavaScript 单线程的原因,如果有长时间运行的计算(比如大循环),将会导致 CPU 时间片不能释放,使得后续 I / O 无法发起;2. 只支持单核 CPU,不能充分利用 CPU 3. 可靠性低,一旦代码某个环节崩溃,整个系统都崩溃 4. 开源组件库质量参差不齐,更新快,向下不兼容
安装:(一) 官网下载:
1. 下载地址:http://nodejs.cn/download/
2. 根据自己的系统进行镜像的下载:
3. 下载的为最新的 node 版本,当前下载的为 10.8.0
Nvm 管理 node:
nvm 可以方便的在同一台设备上进行多个 node 版本之间切换
1. 先下载安装 nvm,下载地址:https://github.com/coreybutle…,选择 nvm-setup 压缩文件,解压后安装;2. 安装过程中出现,选择 nvm 的安装目录 3. 选择 node 的安装目录 4. 配置环境变量 5. 查看 nvm 是否安装成功:
Nvm -v
6. 安装 nodejs
使用 nvm install <version> [<arch>] 命令下载需要的版本。arch 参数表示系统位数,默认是 64 位,如果是 32 位操作系统,需要执行命令:nvm install 10.8.0 32,如:
Nvm install 10.8.0
7. 使用下载的 nodejs
执行 nvm use <version> [<arch>] 命令开始使用特定版本。比如:nvm use 10.8.0 或者 nvm use 10.8.0 32
Nvm use 10.8.0
8. 当有多个 nodejs 版本时,设置默认的 node 版本
nvm alias default v10.8.0
9. 查看当前所安装的 node 版本
Nvm list
全局安装和局部安装: 全局安装:全局安装方式是键入命令:npm install gulp -g 或 npm install gulp –global,其中参数 - g 的含义是代表安装到全局环境里面,包安装在 Node 安装目录下的 node_modules 文件夹中,一般在 Users 用户名 AppDataRoaming 目录下,可以使用 npm root - g 查看全局安装目录。
局部安装(本地安装)
本地安装方式是键入命令:npm install gulp 或 npm install gulp –save-dev 等,其中参数 –save-dev 的含义是代表把你的安装包信息写入 package.json 文件的 devDependencies 字段中,包安装在指定项目的 node_modules 文件夹下。
局部安装的意义:1、可以实现多个项目中使用不同版本的包;2、可以在不使用全局变量 NODE_PATH 的情况下,进行包的引入;
Node 运行
终端运行和外部文件运行
Nodejs 的模块(commonjs 规范)
(一) 模块化
1. 诞生背景:全局变量的灾难: 函数命令的冲突: 对于公用方法的封装会出现很多命名冲突,尤其在多人开发的情况下依赖关系的管理:比如 b.js 依赖 a.js,在文件引入的过程中,就要先引入 b.js
最早的时候在解决上述部分问题时的解决方案是:使用匿名的自执行函数
2. 模块需要解决的问题:
如何安全的包装一个模块的代码?(不污染模块外的任何代码)
如何唯一标识一个模块?
如何优雅的把模块的 API 暴漏出去?(不能增加全局变量)
如何方便的使用所依赖的模块?
(二)Commonjs
1. 规范:1) 模块的标识应遵循的规则(书写规范)定义,标识,引用 2) 定义全局函数 require,通过传入模块标识来引入其他模块,执行的结果即为别的模块暴漏出来的 API3) 如果被 require 函数引入的模块中也包含依赖,那么依次加载这些依赖 4) 如果引入模块失败,那么 require 函数应该报一个异常 5) 模块通过变量 exports 来向往暴漏 API,exports 只能是一个对象,暴漏的 API 须作为此对象的属性。
模块的简单使用:
//math.js
exports.add = function() {
var sum = 0, i = 0, args = arguments, l = args.length;
while (i < l) {
sum += args[i++];
}
return sum;
};
//increment.js
var add = require(‘math’).add;
exports.increment = function(val) {
return add(val, 1);
};
//program.js
var inc = require(‘increment’).increment;
var a = 1;
inc(a); // 2
模块的定义 1) 全局有一个 module 变量,用来定义模块 2) 通过 module.declare 方法来定义一个模块(一般不通过此方式进行模块的定义)3)module.declare 方法只接收一个参数,那就是模块的 factory,次 factory 可以是函数也可以是对象,如果是对象,那么模块输出就是此对象。4) 模块的 factory 函数传入三个参数:require,exports,module,用来引入其他依赖和导出本模块 API 如果 factory 函数最后明确写有 return 数据(js 函数中不写 return 默认返回 undefined),那么 return 的内容即为模块的输出。
不常用:
module.declare(function(require, exports, module) {
exports.foo = “bar”;
});
module.declare(function(require)
{
return {foo: “bar”};
});
常用:
module.exports={}
odule.exports 和 exports 的区别:
1)module.exports 初始值为一个空对象 {}2)exports 是指向的 module.exports 的引用 3)require() 返回的是 module.exports 而不是 exports
4) 关系为 var exports = module.exports={};
如:module.exports 可以赋值一个对象 module.exports={}
exports 不可以赋值一个对象,只能添加方法或者属性 exports.add=function(){
}5. 模块引用 require 函数的基本功能是,读入并执行一个 JavaScript 文件,然后返回该模块的 exports 对象。当我们用 require() 获取 module 时,Node 会根据 module.id 找到对应的 module,并返回 module. exports,这样就实现了模块的输出。require 函数使用一个参数, 参数值可以带有完整路径的模块的文件名, 也可以为模块名。假如,有三个文件:一个是 a.js(存放路径:home/a.js), 一个是 b.js(存放路径:home/user/b.js), 一个是 c.js(存放路径:home/user/c.js)。我们在 a.js 文件中引用三个模块,实例代码如下:var httpModule=require(‘HTTP’);// 用“模块名”加载服务模块 http
var b=require(‘./user/b’);// 用“相对路径”加载文件 b.js
var b=require(‘../ home/user/c’);// 用“绝对路径”加载文件 c.js 6. 模块标识模块标识就是传递给 require 方法的参数,必须符合小驼峰命名的字符串,或者以.、.. 开头的相对路径,或者绝对路径,默认文件名后缀.js。在 Node 实现中,正是基于这样一个标识符进行模块查找的,如果没有发现指定模块会报错。根据参数的不同格式,require 命令去不同路径寻找模块文件。加载规则如下:(1)如果参数字符串以“/”开头,则表示加载的是一个位于绝对路径的模块文件。比如,require(‘/home/marco/foo.js’) 将加载 /home/marco/foo.js。(2)如果参数字符串以“./”开头,则表示加载的是一个位于相对路径(跟当前执行脚本的位置相比)的模块文件。比如,require(‘./circle’) 将加载当前脚本同一目录的 circle.js。(3)如果参数字符串不以“./“或”/“开头,则表示加载的是一个默认提供的核心模块(位于 Node 的系统安装目录中),或者一个位于各级 node_modules 目录的已安装模块(全局安装或局部安装)。举例来说,脚本 /home/user/projects/foo.js 执行了 require(‘bar.js’) 命令,Node 会依次搜索以下文件。
/usr/local/lib/node/bar.js
/home/user/projects/node_modules/bar.js
/home/user/node_modules/bar.js
/home/node_modules/bar.js
/node_modules/bar.js
这样设计的目的是,使得不同的模块可以将所依赖的模块本地化。(4)如果参数字符串不以“./“或”/“开头,而且是一个路径,比如 require(‘example-module/path/to/file’),则将先找到 example-module 的位置,然后再以它为参数,找到后续路径。(5)如果指定的模块文件没有发现,Node 会尝试为文件名添加.js、.json、.node 后,再去搜索。.js 件会以文本格式的 JavaScript 脚本文件解析,.json 文件会以 JSON 格式的文本文件解析,.node 文件会以编译后的二进制文件解析。(6)如果想得到 require 命令加载的确切文件名,使用 require.resolve() 方法。此方法会返回一个完整的路径,并且还会对文件的是否存在做检测 7. 二进制模块虽然一般我们使用 JS 编写模块,但 NodeJS 也支持使用 C /C++ 编写二进制模块。编译好的二进制模块除了文件扩展名是.node 外,和 JS 模块的使用方式相同。虽然二进制模块能使用操作系统提供的所有功能,拥有无限的潜能,但对于前端同学而言编写过于困难,并且难以跨平台使用,因此不在本教程的覆盖范围内。
Node 模块的分类:
1. 内置模块(核心模块)
核心模块指的是那些被编译进 Node 的二进制模块,它们被预置在 Node 中,提供 Node 的基本功能,如 fs、http、https 等。核心模块使用 C /C++ 实现,外部使用 JS 封装。要加载核心模块,直接在代码文件中使用 require() 方法即可,参数为模块名称,Node 将自动从核心模块文件夹中进行加载。
2. 第三方模块 Node 使用 NPM(Node Package Manager)安装第三方模块,NPM 会将模块安装到应用根目录下的 node_modules 文件夹中,然后就可以像使用核心模块一样使用第三方模块了。在进行模块加载时,Node 会先在核心模块文件夹中进行搜索,然后再到 node_modules 文件夹中进行搜索。
3. 文件模块 上述两种方式都是从当前目录获取模块文件,实际上,可以将文件放在任何位置,然后在加载模块文件时加上路径即可。可以使用以./ 开头的相对路径和以 / 或 C: 之类的盘符开头的绝对路径。
4. 文件夹模块 从文件夹中加载模块,Node 首先会在该文件夹中搜索 package.json 文件。如果存在,Node 便尝试解析它,并加载 main 属性指定的模块文件。如果 package.json 不存在,或者没有定义 main 属性,Node 默认加载该文件夹下的 index.js 文件。如从项目根目录下的 modules/hello 文件夹加载模块:var hello = require(“./modules/hello”); package.json 格式如下:
{“name”: “hello”, “version”: “1.0.0”, “main”: “./hello.js”} 此时,Node 会去加载./modules/hello/hello.js 文件。如果目录里没有 package.json 文件,则 Node.js 就会试图加载目录下的 index.js 或 index.node 文件。例如,如果上面的例子中没有 package.json 文件,则 require(“./modules/hello”) 会试图加载:./modules/hello /index.js./modules/hello /index.node 四、Npm 与 package.json 详解
(一)npm 简介:世界上最大的软件注册表,每星期大约有 30 亿次的下载量,包含超过 600000 个 包(package)(即,代码模块)。来自各大洲的开源软件开发者使用 npm 互相分享和借鉴。包的结构使您能够轻松跟踪依赖项和版本。npm 是一个包管理器,它让 JavaScript 开发者分享、复用代码更方便(有点 maven 的感觉)。在程序开发中我们常常需要依赖别人提供的框架,写 JS 也不例外。这些可以重复的框架代码被称作包(package)或者模块(module),一个包可以是一个文件夹里放着几个文件,同时有一个叫做 package.json 的文件。一个网站里通常有几十甚至上百个 package,分散在各处,通常会将这些包按照各自的功能进行划分,但是如果重复造一些轮子,不如上传到一个公共平台,让更多的人一起使用、参与这个特定功能的模块。而 npm 的作用就是让我们发布、下载一些 JS 轮子更加方便。
(二)npm 构成:
npm 由三个独立的部分组成:网站:是开发者查找包(package)、设置参数以及管理 npm 使用体验的主要途径。注册表(registry):是一个巨大的数据库,保存了每个包(package)的信息命令行工具 (CLI):通过命令行或终端运行。开发者通过 CLI 与 npm 打交道
(三)npm 更新:
查看版本:nvm - V 更新版本:nvm install npm@latest -g
(四)npm 更改全局目录:
查看 npm 全局目录:npm root -g
修改全局包位置:npm config set prefix ‘ 目标目录 ’
查看修改结果 npm config get prefix 或 npm root -g
(五)package.json
A. 作用:
1. 作为一个描述文件,描述了你的项目依赖哪些包 2. 允许我们使用“语义化版本规则”(后面介绍)指明你项目依赖包的版本 3. 让你的构建更好地与其他开发者分享,便于重复使用 4. 如果项目构架进行复制时,可以直接使用 npm install, 直接根据 package.json 的配置进行包的下载 5. 作为项目的描述文件,对整个项目进行描述。
B. 创建:
npm init 即可在当前目录创建一个 package.json 文件:
C. 内容:基本配置:1.name:项目的名字 2.version:项目的版本 3.description:描述信息,有助于搜索 4.main: 入口文件,一般都是 index.js 5.scripts:支持的脚本,默认是一个空的 test 6.keywords:关键字,有助于在人们使用 npm search 搜索时发现你的项目 7.author:作者信息 8.license:默认是 MIT 9.bugs:当前项目的一些错误信息,如果有的话注:如果 package.json 中没有 description 信息,npm 使用项目中的 README.md 的第一行作为描述信息。这个描述信息有助于别人搜索你的项目,因此建议好好写 description 信息。
依赖包配置:1.dependencies:在生产环境中需要用到的依赖 2.devDependencies:在开发、测试环境中用到的依赖
(六)package-lock.json 文件
npm5 之后安装文件之后会多出一个 package-lock.json 的文件,它的作用是:1. 安装之后锁定包的版本,手动更改 package.json 文件安装将不会更新包,想要更新只能使用 npm install xxx@1.0.0 –save 这种方式来进行版本更新 package-lock.json 文件才可以 2. 加快了 npm install 的速度,因为 package-lock.json 文件中已经记录了整个 node_modules 文件夹的树状结构,甚至连模块的下载地址都记录了,再重新安装的时候只需要直接下载文件即可
(七)npm 的包版本规范和 package.json 的使用规范
npm 版本规范:如果一个项目打算与别人分享,应该从 1.0.0 版本开始。以后要升级版本应该遵循以下标准:补丁版本:解决了 Bug 或者一些较小的更改,增加最后一位数字,比如 1.0.1 小版本:增加了新特性,同时不会影响之前的版本,增加中间一位数字,比如 1.1.0 大版本:大改版,无法兼容之前的,增加第一位数字,比如 2.0.0
Package.json 的版本书写:
我们可以在 package.json 文件中写明我们可以接受这个包的更新程度(假设当前依赖的是 1.0.4 版本):如果只打算接受补丁版本的更新(也就是最后一位的改变),就可以这么写:1.0 1.0.x ~1.0.4 如果接受小版本的更新(第二位的改变),就可以这么写:1 1.x ^1.0.4 如果可以接受大版本的更新(自然接受小版本和补丁版本的改变),就可以这么写:
x
(八)npm 下载包
安装方式:如果你只是想在当前项目里用 require() 加载使用,那你可以安装到本地 npm install 默认就是安装到本地的 如果你想要在命令行里直接使用,比如 grunt CLI,就需要安装到全局了如果在你的项目里有 package.json 文件,运行 npm install 后它会查找文件中列出的依赖包,然后下载符合语义化版本规则的版本。npm install 默认会安装 package.json 中 dependencies 和 devDependencies 里的所有模块。如果想只安装 dependencies 中的内容,可以使用 –production 字段:npm install –production
1. 本地安装:1) 安装指定版本:$ npm install sax@latest:最新版本 $ npm install sax@0.1.1:指定版本 $ npm install sax@” >=0.1.0 <0.2.0”: 安装 0.1.0 到 0.2.0 版本注:有时下载会报错:npm install error saveError ENOENT: no such file or directory, 解决办法:– 在目录下执行 npm init 创建 package.json,输入初始化信息 – 然后再执行下载命令
2) 安装参数 –save 和 –save -dev
添加依赖时我们可以手动修改 package.json 文件,添加或者修改 dependencies devDependencies 中的内容即可。另一种更酷的方式是用命令行,在使用 npm install 时增加 –save 或者 –save -dev 后缀:npm install –save 表示将这个包名及对应的版本添加到 package.json 的 dependencies npm install –save-dev 表示将这个包名及对应的版本添加到 package.json 的 devDependencies
3) 更新本地 package 有时候我们想知道依赖的包是否有新版本,可以使用 npm outdated 查看,如果发现有的包有新版本,就可以使用 npm update 更新它,或者直接 npm update 更新所有:npm update 的工作过程是这样的:先到远程仓库查询最新版本 然后对比本地版本,如果本地版本不存在,或者远程版本较新 查看 package.json 中对应的语义版本规则(一定注意规则)如果当前新版本符合语义规则,就更新,否则不更新
4) 卸载本地 package
卸载一个本地 package 很简单,npm uninstall
2. 全局安装
1) 安装 npm install -g <packages>
2) 权限处理(非 windows 处理)在全局安装时可能会遇到 EACCES 权限问题,解决办法办法有如下 2 种:1.sudo npm install -g jshint,使用 sudo 简单粗暴,但是治标不治本 2. 修改 npm 全局默认目录的权限 先获取 npm 全局目录:npm config get prefix,一般都是 /usr/local;然后修改这个目录权限为当前用户:sudo chown -R $(whoami) $(npm config get prefix)/{lib/node_modules,bin,share}
3) 更新全局包想知道哪些包需要更新,可以使用 npm outdated -g –depth=0,然后使用 npm update -g 更新指定的包;要更新所有全局包,可以使用 npm update -g,可以发现对比本地的,只是多了个 -g。
4) 卸载全局包
npm uninstall -g <package>
3. 其他命令
Npm run: 运行 package.json 中 scripts 指定的脚本 npm install from github: 从 github 下载资源 npm install git://github.com/package/path.git;npm info:npm info 可以查看指定包的信息:
(九)Npm 发布包:
1. 注册:npm 网站地址:https://www.npmjs.com/npm 网站注册地址:https://www.npmjs.com/signup2. 命令行登录 Windows 直接 cmd 到命令行: 输入以下命令,会提示输入用户名、密码、邮箱,这些都是注册时填写过的。npm login3. 创建项目创建一个 testxxxxx 文件夹,cd 到 testxxxxx 文件夹中,然后下载基础配置文件:12 // 输入以下命令,会提示配置包的相关信息,名称版本等等,都是包的基本配置信息 npm init 配置完毕开始写自己的包内代码:创建一个 index.js 文件,文件内的代码如下,直接输出 123456789module.exports = 123456789;4. 发布:开始命令行发布包,命令如下:npm publish testxxxxx 发布完毕,在 npm 网站上搜索,就可以搜索到自己刚刚发布的包了。5. 验证下载:正常下载好了,没有问题了,搞定。6. 撤销发布接下来说明一下怎么撤销自己发布的版本。这只是一个测试的包,最好当然还是撤销下来:删除要用 force 强制删除。超过 24 小时就不能删除了。自己把握好时间。npm –force unpublish testxxxxx(十)Npm 修改镜像源:
由于 npm 的源在国外,所以国内用户使用起来各种不方便。部分国内优秀的 npm 镜像资源,国内用户可以选择使用 1. 淘宝 npm 镜像 搜索地址:http://npm.taobao.org/ registry 地址:http://registry.npm.taobao.org/ 2.cnpmjs 镜像 搜索地址:http://cnpmjs.org/ registry 地址:http://r.cnpmjs.org/ 3. 如何使用 有很多方法来配置 npm 的 registry 地址,下面根据不同情境列出几种比较常用的方法。以淘宝 npm 镜像举例:1) 临时使用 npm –registry https://registry.npm.taobao.org 2) 持久使用(推荐使用)npm config set registry https://registry.npm.taobao.org 配置后可通过下面方式来验证是否成功 npm config get registry 3) 通过 cnpm 使用(也可以使用 cnpm)(常用)npm install -g cnpm –registry=https://registry.npm.taobao.org 4. 恢复 npm 源镜像:如果将 npm 的镜像地址改变后,在发布包时,应该将镜像改回:npm config set registry https://registry.npmjs.org/
五、yarn 的使用:
1. 简介:Yarn 是由 Facebook、Google、Exponent 和 Tilde 联合推出了一个新的 JS 包管理工具 Yarn 是为了弥补 npm 的一些缺陷而出现的。2.Npm 的缺陷:1)npm install 的时候巨慢。特别是新的项目拉下来要等半天,删除 node_modules,重新 install 的时候依旧如此。2) 同一个项目,安装的时候无法保持一致性。由于 package.json 文件中版本号的特点,下面三个版本号在安装的时候代表不同的含义。”5.0.3″,”~5.0.3″,”^5.0.3″“5.0.3”表示安装指定的 5.0.3 版本,“~5.0.3”表示安装 5.0.X 中最新的版本,“^5.0.3”表示安装 5.X.X 中最新的版本。这就麻烦了,常常会出现同一个项目,有的同事是 OK 的,有的同事会由于安装的版本不一致出现 bug。3) 安装的时候,包会在同一时间下载和安装,中途某个时候,一个包抛出了一个错误,但是 npm 会继续下载和安装包。因为 npm 会把所有的日志输出到终端,有关错误包的错误信息就会在一大堆 npm 打印的警告中丢失掉,并且你甚至永远不会注意到实际发生的错误。3.Yarn 的优点 1) 速度快。速度快主要来自以下两个方面:a) 并行安装:无论 npm 还是 Yarn 在执行包的安装时,都会执行一系列任务。npm 是按照队列执行每个 package,也就是说必须要等到当前 package 安装完成之后,才能继续后面的安装。而 Yarn 是同步执行所有任务,提高了性能。b) 离线模式:如果之前已经安装过一个软件包,用 Yarn 再次安装时之间从缓存中获取,就不用像 npm 那样再从网络下载了。2) 安装版本统一:为了防止拉取到不同的版本,Yarn 有一个锁定文件 (lock file) 记录了被确切安装上的模块的版本号。每次只要新增了一个模块,Yarn 就会创建(或更新)yarn.lock 这个文件。这么做就保证了,每一次拉取同一个项目依赖时,使用的都是一样的模块版本。npm 其实也有办法实现处处使用相同版本的 packages,但需要开发者执行 npm shrinkwrap 命令。这个命令将会生成一个锁定文件,在执行 npm install 的时候,该锁定文件会先被读取,和 Yarn 读取 yarn.lock 文件一个道理。npm 和 Yarn 两者的不同之处在于,Yarn 默认会生成这样的锁定文件,而 npm 要通过 shrinkwrap 命令生成 npm-shrinkwrap.json 文件,只有当这个文件存在的时候,packages 版本信息才会被记录和更新。3) 更简洁的输出:npm 的输出信息比较冗长。在执行 npm install <package> 的时候,命令行里会不断地打印出所有被安装上的依赖。相比之下,Yarn 简洁太多:默认情况下,结合了 emoji 直观且直接地打印出必要的信息,也提供了一些命令供开发者查询额外的安装信息。4) 多注册来源处理:所有的依赖包,不管他被不同的库间接关联引用多少次,安装这个包时,只会从一个注册来源去装,要么是 npm 要么是 bower, 防止出现混乱不一致。5) 更好的语义化:yarn 改变了一些 npm 命令的名称,比如 yarn add/remove,感觉上比 npm 原本的 install/uninstall 要更清晰。4.Yarn 和 npm 命令对比 npm yarnnpm install yarnnpm install react –save yarn add reactnpm uninstall react –save yarn remove reactnpm install react –save-dev yarn add react –devnpm update –save yarn upgrade5.npm 的未来:npm5.0(目前使用大多为 5.0 版本)默认新增了类似 yarn.lock 的 package-lock.json;文件依赖优化:在之前的版本,如果将本地目录作为依赖来安装,将会把文件目录作为副本拷贝到 node_modules 中。而在 npm5 中,将改为使用创建 symlinks 的方式来实现(使用本地 tarball 包除外),而不再执行文件拷贝。这将会提升安装速度。目前 yarn 还不支持。总结在 npm5.0 之前,yarn 的优势特别明显。但是在 npm 之后,通过以上一系列对比,我们可以看到 npm5 在速度和使用上确实有了很大提升,值得尝试,不过还没有超过 yarn。综上我个人的建议是如果你已经在个人项目上使用 yarn,并且没有遇到更多问题,目前完全可以继续使用。但如果有兼容 npm 的场景,或者身处在使用 npm,cnpm,tnpm 的团队,以及还没有切到 yarn 的项目,那现在就可以试一试 npm5 了。
六、断点调试
(一)Node-inspector 的浏览器调试
1. 安装 node-inspector 运行环境 安装命令:npm install -g node-inspector 注意:a、参数 -g 将 node-inspector 安装到系统环境变量中,可以在任何路径下执行,尽量保留。b、如果是 Linux 或 Unix 系统,需要使用 root 权限安装 2. 启动 node-inspector node-inspector 启动后会生成一个服务,主要负责调试工具与 nodejs 程序之间的沟通工作,一个桥梁。a、window:直接在任意路径下执行 node-inspector,进行守护 b、Linux || Unix:node-inspector & 将 node-inspcetor 作为后台服务,这样就不怕误操作,把窗口关掉了。出现进程 PID,表示 node-inspcetor 已经成为后台进程,可以 ctrl+ c 结束当前任务,node-inspcetor 进程依然保持。如果想停止可以 kill -9 pid 杀掉 node-inspcetor 进程。3. 打开 chrome,输入地址 http://127.0.0.1:8080/debug?port=5858 NodeJS 程序还没起来呢,目前先到这,看看 NodeJS 程序的变化。4. 打开 NodeJS 的调试模式 node –debug app.js debugger 的监听端口是 5858,这个端口可以修改 5. 再次打开 chrome,刷新页面,chrome 通过 node-inspector 服务连接到 nodejs 服务上了,并显示 nodejs 应用的入口文件内容。总结:1、node-inspector 依赖 nodejs 的运行环境。2、调试过程中 node-inspector 的服务不要重启,只需要在重启 nodejs 应用后刷新一下 chrome 的页面即可。3、严格的来说 node-inspector 不是一个完整的调试工具,它需要一个可视化的调试界面来展示所有的调试信息,node-inspector 是调试界面与 nodejs 之间的桥梁,是调试界面能与 nodejs 沟通。
由于文章过程笔者也在做改进只整理了部分,后序会继续推出更多优秀的作品。希望大家喜欢并支持