NodeJS (或 Node.js) 是一个事件驱动 I/O 服务端 JavaScript 环境,基于 Google 的 V8 引擎,V8 引擎执行 Javascript 的速度非常快,性能非常好。简而言之,NodeJS 就是运行在服务端的 JavaScript。
NVM (Node Version Manage),即 NodeJS 的版本管理工具。不同项目依赖不同的 NodeJS 版本,使用 NVM 可以在多个 NodeJS 版本之间快速切换。
NodeJS: https://nodejs.org
1. 系统环境
操作系统:Windows 10 (x64)
NodeJS: 16.14.2 或 18.16.0
2. 使用 NVM 安装 NodeJS
1) 安装 NVM
下载 NVM 安装包 https://github.com/coreybutler/nvm-windows/releases,选择下载 nvm-setup.zip,双击 nvm-setup.exe 文件,进入安装过程,按默认选项即可。
打开命令行窗口,运行 nvm -v,出现版本号即表示安装成功。
C:\Users\admin>nvm -v
1.1.11
注:安装 NVM 前,建议先卸载电脑上现有的 NodeJS,避免冗余。
安装程序会自动帮我们配置了环境变量 NVM_HOME 和 NVM_SYMLINK,并且配置了 Path 的值,免安装版的 NVM,需要手动配置环境变量。
可以修改 NVM 根目录下的 setting.txt 文件,配置 NodeJS 下载代理镜像,解决在线安装 NodeJS 时速度慢的问题。
2) 安装 NodeJS
使用 nvm list available 命令,查看可安装的 NodeJS 版本。建议选择 LTS 中的版本进行安装(LTS,即Long Term Support,长期支持版本)。
C:\Users\admin> nvm list available
| CURRENT | LTS | OLD STABLE | OLD UNSTABLE | |--------------|--------------|--------------|--------------| | 20.3.0 | 18.16.0 | 0.12.18 | 0.11.16 | | 20.2.0 | 18.15.0 | 0.12.17 | 0.11.15 | | 20.1.0 | 18.14.2 | 0.12.16 | 0.11.14 | | 20.0.0 | 18.14.1 | 0.12.15 | 0.11.13 | | 19.9.0 | 18.14.0 | 0.12.14 | 0.11.12 | | 19.8.1 | 18.13.0 | 0.12.13 | 0.11.11 | | 19.8.0 | 18.12.1 | 0.12.12 | 0.11.10 | | 19.7.0 | 18.12.0 | 0.12.11 | 0.11.9 | | 19.6.1 | 16.20.0 | 0.12.10 | 0.11.8 | | 19.6.0 | 16.19.1 | 0.12.9 | 0.11.7 | | 19.5.0 | 16.19.0 | 0.12.8 | 0.11.6 | | 19.4.0 | 16.18.1 | 0.12.7 | 0.11.5 | | 19.3.0 | 16.18.0 | 0.12.6 | 0.11.4 | | 19.2.0 | 16.17.1 | 0.12.5 | 0.11.3 | | 19.1.0 | 16.17.0 | 0.12.4 | 0.11.2 | | 19.0.1 | 16.16.0 | 0.12.3 | 0.11.1 | | 19.0.0 | 16.15.1 | 0.12.2 | 0.11.0 | | 18.11.0 | 16.15.0 | 0.12.1 | 0.9.12 | | 18.10.0 | 16.14.2 | 0.12.0 | 0.9.11 | | 18.9.1 | 16.14.1 | 0.10.48 | 0.9.10 | This is a partial list. For a complete list, visit https://nodejs.org/en/download/releases
使用 nvm install 命令,进行对应版本 NodeJS 的在线安装,这里安装 18.16.0 和 16.14.2,运行如下命令。
C:\Users\admin> nvm install 18.16.0
...
C:\Users\admin> nvm install 16.14.2
...
C:\Users\admin> nvm list
18.16.0
16.14.2
# 使用或切换版本
C:\Users\admin> nvm use 16.14.2
Now using node v16.14.2 (64-bit)
C:\Users\admin> nvm list
18.16.0
* 16.14.2 (Currently using 64-bit executable)
C:\Users\admin> node -v
v16.14.2
C:\Users\admin> npm -v
8.5.0
注:老版本的 NodeJS 不包含 npm,
在线安装 nodeJS 如果遇到问题,也可以从 https://nodejs.org/en/download/releases 下载 NodeJS 离线安装包,解压后放入到 NVM 安装路径的根目录下,即可完成离线安装。
3) NVM 常用命令
nvm list:列出所有已经在 NVM 中安装的 NodeJS 版本,简写 nvm ls。
nvm list available:查看可在线安装的 NodeJS 版本。
nvm current:显示当前正在使用的 NodeJS 版本。
nvm install xx.xx.xx:在线安装指定版本的 NodeJS,xx.xx.xx 为指定的版本号。
nvm uninstall xx.xx.xx:卸载指定版本的 NodeJS,xx.xx.xx 为指定的版本号。
nvm use xx.xx.xx:切换 NodeJS 版本,xx.xx.xx 为指定的版本号。
nvm version:显示当前所使用的 NVM 的版本号。
3. 安装 cnpm(可选项)
npm 默认的仓库地址为 http://registry.npmjs.org,可以使用如下命令查看当前 npm 仓库。
C:\Users\admin> npm config get registry
https://registry.npmjs.org/
在国内访问国外的仓库,有时候访问速度比较慢,甚至无法访问。为了解决这个问题,可以使用如下 2 种方法中的 1 种。
1) 安装 cnpm
C:\Users\admin> npm install cnpm -g
# 在国内可以使用如下命令
C:\Users\admin> npm install cnpm -g --registry=https://registry.npmmirror.com
直接使用 cpm 替代 npm,参数和 npm 命令一样,比如 npm install uniq --save 对应 cnpm 命令为cnpm install uniq --save
注:https://registry.npmmirror.com 是 npm 的官方镜像站,也可以使用 https://registry.npm.taobao.org,下同。
2) 替换 npm 的仓库地址
C:\Users\admin> npm config set registry https://registry.npmmirror.com
C:\Users\admin> npm config get registry
https://registry.npmmirror.com
4. NodeJS 交互式解释器 (Read Eval Print Loop, REPL)
NodeJS REPL 表示一个电脑的环境,类似 Windows 系统的终端或 Unix/Linux shell,可以在终端中输入命令,并接收系统的响应。
Node 自带了交互式解释器,可以执行以下任务:
读取 - 读取用户输入,解析输入的 Javascript 数据结构并存储在内存中。
执行 - 执行输入的数据结构。
打印 - 输出结果。
循环 - 循环操作以上步骤直到用户两次按下 ctrl-c 按钮退出。
Node 的交互式解释器可以很好的调试 Javascript 代码。
1) 示例
C:\Users\admin> node
Welcome to Node.js v16.14.2. Type ".help" for more information. # 表达式运算 > 1+1 2 > 2-1 1 > 2*3 6 > 5/2 2.5 # 使用变量 > a=1 1 > var b=2 undefined > a+b 3 > console.log(b) 2 undefined > console.log('hello world') hello world undefined 注:没有使用 var 关键字变量会直接打印出来,使用 var 关键字的变量可以使用 console.log() 来输出变量。 # 多行表达式 > var x=0 undefined > for (i=0;i<5;i++){ ... x++; ... console.log("x: " + x); ... } x: 1 x: 2 x: 3 x: 4 x: 5 undefined # 下划线(_)变量,可以使用下划线(_)获取上一个表达式的运算结果 > var a=3 undefined > var b=8 undefined > a+b 11 > console.log(_) 11
2) REPL 命令
ctrl + c - 退出当前终端
ctrl + c 按下两次 - 退出 Node REPL
ctrl + d - 退出 Node REPL
向上/向下 键 - 查看输入的历史命令
tab 键 - 列出当前命令
.help - 列出使用命令
.break - 退出多行表达式
.clear - 退出多行表达式
.save filename - 保存当前的 Node REPL 会话到指定文件
.load filename - 载入当前 Node REPL 会话的文件内容
5. NodeJS 脚本
1) Hello World
创建 D:\workshop\nodejs\hello.js 脚本文件,内容如下
console.log("Hello World");
运行
D:\workshop\nodejs> node hello.js
或
D:\workshop\nodejs> node hello
Hello world!
2) 简单 Web 服务器
我们使用 require 指令来载入 http 模块,并使用 http.createServer() 方法创建一个简单 Web 服务器,使用 listen 方法绑定 8000 端口。 函数通过 request, response 参数来接收和响应数据。
创建 D:\workshop\nodejs\server.js 文件,内容如下
var http = require('http'); http.createServer(function (request, response) { response.writeHead(200, {'Content-Type': 'text/plain'}); response.end('Web: Hello World!'); }).listen(8000); console.log('Server running at http://localhost:8000/');
运行
D:\workshop\nodejs> node server
Server running at http://localhost:8000
打开浏览器访问 http://localhost:8000,显示如下内容
Web: Hello World!
6. NodeJS 模块系统
模块是 NodeJS 应用程序的基本组成部分,文件和模块是一一对应的。换言之,一个 NodeJS 文件就是一个模块,这个文件可能是 JavaScript 代码、JSON 或者编译过的 C/C++ 扩展。
NodeJS 提供了 exports 和 require 两个对象,其中 exports 是模块公开的接口,require 用于从外部获取一个模块的接口,即所获取模块的 exports 对象。
示例1
修改 D:\workshop\nodejs\hello.js 文件,内容如下
exports.test = function() { console.log('Hello World'); }
创建一个 D:\workshop\nodejs\main.js 文件,内容如下
var hello = require('./hello'); // 导入 hello 模块 console.log("typeof(hello): " + typeof(hello)); hello.test();
运行
D:\workshop\nodejs> node main
typeof(hello): object
Hello world
示例2
创建 D:\workshop\nodejs\hello2.js 文件,内容如下
module.exports.test = function() { console.log('Hello World 2'); }
创建一个 D:\workshop\nodejs\main2.js 文件,内容如下
var hello2 = require('./hello2'); // 导入 hello2 模块 console.log("typeof(hello2): " + typeof(hello2)); hello2.test();
运行
D:\workshop\nodejs> node main2
typeof(hello2): object
Hello world 2
示例3
创建 D:\workshop\nodejs\hello3.js 文件,内容如下
module.exports = function() { console.log('Hello World 3'); }
创建一个 D:\workshop\nodejs\main3.js 文件,内容如下
var hello3 = require('./hello3'); // 导入 hello3 模块 console.log("typeof(hello3): " + typeof(hello3)); hello3();
运行
D:\workshop\nodejs> node main3
typeof(hello3): function
Hello world 3
示例4
修改 D:\workshop\nodejs\hello4.js 文件,内容如下
exports = function() { console.log('Hello World 4'); }
创建一个 D:\workshop\nodejs\main4.js 文件,内容如下
var hello4 = require('./hello4'); // 导入 hello4 模块 console.log("typeof(hello4): " + typeof(hello4)); hello4();
运行
D:\workshop\nodejs> node main4
typeof(hello4): object D:\Workshop\dev-nodejs\main4.js:3 hello4(); ^ TypeError: hello4 is not a function at Object.<anonymous> (D:\Workshop\dev-nodejs\main4.js:3:1) at Module._compile (node:internal/modules/cjs/loader:1103:14) at Object.Module._extensions..js (node:internal/modules/cjs/loader:1157:10) at Module.load (node:internal/modules/cjs/loader:981:32) at Function.Module._load (node:internal/modules/cjs/loader:822:12) at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:77:12) at node:internal/main/run_main_module:17:47
CommonJS 规范规定,每个模块内部,module 变量代表当前模块。这个变量是一个对象,它的 exports 属性(即module.exports)是对外的接口。加载某个模块,其实是加载该模块的 module.exports 属性。并且 Node 为每个模块提供一个 exports 变量 (或引用),指向 module.exports。
exports 和 module.exports 的区别:
(1) exports 只能使用 . 语法来向外暴露内部变量,比如:expotrs.xxx = xxx;
(2) module.exports 既可以通过.语法,也可以直接赋值一个对象。