Node.js学习之一:概念

基本概念

node.js百度百科的解释

第一段如下:

Node.js发布于2009年5月,由Ryan Dahl开发,是一个基于Chrome V8引擎的JavaScript运行环境,使用了一个事件驱动、非阻塞式I/O模型,让JavaScript 运行在服务端的开发平台,它让JavaScript成为与PHP、Python、Perl、Ruby等服务端语言平起平坐的脚本语言。

可以看出,node.js对JavaScript意义重大,极大提升了其江湖地位。 但这一个解释又引出了我如下问题:

  1. V8引擎是啥?
  2. 事件驱动是什么意思?
  3. 非阻塞式I/O模型?还有阻塞式的吧?

node.js维基百科的解释

前三段如下:

Node.js 是能够在服务器端运行 JavaScript 的开放源代码、跨平台执行环境。Node.js 由 OpenJS Foundation (原为 Node.js Foundation,已与 JS Foundation 合并)持有和维护,亦为 Linux 基金会的项目。Node.js 采用 Google 开发的 V8 执行代码,使用事件驱动、非阻塞和异步IO模型等技术来提高性能,可优化应用程序的传输量和规模。这些技术通常用于资料密集的即时应用程序。

Node.js 大部分基本模块都用 JavaScript 语言编写。在 Node.js 出现之前,JavaScript 通常作为客户端程序设计语言使用,以JavaScript 写出的程序常在用户的浏览器上执行。Node.js 的出现使 JavaScript 也能用于服务端编程。Node.js 含有一系列内置模块,使得程序可以脱离 Apache HTTP Server 或 IIS,作为独立服务器执行。

目前,Node.js 已被IBM、Microsoft、Yahoo!、Walmart、Groupon、SAP、LinkedIn、Rakuten、PayPal、Voxer、GoDaddy等企业采用。

Node.js将JavaScript这一只在客户端浏览器上运行的程序语言,扩展到了服务器端编程。 新的问题:

  • 异步IO模型?还有同步IO吧?

扩展概念

  1. V8引擎:V8是一个由Google开发的开源JavaScript引擎,用于Google Chrome及Chromium中。V8在执行之前将JavaScript编译成了机器代码,而非字节码或是解释执行它,以此提升性能。V8还使用了如内联缓存(inline caching)等方法来提高性能。

    Lars Bak是这个项目的组长,以V8发动机为其命名。V8发动机是一款8汽缸的V型发动机,在大型汽车中使用。

  2. 事件驱动:事件驱动程序设计(Event-driven programming)是一种计算机程序设计模型。这种模型的程序执行流程是由用户的动作(如鼠标的按键,键盘的按键动作)或者是由其他程序的消息来决定的。图形用户界面类程序是典型的事件驱动设计方式。计算机操作系统也是事件驱动程序的典型示例。

    对应概念:批处理程序设计(batch programming),程序执行的流程由程序员来决定。

  3. 非阻塞式I/OI/O是从程序本身视角而言,指与系统磁盘或网络之间的交互;阻塞是指在 Node.js 程序中,其它 JavaScript 语句的执行,必须等待一个非 JavaScript 操作完成。(当阻塞发生时,事件循环无法继续运行 JavaScript。)非阻塞则非如此,通过接受回调函数,可以在其它操作进行时(如读取文件)继续执行其它 JavaScript 语句。

    阻塞|非阻塞 vs 异步|同步:阻塞方法同步执行,非阻塞方法异步执行。

  4. 异步I/O:是计算机操作系统对输入输出的一种处理方式,即发起I/O请求的线程不等I/O操作完成,就继续执行随后的代码,I/O结果用其他方式通知发起I/O请求的程序。

    对应概念:同步(阻塞)I/O,即发起I/O请求的线程不从正在调用的I/O操作函数返回(即被阻塞),直至I/O操作完成。

了解与尝试

B站视频:node.js 到底是什么鬼?

啥是node,node有啥用,啥又是npm,
package.json是个啥
node_modules里放的啥

npm

node.js:基于v8引擎的JavaScript运行时(runtime,也即运行环境)。

npm:Node.js附带的包管理器(Node package manager)

npm是一个命令行工具,用于从NPM Registry中下载、安装Node.js程序,同时解决依赖问题。
npm, Inc.是Node package manager背后的公司,提供npm Registry 和 npm CLI

问题:

  1. npm Registry 是什么?
  2. npm CLI 啥意思?

著名的 packages 比如:

  • jquery
  • vue
  • react
  • lodash

npm用来下载(安装)、管理(升级、删除)这些包。

  • 下载安装jquerylodash(新建一个测试目录:nodeTest)

    1
    2
    3
    4
    5
    6
    $ cd "D:\MyStuday\nodeTest"
    $ mkdir test1
    $ cd test1
    JING@LAPTOP-DEHH91FV MINGW64 /d/MyStuday/nodeTest/test1
    $ npm install jquery
    $ npm install lodash
    • 删除lodash
    1
    $ npm uninstall lodash

    在目录test1\node_modules下,相应package以单独文件夹的形式存在,package依赖信息记录在文件package.jsonpackage-lock.json中,如:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    // package.json 两个package时
    {
    "dependencies": {
    "jquery": "^3.6.0",
    "lodash": "^4.17.21"
    }
    }

    // package-lock.json 一个package时
    {
    "name": "test1",
    "lockfileVersion": 2,
    "requires": true,
    "packages": {
    "": {
    "dependencies": {
    "jquery": "^3.6.0"
    }
    },
    "node_modules/jquery": {
    "version": "3.6.0",
    "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.6.0.tgz",
    "integrity": "sha512-JVzAR/AjBvVt2BmYhxRCSYysDsPcssdmTFnzyLEts9qNwmjmu4JTAMYubEfwVOSwpQ1I1sKKFcxhZCI2buerfw=="
    }
    },
    "dependencies": {
    "jquery": {
    "version": "3.6.0",
    "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.6.0.tgz",
    "integrity": "sha512-JVzAR/AjBvVt2BmYhxRCSYysDsPcssdmTFnzyLEts9qNwmjmu4JTAMYubEfwVOSwpQ1I1sKKFcxhZCI2buerfw=="
    }
    }
    }

package.json

工程移交或上传时,仅提供 package.json 文件即可,而无需对整个node_modules目录打包。
可根据 package.json 下载所依赖的package的指令为:npm install,或简写为 npm i

1
2
$ npm i
added 2 packages, and audited 3 packages in 3s

此外,在一个空目录下运行npm init,初始化该目录:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
JING@LAPTOP-DEHH91FV MINGW64 /d/MyStuday/nodeTest/test1
$ cd ..
$ mkdir test2
$ cd test2
JING@LAPTOP-DEHH91FV MINGW64 /d/MyStuday/nodeTest/test2
$ npm init
This utility will walk you through creating a package.json file.
It only covers the most common items, and tries to guess sensible defaults.

See `npm help init` for definitive documentation on these fields
and exactly what they do.

Use `npm install <pkg>` afterwards to install a package and
save it as a dependency in the package.json file.

Press ^C at any time to quit.
package name: (test2)
version: (1.0.0)
description:
entry point: (index.js)
test command:
git repository:
keywords:
author:
license: (ISC)
About to write to D:\MyStuday\nodeTest\test2\package.json:

{
"name": "test2",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC"
}

Is this OK? (yes) yes

在package name: (test2)停顿后,连续输入回车向后执行。

生成一个package.json 文件:

1
2
3
4
5
6
7
8
9
10
11
12
// package.json ,空目录 npm init 生成
{
"name": "test2",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC"
}

解释一下package.json

过程中输入npm i jquery安装一个包,package.json文件内增加dependencies项; node_modulespackage.json文件,描述jquery的信息和依赖项。

  • main:入口文件,告诉引用者从哪里开始执行;

  • scripts:脚本命令集,比如上述文件定义了test脚本命令,可npm run执行,结果如下

    1
    2
    3
    4
    5
    6
    $ npm run test

    > test2@1.0.0 test
    > echo "Error: no test specified" && exit 1 # 脚本命令语句

    "Error: no test specified" # 执行结果,打印信息

多条脚本每行结束要有逗号,,如

1
2
3
4
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"test_ls": "ls -l"
},

执行第二条脚本test_ls

1
2
3
4
5
6
7
8
9
10
$ npm run test_ls

> test2@1.0.0 test_ls
> ls -l

total 6
drwxr-xr-x 1 JING 197609 0 May 13 18:58 node_modules
-rw-r--r-- 1 JING 197609 774 May 13 18:58 package-lock.json
-rw-r--r-- 1 JING 197609 273 May 13 19:17 package.json
-rw-r--r-- 1 JING 197609 272 May 13 19:16 package.json.bak

概念扩展

  1. npm Registry:npm模块仓库提供了一个名为“registry”的查询服务,用户可通过本地的npm命令下载并安装指定模块。此外用户也可以通过npm把自己设计的模块分发到registry上面。registry上面的模块通常采用CommonJS格式,而且都包含一个JSON格式的元文件。

  2. npm CLI:npm 的 command-line interface(命令行界面)。

    CLI 通常不支持鼠标(也可支持),用户通过键盘输入指令,计算机接收到指令后,予以执行。又称字符用户界面(character user interface, CUI)。常用的CLI,如

    • bash / sh / ksh / csh / zsh(Unix-like系统)
    • COMMAND.COM(MS-DOS系统)
    • DIGITAL命令语言(VMS)
    • cmd.exe / 命令提示符(Windows NT和Windows CE系统)
    • Windows PowerShell(支持.NET Framework技术的Windows NT系统)