走在前端的大道上

本文记录自己 nodejs 学习过程中的一些知识点

最后更新时间 2018年1月18日

1.node 版本控制工具 nvm

NVM——Node Version Manager(Node版本管理器),用它可以方便的在机器上安装并维护多个Node的版本。那么为什么需要多个版本呢?场景有很多,比方说:你可能同时进行两个项目,而不同项目所使用的node版本是不一样的;又或者你要用更新的版本是做一些实验。

有需要的同学可以查看我之前总结的文章 Windows下安装 node 的版本控制工具 nvm


2.npm 包镜像地址切换工具 nrm

nrm就是npm registry manager 也就是npm的镜像源管理工具,有时候国外资源太慢,那么我们可以用这个来切换镜像源。

$ npm install -g nrm

nrm ls可以查看我们可以切换的地址

$ nrm ls
 
* npm -----   https://registry.npmjs.org/
  cnpm ----   http://r.cnpmjs.org/
  taobao -   https://registry.npm.taobao.org/
  nj ------   https://registry.nodejitsu.com/
  rednpm  -  http://registry.mirror.cqupt.edu.cn
  skimdb  -  https://skimdb.npmjs.com/registry

提示:其中的*代表当前使用的地址

切换

$ nrm use cnpm  //switch registry to cnpm
Registry has been set to: http://r.cnpmjs.org/

使用

Usage: nrm [options] [command]

  Commands:

    ls                           List all the registries
    use <registry>               Change registry to registry
    add <registry> <url> [home]  Add one custom registry
    del <registry>               Delete one custom registry
    home <registry> [browser]    Open the homepage of registry with optional browser
    test [registry]              Show the response time for one or all registries
    help                         Print this help

  Options:

    -h, --help     output usage information
    -V, --version  output the version number

Registries

  • npm
  • cnpm
  • nodejitsu
  • taobao
  • rednpm

3.npm 包版本更新工具npm-check-updates

npm-check-updates可以将package.jsonbower.json中的依赖项升级到最新版

clipboard.png

安装

npm install -g npm-check-updates

使用

在当前目录中显示项目的所有新的依赖关系:

$ ncu

express 4.12.x → 4.13.x
multer ^0.1.8 → ^1.0.1
react-bootstrap ^0.22.6 → ^0.24.0
react-a11y ^0.1.1 → ^0.2.6
webpack ~1.9.10 → ~1.10.5

升级项目的包文件:

$ ncu -u
 express           4.12.x  →   4.13.x

更多关于npm-check-updates

4.npm 更新

$ npm i -g npm

5.node进程管理器

在初上手Node.js开发的时候,我们要启动一个服务,使用的是 node 命令:

node myapp

然而,node告诉我们,服务端的js代码只有在node第一次引用,才会重新加载;如果node已经加载了某个文件,即使我们对它进行了修改, node也不会重新加载这个文件。

那么,在开发过程中,要如何才能像PHP一样,修改某个文件后,直接刷新网页就能看到效果呢?

方法有很多,比如使用 Supervisor、pm2、forever 等来管理。

开发环境下进程管理器 Supervisor

1.安装

在开发过程中,每次修改代码保存后,我们都需要手动重启程序,才能查看改动的效果。使用 supervisor 可以解决这个繁琐的问题,全局安装 supervisor。这里注意一点的就是,supervisor必须安装到全局,如果你不安装到全局,错误命令会提示你安装到全局。

  npm install -g supervisor

2.基本使用

最常用、最快捷的方式,就是直接进入你的网站根目录,执行:

supervisor myapp

这里要说明的一点是,不论你的网站服务启动文件在什么位置,你必须在根目录启动它。

举个例子

Express4.0中,启动文件位于 ./bin/www 中,则我们启动时,必须在 ./ 中执行:

supervisor bin/www

clipboard.png

而不能进入 bin 目录执行: supervisor www。这样虽然有可能也能启动,但这么做相当于把 bin 目录当作了服务的根目录了,一旦有涉及到文件目录的操作,一定会出错的。

另外,执行完这个命令后,我们的网站服务就已经启动了;不过,需要注意的是,这种方式启动的服务,是默认监控所有文件、文件夹的变化的;一旦有变化,服务就会重启

这样就出现了一些问题:我们会将一些日志文件存入某些文件夹,或者用户会上传附件到服务器;而这样的操作都导致了服务器文件的变化,必然会引起node服务器的重启。试想一下,如果每一次上传都重启一次,那用户操作一旦频繁起来,服务器啥都不用干,每天重启就行了

所以说,supervisor的这种工作方式,仅仅适用于调试阶段;甚至于有一些调试环境都不适合(比如调试服务器在远程,网络状态不是很好的情况下)。

3.使用方法
我们在命令行中直接执行下边命令,会得到它的详细使用方法

supervisor

如果想不监控某一些文件夹,可以使用 -i 参数。如:我们要忽略根目录下的 private 文件夹,可以这样启动:

supervisor -i ./private myapp

如果要忽略多个文件夹,则用英文的逗号,分隔:

supervisor -i ./private,./otherdir myapp

生产环境下进程管理器 pm2

当我们的项目要部署到线上服务器时,不能单纯的靠 node index 或者 supervisor index 来启动了,因为我们断掉 SSH 连接后服务就终止了,这时我们就需要像 pm2 或者 forever 这样的进程管理器了。pm2 是 Node.js 下的生产环境进程管理工具,就是我们常说的进程守护工具,可以用来在生产环境中进行自动重启、日志记录、错误预警等等。pm2官方文档

以 pm2 为例,全局安装 pm2:

首先需要安装pm2:

npm install -g pm2

运行:

pm2 start www.js

或者 修改 package.json中的start命令,然后运行 npm start 通过 pm2 启动程序

"scripts": {  
   "start": "pm2 start ./bin/www"  
 }  

常用命令总结如下:

安装pm2 npm install -g pm2
启动应用 pm2 start app.js
列出所有应用 pm2 list
查看资源消耗 pm2 monit
查看某一个应用状态 pm2 describe [app id]
查看所有日志 pm2 logs
重启应用 pm2 restart [app id]
停止应用 pm2 stop [app id]
开启api访问 pm2 web

本节参考文章:
1.pm2
2.详细版 | 用Supervisor守护你的Node.js进程
3.supervisor与pm2


6.node 基础入门

本章节主要是学习 Node.js 概述 - 阮一峰 这本书的笔记,里边会结合自己掌握情况简化描述,也会在后续的学习中添加其他书中未提到的知识点。

安装略

6.1.1 执行js脚本,如当前目录demo.js。

$ node demo
# 或者
$ node demo.js

使用-e参数,可以执行代码字符串。

$ node -e 'console.log("Hello World")'
Hello World

6.1.2 REPL环境

在命令行键入node命令,后面没有文件名,就进入一个Node.js的REPL环境(Read–eval–print loop,”读取-求值-输出”循环),可以直接运行各种JavaScript命令。

$ node
> 1+1
2
>

REPL是Node.js与用户互动的shell,各种基本的shell功能都可以在里面使用,比如使用上下方向键遍历曾经使用过的命令。

特殊变量下划线(_)表示上一个命令的返回结果。

> 1 + 1
2
> _ + 1
3

6.1.3 异步操作

Node采用V8引擎处理JavaScript脚本,最大特点就是单线程运行,一次只能运行一个任务。这导致Node大量采用异步操作(asynchronous opertion),即任务不是马上执行,而是插在任务队列的尾部,等到前面的任务运行完后再执行。

由于这种特性,某一个任务的后续操作,往往采用回调函数(callback)的形式进行定义。

var isTrue = function(value, callback) {
  if (value === true) {
    callback(null, "Value was true.");
  }
  else {
    callback(new Error("Value is not true!"));
  }
}

上面代码就把进一步的处理,交给回调函数callback。

Node约定,如果某个函数需要回调函数作为参数,则回调函数是最后一个参数。另外,回调函数本身的第一个参数,约定为上一步传入的错误对象。

var callback = function (error, value) {
  if (error) {
    return console.log(error);
  }
  console.log(value);
}

上面代码中,callback的第一个参数是Error对象,第二个参数才是真正的数据参数。这是因为回调函数主要用于异步操作,当回调函数运行时,前期的操作早结束了,错误的执行栈早就不存在了,传统的错误捕捉机制try…catch对于异步操作行不通,所以只能把错误交给回调函数处理。

try {
  db.User.get(userId, function(err, user) {
    if(err) {
      throw err
    }
    // ...
  })
} catch(e) {
  console.log(‘Oh no!’);
}

上面代码中,db.User.get方法是一个异步操作,等到抛出错误时,可能它所在的try…catch代码块早就运行结束了,这会导致错误无法被捕捉。所以,Node统一规定,一旦异步操作发生错误,就把错误对象传递到回调函数。

如果没有发生错误,回调函数的第一个参数就传入null。这种写法有一个很大的好处,就是说只要判断回调函数的第一个参数,就知道有没有出错,如果不是null,就肯定出错了。另外,这样还可以层层传递错误。

if(err) {
  // 除了放过No Permission错误意外,其他错误传给下一个回调函数
  if(!err.noPermission) {
    return next(err);
  }
}

6.1.4 全局对象和全局变量

Node提供以下几个全局对象,它们是所有模块都可以调用的。

global:表示Node所在的全局环境,类似于浏览器的window对象。需要注意的是,如果在浏览器中声明一个全局变量,实际上是声明了一个全局对象的属性,比如var x = 1等同于设置window.x = 1,但是Node不是这样,至少在模块中不是这样(REPL环境的行为与浏览器一致)。在模块文件中,声明var x = 1,该变量不是global对象的属性,global.x等于undefined。这是因为模块的全局变量都是该模块私有的,其他模块无法取到。

process:该对象表示Node所处的当前进程,允许开发者与该进程互动。

console:指向Node内置的console模块,提供命令行环境中的标准输入、标准输出功能。

Node还提供一些全局函数

setTimeout():用于在指定毫秒之后,运行回调函数。实际的调用间隔,还取决于系统因素。间隔的毫秒数在1毫秒到2,147,483,647毫秒(约24.8天)之间。如果超过这个范围,会被自动改为1毫秒。该方法返回一个整数,代表这个新建定时器的编号。
clearTimeout():用于终止一个setTimeout方法新建的定时器。
setInterval():用于每隔一定毫秒调用回调函数。由于系统因素,可能无法保证每次调用之间正好间隔指定的毫秒数,但只会多于这个间隔,而不会少于它。指定的毫秒数必须是1到2,147,483,647(大约24.8天)之间的整数,如果超过这个范围,会被自动改为1毫秒。该方法返回一个整数,代表这个新建定时器的编号。
clearInterval():终止一个用setInterval方法新建的定时器。
require():用于加载模块。
Buffer():用于操作二进制数据。

Node提供两个全局变量,都以两个下划线开头。

__filename:指向当前运行的脚本文件名。
__dirname:指向当前运行的脚本所在的目录。

除此之外,还有一些对象实际上是模块内部的局部变量,指向的对象根据模块不同而不同,但是所有模块都适用,可以看作是伪全局变量,主要为module, module.exports, exports等。


安装不了node-sass

安装 node-sass 的时候总是会各种不成功

正确姿势

在项目目录 执行

macOS 系统直接运行下面的命令即可:

SASS_BINARY_SITE=https://npm.taobao.org/mirrors/node-sass/ npm install node-sass

windows下的同学可以拆分成两个命令

set SASS_BINARY_SITE=https://npm.taobao.org/mirror...
npm install node-sass

于梦中2010
2.1k 声望181 粉丝

前端菜鸟儿,请多关照!