├── .gitattributes
├── 01-what-is-nodejs
├── README.md
├── different-between-chrome-and-nodejs.png
├── javascript-event-handling.png
├── nodejs-module-system-diagram.png
├── operating-principle-of-web.png
├── the-way-the-brain-work.png
└── the-way-the-server-work.png
├── 02-hello-world.md
├── 02-install-nodejs
├── README.md
├── command-line.png
├── macos-nodejs-installation-step-five.png
├── macos-nodejs-installation-step-four.png
├── macos-nodejs-installation-step-one.png
├── macos-nodejs-installation-step-seven.png
├── macos-nodejs-installation-step-six.png
├── macos-nodejs-installation-step-three.png
├── macos-nodejs-installation-step-two.png
├── macos-system-environment-installation-nodejs.md
├── nodejs-installation-file-macos.png
├── nodejs-installation-file.png
├── nodejs-installation-step-eight.png
├── nodejs-installation-step-five.png
├── nodejs-installation-step-four.png
├── nodejs-installation-step-one.png
├── nodejs-installation-step-seven.png
├── nodejs-installation-step-six.png
├── nodejs-installation-step-three.png
├── nodejs-installation-step-two.png
├── nodejs-official-website-macos.png
├── nodejs-official-website.png
├── nodejs-v-command.png
├── nodejs-v-terminal.png
├── nodejs-version.png
├── npm-v-command.png
├── npm-v-terminal.png
├── terminal.png
└── windows-system-environment-installation-nodejs.md
├── 03-first-sample.md
├── 03-windows-system-environment-installation-nodejs
├── README.md
├── command-line.png
├── nodejs-installation-file.png
├── nodejs-installation-step-eight.png
├── nodejs-installation-step-five.png
├── nodejs-installation-step-four.png
├── nodejs-installation-step-one.png
├── nodejs-installation-step-seven.png
├── nodejs-installation-step-six.png
├── nodejs-installation-step-three.png
├── nodejs-installation-step-two.png
├── nodejs-official-website.png
├── nodejs-v-command.png
├── nodejs-v-terminal.png
├── nodejs-version.png
└── npm-v-command.png
├── 04-macos-system-environment-installation-nodejs
├── README.md
├── macos-nodejs-installation-step-five.png
├── macos-nodejs-installation-step-four.png
├── macos-nodejs-installation-step-one.png
├── macos-nodejs-installation-step-seven.png
├── macos-nodejs-installation-step-six.png
├── macos-nodejs-installation-step-three.png
├── macos-nodejs-installation-step-two.png
├── nodejs-installation-file-macos.png
├── nodejs-official-website-macos.png
├── nodejs-v-terminal.png
├── nodejs-version.png
├── npm-v-terminal.png
└── terminal.png
├── 04-module-system.md
├── 05-create-server.md
├── 05-nodejs-repl
└── README.md
├── 06-client-request.md
├── 06-hello-world
└── README.md
├── 07-official-sample
└── README.md
├── 08-keywords-const
└── README.md
├── 09-difference-between-var-let-and-const
└── README.md
├── 10-block-scope
└── README.md
├── 11-arrow-function
└── README.md
├── 12-arrow-function-notes
└── README.md
├── 13-template-string
└── README.md
├── 14-what-is-modularity
└── README.md
├── 15-javascript-module
└── README.md
├── 16-ecmascript-2015-module
└── README.md
├── 17-node-modular-system
└── README.md
├── 18-node-file-module
└── README.md
├── 19-nodejs-module-object
└── README.md
├── 20-modular-specification
└── README.md
├── LICENSE
├── README.md
├── SUMMARY.md
├── cover.png
└── images
├── 2016-12-05-16-43-05.png
├── 2016-12-06-14-17-03.jpg
├── 2016-12-06-17-41-46.png
├── 2016-12-10-23-22-23.png
├── 5e10d357716faf0b.png
├── Snip20161126_1.png
├── Snip20161205_1.png
├── Snip20161205_3.png
├── Snip20161205_4.png
├── Snip20161206_10.png
├── Snip20161206_11.png
├── Snip20161206_12.png
├── Snip20161206_13.png
├── Snip20161206_5.png
├── Snip20161206_6.png
├── Snip20161206_9.png
├── Snip20161207_14.png
├── Snip20161207_15.png
├── Snip20161207_16.png
├── Snip20161211_22.png
├── Snip20161211_23.png
├── Snip20161211_24.png
└── Snip20161211_25.png
/.gitattributes:
--------------------------------------------------------------------------------
1 | *.md linguist-language=JavaScript
2 | *.png linguist-language=JavaScript
3 |
--------------------------------------------------------------------------------
/01-what-is-nodejs/README.md:
--------------------------------------------------------------------------------
1 | # 什么是 Node.js
2 |
3 | **作为本套课程的开篇第一回。首先,我们需要搞懂什么是 Node.js,Node.js 有哪些特点,以及需要掌握的相关概念。**
4 |
5 | ## Node.js 的官方介绍
6 |
7 | 在 Node.js 的[官方网站](https://nodejs.org/en/)的首页中,有这样一句话来描述 Node.js:
8 |
9 | > Node.js® is a JavaScript runtime built on Chrome's V8 JavaScript engine. Node.js uses an event-driven, non-blocking I/O model that makes it lightweight and efficient.
翻译过来的意思就是:
10 |
11 | > Node.js 是基于 Chrome 的 V8 JavaScript 引擎的 JavaScript 运行时。Node.js 采用事件驱动、非堵塞 I/O 模型,使其轻量化和高效。
12 |
13 | 上面这句话的第一句说明了什么是 Node.js,第二句说明了 Node.js 的特点。
14 |
15 | 想要搞懂官方这句话的具体含义,我们还要从 JavaScript 语言说起。
16 |
17 | ## Node.js 的核心开发语言
18 |
19 | > 这里假设你已经掌握了 JavaScript 语言的基础语法以及基本使用。**如果还没有掌握 JavaScript 的话,还是先去入门一下 JavaScript 语言吧。**
20 |
21 | 掌握了 JavaScript 语言的应该知道,JavaScript 语言是作为浏览器的脚本语言,可以实现网页与用户之间的交互。
22 |
23 | > 什么是交互?比如用户在网页中输入用户名或密码,这种用户输入行为就可以叫做交互。或者用户点击网页中的按钮等等,都可以叫做交互。
24 |
25 | JavaScript 语言之所以可以实现网页与用户之间的交互,主要是依靠事件来完成的。比如,用户的输入事件、点击按钮事件等等。
26 |
27 | 下面我们通过用户点击按钮的行为为例,来看看 JavaScript 语言是如何处理的。
28 |
29 | 
30 |
31 | 通过上面的分析图,我们可以清晰的看到:
32 |
33 | 1. 用户点击网页的按钮,执行 JavaScript 逻辑。
34 | 2. JavaScript 逻辑经历三个阶段,分别是捕获事件、触发事件和事件冒泡。
35 | 3. 当 JavaScript 逻辑执行完毕后,会将结果返回网页。
36 | 4. 网页再根据结果显示给用户。
37 |
38 | 通过这样的一个小案例,我们可以知道 JavaScript 语言处理网页与用户之间的交互,主要是依靠**事件驱动**。
39 |
40 | ## 网页与 Node.js 中 JavaScript 的区别
41 |
42 | 目前几乎所有的浏览器都支持 JavaScript 语言,之所以支持的原因在于浏览器中都集成了 JavaScript 引擎。
43 |
44 | 在众多浏览器中,Chrome 浏览器的性能相对更好,而且 Chrome 浏览器集成的 V8 JavaScript 引擎还是开源的。
45 |
46 | 而 Node.js 就是利用了 Chrome 浏览器的开源 V8 JavaScript 引擎。那在网页中使用 JavaScript 语言和在 Node.js 中使用 JavaScript 语言有什么不同呢?我们可以通过下面这张图来了解一下。
47 |
48 | 
49 |
50 | 通过上图可以清晰地看到,Node.js 相对于浏览器 Node.js 没有提供 WebKit 内核和 HTML 相关的 UI 技术。也就是说,Node.js 只提供了 JavaScript 语言。
51 |
52 | 为什么要这样呢?其实,Node.js 的作者最初的想法就是想设计一个轻量和高效的服务器。
53 |
54 | ## 什么是服务器
55 |
56 | 那服务器又是什么呢?如果把一个 WEB 应用比作是一个人的话,那服务器就是人的大脑。
57 |
58 | 
59 |
60 | 通过上面的图我们可以知道,人与人交流时,基本上要通过以下几个步骤:
61 |
62 | 1. 别人与我交流,我是通过人的感官进行接收。
63 | 2. 感官将信息传递给大脑。
64 | 3. 大脑接收到信息后,进行处理,将处理的结果返回。
65 | 4. 再通过感官反馈给与我交流的人。
66 |
67 | 通过这个过程,我们可以发现,别人是直接通过感官与我交流的,并不知道大脑是如何工作的,也并不关心大脑是如何工作的。
68 |
69 | 
70 |
71 | 而 WEB 应用与人类似,用户是与网页进行交互,网页将信息传递给服务器,服务器接收、处理并响应,最后网页将结果显示给用户。
72 |
73 | 作为用户来说,并不关心服务器是如何工作的,甚至用户都感觉不到服务器的存在。但是,作为开发人员,想要开发一个完整的 WEB 应用,服务器的逻辑核心。
74 |
75 | > 从现在开始,我们要从用户思维转变成开发思维。通过开发思维重新审视我们曾经使用过的 WEB 应用,你会发现有所不同。
76 | >
77 | > **思维的转变是很重要的!很重要的!很重要的!重要的事儿说三遍。**
78 |
79 | ## Node.js 的简单理解
80 |
81 | 讲到这里,我们可以简单地来归纳一下 Node.js 到底是什么了。
82 |
83 | > Node.js 就是基于 Chrome 浏览器的 V8 JavaScript 引擎,以 JavaScript 语言为核心开发语言的服务器技术。
84 |
85 | 如果使用 Node.js 开发一个 WEB 应用应该是怎么样的呢?
86 |
87 | 
88 |
89 | 由于 JavaScript 逻辑是依靠事件驱动的,所以就不难理解 Node.js 是事件驱动的了。
90 |
91 | > 想要更好地理解和掌握 Node.js,还是先回去恶补一下 JavaScript 语言中的事件处理那些内容吧!
92 |
93 | Node.js 除了是基于 Chrome 浏览器的 V8 引擎以外,还提供了一系列的模块,让我们可以方便地实现一些功能。比如,处理客户端的请求、文件的处理等操作。
94 |
95 | 
96 |
97 | 我们学习 Node.js,主要就是学习 Node.js 所提供的模块内容。所以,不要着急,我们慢慢来。
98 |
99 | ### [下一回 安装 Node.js](../02-install-nodejs/README.md)
--------------------------------------------------------------------------------
/01-what-is-nodejs/different-between-chrome-and-nodejs.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstack-kingj/easy-node/42830f0d2280878409d8a54f0e311ea5a451bd68/01-what-is-nodejs/different-between-chrome-and-nodejs.png
--------------------------------------------------------------------------------
/01-what-is-nodejs/javascript-event-handling.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstack-kingj/easy-node/42830f0d2280878409d8a54f0e311ea5a451bd68/01-what-is-nodejs/javascript-event-handling.png
--------------------------------------------------------------------------------
/01-what-is-nodejs/nodejs-module-system-diagram.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstack-kingj/easy-node/42830f0d2280878409d8a54f0e311ea5a451bd68/01-what-is-nodejs/nodejs-module-system-diagram.png
--------------------------------------------------------------------------------
/01-what-is-nodejs/operating-principle-of-web.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstack-kingj/easy-node/42830f0d2280878409d8a54f0e311ea5a451bd68/01-what-is-nodejs/operating-principle-of-web.png
--------------------------------------------------------------------------------
/01-what-is-nodejs/the-way-the-brain-work.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstack-kingj/easy-node/42830f0d2280878409d8a54f0e311ea5a451bd68/01-what-is-nodejs/the-way-the-brain-work.png
--------------------------------------------------------------------------------
/01-what-is-nodejs/the-way-the-server-work.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstack-kingj/easy-node/42830f0d2280878409d8a54f0e311ea5a451bd68/01-what-is-nodejs/the-way-the-server-work.png
--------------------------------------------------------------------------------
/02-hello-world.md:
--------------------------------------------------------------------------------
1 | **在本节课中,我们将学习在命令行运行 Hello World 程序,常见的命令行选项,以及 Node.js 的 REPL 模块。**
2 |
3 | ## 通过 REPL 运行 Hello World
4 |
5 | ### 1. Hello World
6 |
7 | 打开 Mac 系统的“终端”软件或 Windows 系统的“命令行窗口”。
8 | 输入 `node` 命令,即可进入 Node.js 的 REPL 模式。如下图:
9 |
10 | 
11 | 
12 | 在 REPL 模式下,输入以下语句,并且回车查看结果。
13 |
14 | ```javascript
15 | console.log("Hello World");
16 | ```
17 |
18 | **需要说明的是:** `console` 是 Node.js 的全局对象,作用与浏览器中开发者工具的控制台类似。
19 |
20 | 
21 |
22 | 如上图所示,我们会看到输出的 `Hello World` 内容。
23 | **值得注意的是:** `undefined` 表示 `console.log()` 方法没有任何返回值。
24 | ### 2. Node.js 的 REPL
25 |
26 | REPL 的全称是 Read-Eval-Print-Loop,表示 读取-执行-输出-循环,是 Node.js 提供的一个交互式运行环境。
27 |
28 | REPL 既可以像上述示例一样作为独立程序运行,也可以嵌入到其他程序中。
29 |
30 | 通过这样的一个交互式运行环境,我们可以调试、测试 JavaScript 代码逻辑。
31 |
32 | #### 1) REPL 提供的命令
33 |
34 | REPL 提供了一些命令,方便我们更好地使用这样的交互式运行环境。
35 |
36 | - `.break`: 当输入多行表达式时,`.break` 命令(或者`ctrl+c`)可以跳出本次输入,或者重新输入。
37 | - `.clear`: 重置 REPL 的 `context` 对象为空对象,并且清除输入的多行表达式。
38 | - `.exit`: 表示退出 REPL 环境,也可以通过输入两次 `ctrl+c` 完成同样的目的。
39 | - `.help`: 表示输出 REPL 提供的命令帮助内容。
40 |
41 | #### 2) REPL 的其他命令
42 |
43 | - `.save`: 将当前 REPL 输入的内容保存成一个文件。具体句法如下:
44 | ```
45 | .save ./file/to/save.js
46 | ```
47 | - `.load`: 将指定文件中的代码加载到当前的 REPL 环境中。具体语法如下:
48 |
49 | ```
50 | .load ./file/from/load.js
51 | ```
52 |
53 | ## 通过 Node 命令运行 Hello World
54 |
55 | 我们也可以将通过 Node 命令来运行一个指定的 JavaScript 文件。
56 |
57 | ### 1. Hello World
58 |
59 | 首先,创建一个 JavaScript 文件,输入以下代码内容:
60 |
61 | ```javascript
62 | console.log("Hello World");
63 | ```
64 |
65 | 然后,打开“终端”软件或者“命令行窗口”,执行以下命令:
66 |
67 | ```
68 | node example.js
69 | ```
70 |
71 | **值得注意的是:** “终端”或者“命令行窗口”中的目录,必须与 `example.js` 文件是同一目录。
72 |
73 | ### 2. Node.js 的命令行选项
74 |
75 | 命令行选项是 Node.js 提供给我们用来运行、调试 JavaScript 代码的。我们可以通过以下命令来查看帮助文档:
76 |
77 | ```
78 | man node
79 | ```
80 |
81 | 也可以通过以下命令来查看 `node` 命令的可用选项有哪些:
82 |
83 | ```
84 | node -h 或者 node --help
85 | ```
--------------------------------------------------------------------------------
/02-install-nodejs/README.md:
--------------------------------------------------------------------------------
1 | ### [上一回 什么是 Node.js](../01-what-is-nodejs/README.md)
2 |
3 | # 安装 Node.js
4 |
5 | ## 从官网获取最新版本的 Node.js
6 |
7 | 安装 Node.js 的最简单方法,就是从 Node.js 的[官方网站](https://nodejs.org/en/)获取最新版本的安装文件进行安装。
8 |
9 | 
10 |
11 | Windows 系统或者 MacOS 系统可以参考下面的图文教程来进行安装:
12 |
13 | - [Windows 系统环境安装 Node.js 参考教程](../03-windows-system-environment-installation-nodejs/README.md)
14 | - [MacOS 系统环境安装 Node.js 参考教程](../04-macos-system-environment-installation-nodejs/README.md)
15 |
16 | > **这里需要注意的是:**
17 | >
18 | > - 这种方式安装,每次更新 Node.js 的版本,都需要从官网下载,并且进行覆盖安装。
19 | > - 这种方式安装,在系统中只能存在一个版本的 Node.js ,不适合对比学习。
20 | >
21 | > 如果你是第一次接触 Node.js,建议还是先使用官方这种方式安装最新版本的 Node.js。
22 |
23 | ## 使用 nvm 管理多版本 Node.js
24 |
25 | 首先,我们来简单地来了解一下 nvm。
26 |
27 | nvm 是 [Tim Caswell](https://github.com/creationix) 开发的一款 MacOS 系统中使用的通过命令方式管理多版本 Node.js 的软件。
28 |
29 | > nvm 软件的相关介绍,可以访问[该项目的 github 主页](https://github.com/creationix/nvm)。
30 |
31 | ### 一. 安装 nvm 版本管理器
32 |
33 | > 想要成功的安装 nvm,MaOS 系统下必须要先安装 Xcode 软件, Xcode 软件大概在 4.3GB 左右。
34 |
35 | 如果不想安装 Xcode 软件,又想成功安装 nvm 的话,可以按照以下方式操作:
36 |
37 | 1、打开“终端”窗口,并输入以下命令。
38 |
39 | ```
40 | xcode-select --install
41 | ```
42 |
43 | 2、执行上述命令后,会自动弹出软件安装的提示窗口。点击【Install】按钮,进行安装。(**这个软件大概 130MB 左右**)
44 |
45 | > 通过上述步骤可以替代安装 Xcode 软件,以保证成功安装 nvm 软件。
46 |
47 | 3、打开“终端”窗口,输入以下命令,在线安装 nvm 软件:
48 |
49 | ```
50 | curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.32.1/install.sh|bash
51 | ```
52 |
53 | > **这里需要注意的是:**nvm 只能通过命令在线安装。所以,安装之前要确保电脑是可以联网的。
54 |
55 | 4、安装成功之后,在“终端”窗口,输入 `nvm` 命令,验证 nvm 是否安装成功。
56 |
57 | ### 二、使用 nvm 安装 Node.js
58 |
59 | > 以下操作都是在“终端”窗口中完成。
60 |
61 | #### 1、安装指定版本的 Node.js
62 |
63 | 我们可以通过以下 nvm 命令在线安装指定版本的 Node.js。
64 |
65 | ```
66 | nvm install [nodeversion]
67 | ```
68 |
69 | 例如,需要安装 v6.9.1 版本的 Node.js,那可以通过以下命令完成。
70 |
71 | ```
72 | nvm install v6.9.1
73 | ```
74 |
75 | #### 2、指定当前使用的 Node.js 版本
76 |
77 | 通过 nvm 可以同时安装多个版本的 Node.js,我们可以指定某个版本的使用。
78 |
79 | ```
80 | nvm use [nodeversion]
81 | ```
82 |
83 | 例如,需要使用 v6.9.1 版本的 Node.js,那可以通过以下命令完成。
84 |
85 | ```
86 | nvm use v6.9.1
87 | ```
88 |
89 | #### 3、查看当前安装的 Node.js 版本列表
90 |
91 | 由于通过 nvm 可以安装多个 Node.js,版本多了不好管理。我们还可以随时查看当前安装了哪些 Node.js 的版本。
92 |
93 | ```
94 | nvm ls
95 | ```
96 |
97 | #### 4、nvm 的其他命令
98 |
99 | nvm 还提供一些命令,方便我们平时管理 Node.js 的版本。
100 |
101 | - `nvm uninstall [nodeversion]`: 表示删除指定版本的 Node.js,用法类似于 install 命令。
102 | - `nvm current`: 表示显示当前使用的 Node.js 版本。
103 | - `nvm reinstall-packages [npmversion]`: 表示在当前的 Node.js 版本下,安装指定版本的 npm 包管理器。
104 |
105 | ### 三、安装多个版本 Node.js 的意义
106 |
107 | 自从 Node.js 基金会成立,Node.js 就有一个发布计划,就是同时存在两个发布版本:稳定版和试验版。
108 |
109 | 在 Node.js 中,带有长期支持(LTS)的稳定版是以偶数开始(4,6,8...),而试验版是从奇数开始(5, 7...)。我们推荐在生产环境中用 LTS 版本,而用试验版尝试新东西。
110 |
111 | ### 四、nvm 软件切换镜像源
112 |
113 | 由于国内在一些情况下有些特殊。Node.js 官方镜像源在国外,经常通过 nvm 安装 Node.js 时,速度比较慢,或者没有响应。
114 |
115 | 根据这种情况,nvm 允许更改安装的镜像源,我们可以将镜像源切换到国内的淘宝提供的镜像源。
116 |
117 | 根据 nvm 官方提供的帮助文档,我们可以通过以下命令进行切换。
118 |
119 | ```
120 | export NVM_NODEJS_ORG_MIRROR="http://npm.taobao.org/mirrors/node"
121 | ```
122 |
123 | > [http://npm.taobao.org/mirrors/node](http://npm.taobao.org/mirrors/node) 是[淘宝 NPM 镜像](https://npm.taobao.org/)提供的国内 Node.js 的安装镜像源。
124 |
125 | **这里我们需要注意的是,**这种方式,在每次重启“终端”会失效。也就是说,每次打开“终端”都需要执行上述命令。
126 |
127 | 如果并不想每次打开“终端”,都需要重新设置 `NVM_NODEJS_ORG_MIRROR` 环境变量。
128 |
129 | - 如果“终端”使用的是 `bash Shell` 的话(一般是 Mac 系统终端默认)向 `~/.bash_profile` 文件(*如果没有,会自动创建*)增加以下内容:
130 |
131 | ```
132 | # nvm
133 | export NVM_NODEJS_ORG_MIRROR="http://npm.taobao.org/mirrors/node"
134 | source ~/.nvm/nvm.sh
135 | ```
136 |
137 | - 如果“终端”使用的是 `zsh Shell` 的话(一般是 Mac 开发人员使用)
138 | 向 `~/.zshrc` 文件(*如果没有,会自动创建*)增加以下内容:
139 |
140 | ```
141 | # nvm
142 | export NVM_NODEJS_ORG_MIRROR="http://npm.taobao.org/mirrors/node"
143 | source ~/.nvm/nvm.sh
144 | ```
145 |
146 | ## Windows 系统的 nvm-windows 软件
147 |
148 | Windows 系统的 nvm-windows 软件的功能与 MacOS 系统的 nvm 软件是一样的。我们可以把 nvm-windows 软件当作是 nvm 软件的 windows 版本。
149 |
150 | > nvm-windows 软件的相关介绍,可以访问[ nvm-windows 的 github 主页](https://github.com/coreybutler/nvm-windows)。
151 |
152 | ### 一、安装 nvm-windows 软件
153 |
154 | 安装 nvm-windows 软件相对比较简单。我们只需访问 [https://github.com/coreybutler/nvm-windows/releases](https://github.com/coreybutler/nvm-windows/releases),下载最新版本的安装文件即可。
155 |
156 | > **这里需要注意的是,**`nvm-setup.zip` 压缩文件是 nvm-windows 软件的安装压缩包。下载并解压即可安装。
157 |
158 | ### 二、nvm-windows 软件切换镜像源
159 |
160 | 我们可以找到 nvm-windows 软件的安装目录中的 `settings.txt` 文件,增加以下内容:
161 |
162 | ```
163 | node_mirror=http://npm.taobao.org/mirrors/node/
164 | ```
165 |
166 | > 添加成功之后,需要重新打开命令行窗口。
167 |
--------------------------------------------------------------------------------
/02-install-nodejs/command-line.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstack-kingj/easy-node/42830f0d2280878409d8a54f0e311ea5a451bd68/02-install-nodejs/command-line.png
--------------------------------------------------------------------------------
/02-install-nodejs/macos-nodejs-installation-step-five.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstack-kingj/easy-node/42830f0d2280878409d8a54f0e311ea5a451bd68/02-install-nodejs/macos-nodejs-installation-step-five.png
--------------------------------------------------------------------------------
/02-install-nodejs/macos-nodejs-installation-step-four.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstack-kingj/easy-node/42830f0d2280878409d8a54f0e311ea5a451bd68/02-install-nodejs/macos-nodejs-installation-step-four.png
--------------------------------------------------------------------------------
/02-install-nodejs/macos-nodejs-installation-step-one.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstack-kingj/easy-node/42830f0d2280878409d8a54f0e311ea5a451bd68/02-install-nodejs/macos-nodejs-installation-step-one.png
--------------------------------------------------------------------------------
/02-install-nodejs/macos-nodejs-installation-step-seven.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstack-kingj/easy-node/42830f0d2280878409d8a54f0e311ea5a451bd68/02-install-nodejs/macos-nodejs-installation-step-seven.png
--------------------------------------------------------------------------------
/02-install-nodejs/macos-nodejs-installation-step-six.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstack-kingj/easy-node/42830f0d2280878409d8a54f0e311ea5a451bd68/02-install-nodejs/macos-nodejs-installation-step-six.png
--------------------------------------------------------------------------------
/02-install-nodejs/macos-nodejs-installation-step-three.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstack-kingj/easy-node/42830f0d2280878409d8a54f0e311ea5a451bd68/02-install-nodejs/macos-nodejs-installation-step-three.png
--------------------------------------------------------------------------------
/02-install-nodejs/macos-nodejs-installation-step-two.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstack-kingj/easy-node/42830f0d2280878409d8a54f0e311ea5a451bd68/02-install-nodejs/macos-nodejs-installation-step-two.png
--------------------------------------------------------------------------------
/02-install-nodejs/macos-system-environment-installation-nodejs.md:
--------------------------------------------------------------------------------
1 | ## 第一步:访问 Node.js 的官方网站
2 |
3 | 访问 Node.js 官方网站地址:[https://nodejs.org/en/](https://nodejs.org/en/),如下图:
4 |
5 | 
6 |
7 | Node.js 官方提供两个版本:一个是长期支持版本,一个是最新版本。**这里建议下载长期支持版本,因为这个版本更稳定。** 如下图:
8 |
9 | 
10 |
11 | 选择长期支持版本(点击上面的按钮),下载 Mac 系统的安装文件。如下图:
12 |
13 | 
14 |
15 | ## 第二步:安装 Node.js 的环境
16 |
17 | 1、双击 Node.js 的安装文件,进入 Node.js 的安装界面。如下图:
18 |
19 | 
20 |
21 | 2、点击右下角的【继续】按钮,继续安装 Node.js 环境。如下图:
22 |
23 | 
24 |
25 | 如上图所示,显示的是 Node.js 官方的“软件许可协议”。
26 |
27 | 3、一般情况下,点击【继续】按钮,表示同意并继续安装 Node.js 环境。如下图:
28 |
29 | 
30 |
31 | 4、点击【同意】按钮,表示同意 Node.js 软件许可协议的内容。
32 |
33 | 
34 |
35 | 如上图所示,可以选择安装的路径(默认即可)。
36 |
37 | 5、点击【安装】按钮,表示开始安装 Node.js 的环境。如下图:
38 |
39 | 
40 |
41 | > 如上图所示,Mac 系统在安装软件时,需要提供当前系统的用户名及密码,才能正确安装软件。
42 |
43 | 6、这里需要输入你的用户名和密码,点击【安装软件】按钮,开始真正地安装 Node.js 的环境。如下图:
44 |
45 | 
46 |
47 | 如上图所示,安装程序会自动开始安装 Node.js 的环境,直到安装完毕。如下图:
48 |
49 | 
50 |
51 | 如上图所示,提供“安装成功”信息后,点击【关闭】按钮,结束 Node.js 环境的安装步骤。
52 |
53 | ## 第三步:验证 Node.js 是否安装成功
54 |
55 | 1、运行 Mac 系统下的 “终端” 程序,如下图:
56 |
57 | 
58 |
59 | 2、在 “终端” 程序中输入如下命令,验证 Node.js 的环境是否安装成功。
60 |
61 | ```
62 | node -v
63 | ```
64 |
65 | 如果在 “终端” 程序中出现如下图的提示内容,则表示 Node.js 的环境安装成功。如下图:
66 |
67 | 
68 |
69 | > **需要说明的是:** `node -v` 命令表示查看当前 Node.js 环境的版本。
70 |
71 | ## 第四步:验证 npm 包管理器是否可用
72 |
73 | 1、运行 Mac 系统下的 “终端” 程序,如下图:
74 |
75 | 
76 |
77 | 2、在 “终端” 程序中输入如下命令,验证 npm 包管理器是否可用。
78 |
79 | ```
80 | npm -v
81 | ```
82 |
83 | 如果在 “终端” 程序中出现如下图的提示内容,则表示 npm 包管理器可用。如下图:
84 |
85 | 
86 |
87 | > **需要说明的是:** `npm -v` 命令表示查看当前 npm 包管理器的版本。
88 |
89 | ### [返回](README.md)
--------------------------------------------------------------------------------
/02-install-nodejs/nodejs-installation-file-macos.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstack-kingj/easy-node/42830f0d2280878409d8a54f0e311ea5a451bd68/02-install-nodejs/nodejs-installation-file-macos.png
--------------------------------------------------------------------------------
/02-install-nodejs/nodejs-installation-file.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstack-kingj/easy-node/42830f0d2280878409d8a54f0e311ea5a451bd68/02-install-nodejs/nodejs-installation-file.png
--------------------------------------------------------------------------------
/02-install-nodejs/nodejs-installation-step-eight.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstack-kingj/easy-node/42830f0d2280878409d8a54f0e311ea5a451bd68/02-install-nodejs/nodejs-installation-step-eight.png
--------------------------------------------------------------------------------
/02-install-nodejs/nodejs-installation-step-five.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstack-kingj/easy-node/42830f0d2280878409d8a54f0e311ea5a451bd68/02-install-nodejs/nodejs-installation-step-five.png
--------------------------------------------------------------------------------
/02-install-nodejs/nodejs-installation-step-four.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstack-kingj/easy-node/42830f0d2280878409d8a54f0e311ea5a451bd68/02-install-nodejs/nodejs-installation-step-four.png
--------------------------------------------------------------------------------
/02-install-nodejs/nodejs-installation-step-one.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstack-kingj/easy-node/42830f0d2280878409d8a54f0e311ea5a451bd68/02-install-nodejs/nodejs-installation-step-one.png
--------------------------------------------------------------------------------
/02-install-nodejs/nodejs-installation-step-seven.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstack-kingj/easy-node/42830f0d2280878409d8a54f0e311ea5a451bd68/02-install-nodejs/nodejs-installation-step-seven.png
--------------------------------------------------------------------------------
/02-install-nodejs/nodejs-installation-step-six.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstack-kingj/easy-node/42830f0d2280878409d8a54f0e311ea5a451bd68/02-install-nodejs/nodejs-installation-step-six.png
--------------------------------------------------------------------------------
/02-install-nodejs/nodejs-installation-step-three.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstack-kingj/easy-node/42830f0d2280878409d8a54f0e311ea5a451bd68/02-install-nodejs/nodejs-installation-step-three.png
--------------------------------------------------------------------------------
/02-install-nodejs/nodejs-installation-step-two.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstack-kingj/easy-node/42830f0d2280878409d8a54f0e311ea5a451bd68/02-install-nodejs/nodejs-installation-step-two.png
--------------------------------------------------------------------------------
/02-install-nodejs/nodejs-official-website-macos.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstack-kingj/easy-node/42830f0d2280878409d8a54f0e311ea5a451bd68/02-install-nodejs/nodejs-official-website-macos.png
--------------------------------------------------------------------------------
/02-install-nodejs/nodejs-official-website.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstack-kingj/easy-node/42830f0d2280878409d8a54f0e311ea5a451bd68/02-install-nodejs/nodejs-official-website.png
--------------------------------------------------------------------------------
/02-install-nodejs/nodejs-v-command.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstack-kingj/easy-node/42830f0d2280878409d8a54f0e311ea5a451bd68/02-install-nodejs/nodejs-v-command.png
--------------------------------------------------------------------------------
/02-install-nodejs/nodejs-v-terminal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstack-kingj/easy-node/42830f0d2280878409d8a54f0e311ea5a451bd68/02-install-nodejs/nodejs-v-terminal.png
--------------------------------------------------------------------------------
/02-install-nodejs/nodejs-version.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstack-kingj/easy-node/42830f0d2280878409d8a54f0e311ea5a451bd68/02-install-nodejs/nodejs-version.png
--------------------------------------------------------------------------------
/02-install-nodejs/npm-v-command.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstack-kingj/easy-node/42830f0d2280878409d8a54f0e311ea5a451bd68/02-install-nodejs/npm-v-command.png
--------------------------------------------------------------------------------
/02-install-nodejs/npm-v-terminal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstack-kingj/easy-node/42830f0d2280878409d8a54f0e311ea5a451bd68/02-install-nodejs/npm-v-terminal.png
--------------------------------------------------------------------------------
/02-install-nodejs/terminal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstack-kingj/easy-node/42830f0d2280878409d8a54f0e311ea5a451bd68/02-install-nodejs/terminal.png
--------------------------------------------------------------------------------
/02-install-nodejs/windows-system-environment-installation-nodejs.md:
--------------------------------------------------------------------------------
1 | # Windows 系统环境安装 Node.js
2 |
3 | ## 第一步:访问 Node.js 的官方网站
4 |
5 | 访问 Node.js 官方网站地址:[https://nodejs.org/en/](https://nodejs.org/en/),如下图:
6 |
7 | 
8 |
9 | Node.js 官方提供两个版本:一个是长期支持版本,一个是最新版本。**这里建议下载长期支持版本,因为这个版本更稳定。**如下图:
10 |
11 | 
12 |
13 | 选择长期支持版本(点击上面的按钮),下载 Windows 系统的安装文件。如下图:
14 |
15 | 
16 |
17 | ## 第二步:安装 Node.js 的环境
18 |
19 | 1、双击 Node.js 的安装文件,进入 Node.js 的安装界面。如下图:
20 |
21 | 
22 |
23 | 2、点击右下角的【Next】按钮,继续安装 Node.js 环境。如下图:
24 |
25 | 
26 |
27 | 如上图所示,显示的是 Node.js 官方的“软件许可协议”。
28 |
29 | 3、勾选选项 “I accept the terms in the License Agreement”,表示同意 Node.js 软件许可协议的内容。如下图:
30 |
31 | 
32 |
33 | 4、点击【Next】按钮,继续安装 Node.js 环境。如下图:
34 |
35 | 
36 |
37 | 如上图所示,自定义 Node.js 环境的安装路径,一般建议使用默认路径。
38 |
39 | > 如果自定义安装路径,**需要注意的是:** 路径中不能包含中文或空格,可能引起乱码问题。
40 |
41 | 5、点击【Next】按钮,继续安装 Node.js 环境。如下图:
42 |
43 | 
44 |
45 | 如上图所示,自定义安装 Node.js 环境的组件。一般建议安装所有组件,即默认安装。
46 |
47 | 6、点击【Next】按钮,继续安装 Node.js 环境。如下图:
48 |
49 | 
50 |
51 | 如上图所示,询问是否确认安装 Node.js 环境。(此步骤主要是确认之前的设置)
52 |
53 | 7、点击【Install】按钮,开始自动安装 Node.js 环境。如下图:
54 |
55 | 
56 |
57 | 8、等待 Node.js 环境自动安装完毕,如下图:
58 |
59 | 
60 |
61 | 如上图所示,点击【Finish】按钮,结束 Node.js 环境的安装过程。
62 |
63 | ## 第三步:验证 Node.js 是否安装成功
64 |
65 | 1、运行 Windows 系统下的 “命令行” 程序,如下图:
66 |
67 | 
68 |
69 | 2、在 “命令行” 程序中输入如下命令,验证 Node.js 的环境是否安装成功。
70 |
71 | ```
72 | node -v
73 | ```
74 |
75 | 如果在 “命令行” 程序中出现如下图的提示内容,则表示 Node.js 的环境安装成功。如下图:
76 |
77 | 
78 |
79 | > **需要说明的是:** `node -v` 命令表示查看当前 Node.js 环境的版本。
80 |
81 | ## 第四步:验证 npm 包管理器是否可用
82 |
83 | 1、运行 Windows 系统下的 “命令行” 程序,如下图:
84 |
85 | 
86 |
87 | 2、在 “命令行” 程序中输入如下命令,验证 npm 包管理器是否可用。
88 |
89 | ```
90 | npm -v
91 | ```
92 |
93 | 如果在 “命令行” 程序中出现如下图的提示内容,则表示 npm 包管理器可用。如下图:
94 |
95 | 
96 |
97 | > **需要说明的是:** `npm -v` 命令表示查看当前 npm 包管理器的版本。
98 |
99 | ### [返回](README.md)
--------------------------------------------------------------------------------
/03-first-sample.md:
--------------------------------------------------------------------------------
1 | **在本节课中,我们将运行 Node.js 官方提供的示例代码,并通过这段示例代码学习相关技术知识。**
2 |
3 | ## 官方示例
4 |
5 | Node.js 官方提供的帮助文档中,首先,提供了一个很好的入门案例。我们通过这个示例,可以快速的了解 Node.js 的基本作用。
6 |
7 | ### 1. 访问 Node.js 的官方文档
8 |
9 | 首先,打开浏览器,通过以下地址可以访问 Node.js 官方帮助文档。
10 |
11 | ```
12 | https://nodejs.org/en/docs/
13 | ```
14 |
15 | 然后,找到长期支持的版本的帮助文档。或者,你可以通过以下链接直接打开。
16 |
17 | ```
18 | https://nodejs.org/dist/latest-v6.x/docs/api/synopsis.html
19 | ```
20 |
21 | ### 2. 创建 JavaScript 示例文件
22 |
23 | 打开对应的帮助文档页面之后,我们可以看到 Node.js 官方提供的示例代码了。
24 |
25 | 
26 | 
27 | 我们需要在本地创建一个 JavaScript 文件,并将如上图所示的代码拷贝到这个文件中。
28 |
29 | ```javascript
30 | const http = require('http');
31 |
32 | const hostname = '127.0.0.1';
33 | const port = 3000;
34 |
35 | const server = http.createServer((req, res) => {
36 | res.statusCode = 200;
37 | res.setHeader('Content-Type', 'text/plain');
38 | res.end('Hello World\n');
39 | });
40 |
41 | server.listen(port, hostname, () => {
42 | console.log(`Server running at http://${hostname}:${port}/`);
43 | });
44 | ```
45 |
46 | ### 3. 运行官方示例
47 |
48 | 保存好官方示例代码之后,我们需要打开“终端”或者“命令行窗口”,并且通过 `Node` 命令来运行这个 JavaScript 文件。
49 |
50 | ```
51 | node example.js
52 | ```
53 |
54 | **值得注意的是:** “终端”或者“命令行窗口”中的目录,必须与 `example.js` 文件是同一目录。
55 | 命令执行成功之后,我们可以看到如下图所示的效果。
56 |
57 | 
58 | 
59 | 通过浏览器,输入以下链接访问这个示例。
60 |
61 | ```
62 | http://127.0.0.1:3000
63 | ```
64 |
65 | 如果访问成功的话,我们可以看到如下图所示的效果。
66 |
67 | 
68 | 
69 | ### 4. 示例代码说明
70 |
71 | ```javascript
72 | // 引用 HTTP 模块
73 | const http = require('http');
74 | // 定义绑定的 IP 地址和端口号
75 | const hostname = '127.0.0.1';
76 | const port = 3000;
77 | // 通过 HTTP 模块创建服务器
78 | const server = http.createServer((req, res) => {
79 | // 当接收客户端请求时,触发该回调函数
80 |
81 | // 设置响应状态码为 200
82 | res.statusCode = 200;
83 | // 设置响应头 "Content-Type"
84 | res.setHeader('Content-Type', 'text/plain');
85 | // 设置响应数据
86 | res.end('Hello World\n');
87 | });
88 | // 设置服务器绑定的 IP 地址和端口号
89 | server.listen(port, hostname, () => {
90 | // 当服务器端启动时,触发该回调函数
91 |
92 | console.log(`Server running at http://${hostname}:${port}/`);
93 | });
94 | ```
95 |
96 | ## 相关技术知识
97 |
98 | ### 1. const 关键字
99 |
100 | 在官方示例中,我们可以发现大量地使用了 `const` 关键字。`const` 关键字是 ECMAScript 2015 规范中的新内容,是用来定义常量的。
101 |
102 | #### 1) 什么是常量
103 |
104 | 所谓常量,就是指一旦被声明,并且初始化值后,便不能再被修改。也就是说,是一个只读的变量。
105 | 在 ECMAScript 2015 中,提供了 `const` 关键字来声明常量。
106 |
107 | #### 2) 声明常量时必须赋值
108 |
109 | 使用 `const` 关键字声明常量时,必须进行初始化(赋值操作)。否则,会报错。
110 |
111 | ```javascript
112 | const CONSTANT;
113 | ```
114 |
115 | 上述示例代码,运行时会报如下错误:
116 |
117 | ```
118 | SyntaxError: Missing initializer in const declaration
119 | ```
120 |
121 | #### 3) 常量的值不能被修改
122 |
123 | 常量的值是只读的,也就是说,值是不能被修改的。一旦修改常量的值,也会报错。
124 |
125 | ```javascript
126 | const PI = 3.1415;
127 | PI = 3;
128 | ```
129 |
130 | 上述示例代码,运行时会报如下错误:
131 |
132 | ```
133 | TypeError: Assignment to constant variable.
134 | ```
135 |
136 | #### 4) const 关键字的作用域
137 |
138 | `const` 关键字声明的常量,除了全局作用域和函数作用域之外,还存在块级作用域。
139 |
140 | ```javascript
141 | if(true){
142 | const CONSTANT = 300;
143 | }
144 | console.log(CONSTANT);
145 | ```
146 |
147 | 上述示例代码,运行时会报如下错误:
148 |
149 | ```
150 | ReferenceError: CONSTANT is not defined
151 | ```
152 |
153 | #### 5) 常量不存在声明提前
154 |
155 | 在 ECMAScript 中定义的变量,是允许声明提前的。
156 |
157 | ```javascript
158 | console.log(v);
159 | var v = 100;
160 | ```
161 |
162 | 上述示例代码,运行的结果为 `undefined`,说明变量 `v` 存在但没值。
163 |
164 | 但 ECMAScript 2015 中声明的常量并不存在声明提前。
165 |
166 | ```javascript
167 | console.log(CONSTANT);
168 | const CONSTANT = 100;
169 | ```
170 |
171 | 上述示例代码,运行时会报如下错误:
172 |
173 | ```
174 | ReferenceError: CONSTANT is not defined
175 | ```
176 |
177 | #### 6) 常量不能重复声明
178 |
179 | 在 ECMAScript 中定义的变量,是允许被重复声明的。重复声明的变量值会覆盖前一次声明的变量值。
180 |
181 | ```javascript
182 | var v = 100;
183 | console.log(v);
184 | var v = 200;
185 | console.log(v);
186 | ```
187 |
188 | 上述示例代码,运行时第一次输出 `100`,第二次输出 `200`。这说明第二次声明的变量 `c` 的值覆盖了第一次声明的变量 `c` 的值。
189 |
190 | 但 ECMAScript 2015 中声明的常量是不允许被重复声明的。
191 |
192 | ```javascript
193 | const C = 100;
194 | console.log(C);
195 | const C = 200;
196 | console.log(C);
197 | ```
198 |
199 | 上述示例代码,运行时会报如下错误:
200 |
201 | ```
202 | SyntaxError: Identifier 'C' has already been declared
203 | ```
204 |
205 | ### 2. 箭头函数
206 |
207 | 在官方示例中,我们可以看到如下形式的函数:
208 |
209 | ```javascript
210 | http.createServer((req, res) => {
211 | res.statusCode = 200;
212 | res.setHeader('Content-Type', 'text/plain');
213 | res.end('Hello World\n');
214 | });
215 | ```
216 |
217 | 上述示例中的函数形式,看起来很怪异,我们将其进行改写:
218 |
219 | ```javascript
220 | const server = http.createServer(function(req, res){
221 | res.statusCode = 200;
222 | res.setHeader('Content-Type', 'text/plain');
223 | res.end('Hello World\n');
224 | });
225 | ```
226 |
227 | 实际上,官方示例中使用的是 ECMAScript 2015 中新增的箭头函数。
228 |
229 | #### 1) 定义无参的箭头函数
230 |
231 | 在 ECMAScript 5 中,我们定义一个无参函数是这样的:
232 |
233 | ```javascript
234 | var fn = function(){
235 | return 'this is function';
236 | }
237 | ```
238 |
239 | 而在 ECMAScript 2015 中的箭头函数定义是这样的:
240 |
241 | ```javascript
242 | var fn = () => 'this is function';
243 | ```
244 |
245 | 上述两个函数的定义是等价的。
246 |
247 | #### 2) 定义带参的箭头函数
248 |
249 | 如果想要定义带有参数的箭头函数,可以如下方式:
250 |
251 | ```javascript
252 | var fn = v => v;
253 | ```
254 |
255 | 上述代码等同于如下:
256 |
257 | ```javascript
258 | var fn = function(v){
259 | return v;
260 | }
261 | ```
262 |
263 | 如果定义带有多个参数的箭头函数,可以将参数通过圆括号进行包裹。
264 |
265 | ```javascript
266 | var sum = (num1, num2) => num1 + num2;
267 | ```
268 |
269 | 上述代码等同于如下:
270 |
271 | ```javascript
272 | var sum = function(num1, num2) {
273 | return num1 + num2;
274 | }
275 | ```
276 |
277 | #### 3) 箭头函数体包含多条语句
278 |
279 | 上述示例代码中,我们只在箭头函数中定义了一条语句。那想要定义多条语句的话,可以将所有函数体内的语句通过大括号进行包裹。
280 |
281 | ```javascript
282 | var sum = (num1, num2) => {
283 | if(num1 < num2){
284 | return num1;
285 | }else{
286 | return num2;
287 | }
288 | }
289 | ```
290 |
291 | 上述代码等同于如下:
292 |
293 | ```javascript
294 | var sum = function(num1, num2) {
295 | if(num1 < num2){
296 | return num1;
297 | }else{
298 | return num2;
299 | }
300 | }
301 | ```
302 |
303 | 大括号会被解析为代码块。如果箭头函数想要返回的是复杂数据(例如对象),需要使用圆括号进行包裹。
304 |
305 | ```javascript
306 | var me = () => ({ name: "longestory" });
307 | ```
308 |
309 | 上述代码等同于如下:
310 |
311 | ```javascript
312 | var me = function() {
313 | return { name: "longestory" };
314 | }
315 | ```
316 |
317 | #### 4) 箭头函数的作用
318 |
319 | 通过上述内容,我们已经基本掌握了箭头函数的用法。那箭头函数究竟会有什么作用呢?我们再回过头来看看官方示例的代码。
320 |
321 | ```javascript
322 | // ECMAScript 5 中的写法
323 | http.createServer(function(req, res){
324 | res.statusCode = 200;
325 | res.setHeader('Content-Type', 'text/plain');
326 | res.end('Hello World\n');
327 | });
328 | ```
329 |
330 | 上述示例代码中,我们可以知道,通过 `http` 对象调用了 `createServer` 方法的同时向该方法传递了一个回调函数。
331 |
332 | ```javascript
333 | // ECMAScript 2015 中的写法
334 | http.createServer((req, res) => {
335 | res.statusCode = 200;
336 | res.setHeader('Content-Type', 'text/plain');
337 | res.end('Hello World\n');
338 | });
339 | ```
340 |
341 | 所以,箭头函数的主要用法之一,就是用来简化回调函数的使用。
342 |
343 | ### 3. 模板字符串
344 |
345 | 在官方示例中,我们还看到一行比较特殊的代码。
346 |
347 | ```javascript
348 | console.log(`Server running at http://${hostname}:${port}/`);
349 | ```
350 |
351 | 上述示例代码如果被改写成这样,相信你会更熟悉。
352 |
353 | ```javascript
354 | console.log('Server running at http://'+hostname+':'+port+'/');
355 | ```
356 |
357 | 实际上,在上述代码中,其实是使用了 JavaScript 的字符串拼串。而官方示例中,则使用 ECMAScript 2015 中的**模板字符串**。
358 |
359 | #### 1) 模板字符串的基本使用
360 |
361 | 模板字符串(template string)是增强版的字符串,用反引号(`)标识。
362 |
363 | ```javascript
364 | console.log(`this is a string.`);
365 | ```
366 |
367 | 上述示例代码的输出结果如下:
368 |
369 | ```
370 | this is a string.
371 | ```
372 |
373 | 你会发现上述示例代码的输出结果与 ECMAScript 5 中的普通字符串并没有任何区别。
374 |
375 | ```javascript
376 | console.log('this is a string.');
377 | ```
378 |
379 | 但,如果我们想要输出的字符串很复杂,或者是多行的。那 ECMAScript 5 中的写法应该是这样的:
380 |
381 | ```javascript
382 | $('#list').html(
383 | '
'+
384 | '- first
'+
385 | '- second
'+
386 | '
'
387 | );
388 | ```
389 |
390 | 而使用 ECMAScript 2015 中的模板字符串,我们可以写成这样:
391 |
392 | ```javascript
393 | $('#list').html(`
394 |
395 | - first
396 | - second
397 |
398 | `);
399 | ```
400 |
401 | #### 2) 模板字符串中使用变量
402 |
403 | 如果输出的是一些文本加上变量的内容的话,在 ECMAScript 5 中的写法是这样的:
404 |
405 | ```javascript
406 | const hostname = '127.0.0.1';
407 | const port = 3000;
408 | console.log('Server running at http://'+hostname+':'+port+'/');
409 | ```
410 |
411 | 也就是说,我们在实际开发中,需要大量的字符串拼写工作。这样做的问题在于:
412 |
413 | * 工作量巨大
414 | * 比较容易出错
415 |
416 | 而 ECMAScript 2015 中的模板字符串,则允许嵌入变量。只需要将需要嵌入的变量通过 `${}` 进行包裹即可。
417 |
418 | ```javascript
419 | const hostname = '127.0.0.1';
420 | const port = 3000;
421 | console.log(`Server running at http://${hostname}:${port}/`);
422 | ```
423 |
424 | 在模板字符串中,甚至可以嵌入函数的调用。
425 |
426 | ```javascript
427 | function fn(){
428 | return 'Hello';
429 | }
430 | console.log(`${fn()} World`);
431 | ```
432 |
433 | 上述示例代码运行的结果如下:
434 |
435 | ```javascript
436 | Hello World
437 | ```
438 |
439 | #### 3) 模板字符串的注意事项
440 |
441 | 如果模板字符串中嵌入的变量没有声明,则会报错。
442 |
443 | ```javascript
444 | console.log(`Server running at http://${hostname}/`);
445 | ```
446 |
447 | 上述示例代码,运行后会报如下错误:
448 |
449 | ```
450 | ReferenceError: hostname is not defined
451 | ```
--------------------------------------------------------------------------------
/03-windows-system-environment-installation-nodejs/README.md:
--------------------------------------------------------------------------------
1 | # Windows 系统环境安装 Node.js
2 |
3 | ## 第一步:访问 Node.js 的官方网站
4 |
5 | 访问 Node.js 官方网站地址:[https://nodejs.org/en/](https://nodejs.org/en/),如下图:
6 |
7 | 
8 |
9 | Node.js 官方提供两个版本:一个是长期支持版本,一个是最新版本。**这里建议下载长期支持版本,因为这个版本更稳定。**如下图:
10 |
11 | 
12 |
13 | 选择长期支持版本(点击上面的按钮),下载 Windows 系统的安装文件。如下图:
14 |
15 | 
16 |
17 | ## 第二步:安装 Node.js 的环境
18 |
19 | 1、双击 Node.js 的安装文件,进入 Node.js 的安装界面。如下图:
20 |
21 | 
22 |
23 | 2、点击右下角的【Next】按钮,继续安装 Node.js 环境。如下图:
24 |
25 | 
26 |
27 | 如上图所示,显示的是 Node.js 官方的“软件许可协议”。
28 |
29 | 3、勾选选项 “I accept the terms in the License Agreement”,表示同意 Node.js 软件许可协议的内容。如下图:
30 |
31 | 
32 |
33 | 4、点击【Next】按钮,继续安装 Node.js 环境。如下图:
34 |
35 | 
36 |
37 | 如上图所示,自定义 Node.js 环境的安装路径,一般建议使用默认路径。
38 |
39 | > 如果自定义安装路径,**需要注意的是:** 路径中不能包含中文或空格,可能引起乱码问题。
40 |
41 | 5、点击【Next】按钮,继续安装 Node.js 环境。如下图:
42 |
43 | 
44 |
45 | 如上图所示,自定义安装 Node.js 环境的组件。一般建议安装所有组件,即默认安装。
46 |
47 | 6、点击【Next】按钮,继续安装 Node.js 环境。如下图:
48 |
49 | 
50 |
51 | 如上图所示,询问是否确认安装 Node.js 环境。(此步骤主要是确认之前的设置)
52 |
53 | 7、点击【Install】按钮,开始自动安装 Node.js 环境。如下图:
54 |
55 | 
56 |
57 | 8、等待 Node.js 环境自动安装完毕,如下图:
58 |
59 | 
60 |
61 | 如上图所示,点击【Finish】按钮,结束 Node.js 环境的安装过程。
62 |
63 | ## 第三步:验证 Node.js 是否安装成功
64 |
65 | 1、运行 Windows 系统下的 “命令行” 程序,如下图:
66 |
67 | 
68 |
69 | 2、在 “命令行” 程序中输入如下命令,验证 Node.js 的环境是否安装成功。
70 |
71 | ```
72 | node -v
73 | ```
74 |
75 | 如果在 “命令行” 程序中出现如下图的提示内容,则表示 Node.js 的环境安装成功。如下图:
76 |
77 | 
78 |
79 | > **需要说明的是:** `node -v` 命令表示查看当前 Node.js 环境的版本。
80 |
81 | ## 第四步:验证 npm 包管理器是否可用
82 |
83 | 1、运行 Windows 系统下的 “命令行” 程序,如下图:
84 |
85 | 
86 |
87 | 2、在 “命令行” 程序中输入如下命令,验证 npm 包管理器是否可用。
88 |
89 | ```
90 | npm -v
91 | ```
92 |
93 | 如果在 “命令行” 程序中出现如下图的提示内容,则表示 npm 包管理器可用。如下图:
94 |
95 | 
96 |
97 | > **需要说明的是:** `npm -v` 命令表示查看当前 npm 包管理器的版本。
98 |
99 | ### [返回](README.md)
--------------------------------------------------------------------------------
/03-windows-system-environment-installation-nodejs/command-line.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstack-kingj/easy-node/42830f0d2280878409d8a54f0e311ea5a451bd68/03-windows-system-environment-installation-nodejs/command-line.png
--------------------------------------------------------------------------------
/03-windows-system-environment-installation-nodejs/nodejs-installation-file.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstack-kingj/easy-node/42830f0d2280878409d8a54f0e311ea5a451bd68/03-windows-system-environment-installation-nodejs/nodejs-installation-file.png
--------------------------------------------------------------------------------
/03-windows-system-environment-installation-nodejs/nodejs-installation-step-eight.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstack-kingj/easy-node/42830f0d2280878409d8a54f0e311ea5a451bd68/03-windows-system-environment-installation-nodejs/nodejs-installation-step-eight.png
--------------------------------------------------------------------------------
/03-windows-system-environment-installation-nodejs/nodejs-installation-step-five.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstack-kingj/easy-node/42830f0d2280878409d8a54f0e311ea5a451bd68/03-windows-system-environment-installation-nodejs/nodejs-installation-step-five.png
--------------------------------------------------------------------------------
/03-windows-system-environment-installation-nodejs/nodejs-installation-step-four.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstack-kingj/easy-node/42830f0d2280878409d8a54f0e311ea5a451bd68/03-windows-system-environment-installation-nodejs/nodejs-installation-step-four.png
--------------------------------------------------------------------------------
/03-windows-system-environment-installation-nodejs/nodejs-installation-step-one.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstack-kingj/easy-node/42830f0d2280878409d8a54f0e311ea5a451bd68/03-windows-system-environment-installation-nodejs/nodejs-installation-step-one.png
--------------------------------------------------------------------------------
/03-windows-system-environment-installation-nodejs/nodejs-installation-step-seven.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstack-kingj/easy-node/42830f0d2280878409d8a54f0e311ea5a451bd68/03-windows-system-environment-installation-nodejs/nodejs-installation-step-seven.png
--------------------------------------------------------------------------------
/03-windows-system-environment-installation-nodejs/nodejs-installation-step-six.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstack-kingj/easy-node/42830f0d2280878409d8a54f0e311ea5a451bd68/03-windows-system-environment-installation-nodejs/nodejs-installation-step-six.png
--------------------------------------------------------------------------------
/03-windows-system-environment-installation-nodejs/nodejs-installation-step-three.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstack-kingj/easy-node/42830f0d2280878409d8a54f0e311ea5a451bd68/03-windows-system-environment-installation-nodejs/nodejs-installation-step-three.png
--------------------------------------------------------------------------------
/03-windows-system-environment-installation-nodejs/nodejs-installation-step-two.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstack-kingj/easy-node/42830f0d2280878409d8a54f0e311ea5a451bd68/03-windows-system-environment-installation-nodejs/nodejs-installation-step-two.png
--------------------------------------------------------------------------------
/03-windows-system-environment-installation-nodejs/nodejs-official-website.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstack-kingj/easy-node/42830f0d2280878409d8a54f0e311ea5a451bd68/03-windows-system-environment-installation-nodejs/nodejs-official-website.png
--------------------------------------------------------------------------------
/03-windows-system-environment-installation-nodejs/nodejs-v-command.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstack-kingj/easy-node/42830f0d2280878409d8a54f0e311ea5a451bd68/03-windows-system-environment-installation-nodejs/nodejs-v-command.png
--------------------------------------------------------------------------------
/03-windows-system-environment-installation-nodejs/nodejs-v-terminal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstack-kingj/easy-node/42830f0d2280878409d8a54f0e311ea5a451bd68/03-windows-system-environment-installation-nodejs/nodejs-v-terminal.png
--------------------------------------------------------------------------------
/03-windows-system-environment-installation-nodejs/nodejs-version.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstack-kingj/easy-node/42830f0d2280878409d8a54f0e311ea5a451bd68/03-windows-system-environment-installation-nodejs/nodejs-version.png
--------------------------------------------------------------------------------
/03-windows-system-environment-installation-nodejs/npm-v-command.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstack-kingj/easy-node/42830f0d2280878409d8a54f0e311ea5a451bd68/03-windows-system-environment-installation-nodejs/npm-v-command.png
--------------------------------------------------------------------------------
/04-macos-system-environment-installation-nodejs/README.md:
--------------------------------------------------------------------------------
1 | ## 第一步:访问 Node.js 的官方网站
2 |
3 | 访问 Node.js 官方网站地址:[https://nodejs.org/en/](https://nodejs.org/en/),如下图:
4 |
5 | 
6 |
7 | Node.js 官方提供两个版本:一个是长期支持版本,一个是最新版本。**这里建议下载长期支持版本,因为这个版本更稳定。** 如下图:
8 |
9 | 
10 |
11 | 选择长期支持版本(点击上面的按钮),下载 Mac 系统的安装文件。如下图:
12 |
13 | 
14 |
15 | ## 第二步:安装 Node.js 的环境
16 |
17 | 1、双击 Node.js 的安装文件,进入 Node.js 的安装界面。如下图:
18 |
19 | 
20 |
21 | 2、点击右下角的【继续】按钮,继续安装 Node.js 环境。如下图:
22 |
23 | 
24 |
25 | 如上图所示,显示的是 Node.js 官方的“软件许可协议”。
26 |
27 | 3、一般情况下,点击【继续】按钮,表示同意并继续安装 Node.js 环境。如下图:
28 |
29 | 
30 |
31 | 4、点击【同意】按钮,表示同意 Node.js 软件许可协议的内容。
32 |
33 | 
34 |
35 | 如上图所示,可以选择安装的路径(默认即可)。
36 |
37 | 5、点击【安装】按钮,表示开始安装 Node.js 的环境。如下图:
38 |
39 | 
40 |
41 | > 如上图所示,Mac 系统在安装软件时,需要提供当前系统的用户名及密码,才能正确安装软件。
42 |
43 | 6、这里需要输入你的用户名和密码,点击【安装软件】按钮,开始真正地安装 Node.js 的环境。如下图:
44 |
45 | 
46 |
47 | 如上图所示,安装程序会自动开始安装 Node.js 的环境,直到安装完毕。如下图:
48 |
49 | 
50 |
51 | 如上图所示,提供“安装成功”信息后,点击【关闭】按钮,结束 Node.js 环境的安装步骤。
52 |
53 | ## 第三步:验证 Node.js 是否安装成功
54 |
55 | 1、运行 Mac 系统下的 “终端” 程序,如下图:
56 |
57 | 
58 |
59 | 2、在 “终端” 程序中输入如下命令,验证 Node.js 的环境是否安装成功。
60 |
61 | ```
62 | node -v
63 | ```
64 |
65 | 如果在 “终端” 程序中出现如下图的提示内容,则表示 Node.js 的环境安装成功。如下图:
66 |
67 | 
68 |
69 | > **需要说明的是:** `node -v` 命令表示查看当前 Node.js 环境的版本。
70 |
71 | ## 第四步:验证 npm 包管理器是否可用
72 |
73 | 1、运行 Mac 系统下的 “终端” 程序,如下图:
74 |
75 | 
76 |
77 | 2、在 “终端” 程序中输入如下命令,验证 npm 包管理器是否可用。
78 |
79 | ```
80 | npm -v
81 | ```
82 |
83 | 如果在 “终端” 程序中出现如下图的提示内容,则表示 npm 包管理器可用。如下图:
84 |
85 | 
86 |
87 | > **需要说明的是:** `npm -v` 命令表示查看当前 npm 包管理器的版本。
88 |
89 | ### [返回](README.md)
--------------------------------------------------------------------------------
/04-macos-system-environment-installation-nodejs/macos-nodejs-installation-step-five.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstack-kingj/easy-node/42830f0d2280878409d8a54f0e311ea5a451bd68/04-macos-system-environment-installation-nodejs/macos-nodejs-installation-step-five.png
--------------------------------------------------------------------------------
/04-macos-system-environment-installation-nodejs/macos-nodejs-installation-step-four.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstack-kingj/easy-node/42830f0d2280878409d8a54f0e311ea5a451bd68/04-macos-system-environment-installation-nodejs/macos-nodejs-installation-step-four.png
--------------------------------------------------------------------------------
/04-macos-system-environment-installation-nodejs/macos-nodejs-installation-step-one.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstack-kingj/easy-node/42830f0d2280878409d8a54f0e311ea5a451bd68/04-macos-system-environment-installation-nodejs/macos-nodejs-installation-step-one.png
--------------------------------------------------------------------------------
/04-macos-system-environment-installation-nodejs/macos-nodejs-installation-step-seven.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstack-kingj/easy-node/42830f0d2280878409d8a54f0e311ea5a451bd68/04-macos-system-environment-installation-nodejs/macos-nodejs-installation-step-seven.png
--------------------------------------------------------------------------------
/04-macos-system-environment-installation-nodejs/macos-nodejs-installation-step-six.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstack-kingj/easy-node/42830f0d2280878409d8a54f0e311ea5a451bd68/04-macos-system-environment-installation-nodejs/macos-nodejs-installation-step-six.png
--------------------------------------------------------------------------------
/04-macos-system-environment-installation-nodejs/macos-nodejs-installation-step-three.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstack-kingj/easy-node/42830f0d2280878409d8a54f0e311ea5a451bd68/04-macos-system-environment-installation-nodejs/macos-nodejs-installation-step-three.png
--------------------------------------------------------------------------------
/04-macos-system-environment-installation-nodejs/macos-nodejs-installation-step-two.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstack-kingj/easy-node/42830f0d2280878409d8a54f0e311ea5a451bd68/04-macos-system-environment-installation-nodejs/macos-nodejs-installation-step-two.png
--------------------------------------------------------------------------------
/04-macos-system-environment-installation-nodejs/nodejs-installation-file-macos.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstack-kingj/easy-node/42830f0d2280878409d8a54f0e311ea5a451bd68/04-macos-system-environment-installation-nodejs/nodejs-installation-file-macos.png
--------------------------------------------------------------------------------
/04-macos-system-environment-installation-nodejs/nodejs-official-website-macos.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstack-kingj/easy-node/42830f0d2280878409d8a54f0e311ea5a451bd68/04-macos-system-environment-installation-nodejs/nodejs-official-website-macos.png
--------------------------------------------------------------------------------
/04-macos-system-environment-installation-nodejs/nodejs-v-terminal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstack-kingj/easy-node/42830f0d2280878409d8a54f0e311ea5a451bd68/04-macos-system-environment-installation-nodejs/nodejs-v-terminal.png
--------------------------------------------------------------------------------
/04-macos-system-environment-installation-nodejs/nodejs-version.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstack-kingj/easy-node/42830f0d2280878409d8a54f0e311ea5a451bd68/04-macos-system-environment-installation-nodejs/nodejs-version.png
--------------------------------------------------------------------------------
/04-macos-system-environment-installation-nodejs/npm-v-terminal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstack-kingj/easy-node/42830f0d2280878409d8a54f0e311ea5a451bd68/04-macos-system-environment-installation-nodejs/npm-v-terminal.png
--------------------------------------------------------------------------------
/04-macos-system-environment-installation-nodejs/terminal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstack-kingj/easy-node/42830f0d2280878409d8a54f0e311ea5a451bd68/04-macos-system-environment-installation-nodejs/terminal.png
--------------------------------------------------------------------------------
/04-module-system.md:
--------------------------------------------------------------------------------
1 | **在本节课中,我们将学习 Node.js 的模块机制,以及模块化相关标准。**
2 |
3 | 在官方示例中,使用了 Node.js 中的 HTTP 模块来构建一个服务器端。
4 |
5 | ```javascript
6 | const http = require('http');
7 | ```
8 |
9 | 想掌握 HTTP 模块的用法,首先需要先掌握 Node.js 的模块机制是如何的。
10 |
11 | ## 什么是模块化
12 |
13 | 想要真正理解模块化的概念,我们可以通过下面的例子进行学习。
14 |
15 | ### 1. 生活中的模块化
16 |
17 | 其实,生活中有很多模块化的产品就在我们身边,比如电脑。
18 | 
19 | 
20 |
21 | 电脑并不是不可拆卸的一体化产品,它是由各个零件所组成的。
22 | 
23 | 
24 |
25 | 当我们更换电脑中的某个零件时,并不会影响其他零件的工作。
26 |
27 | ### 2. 软件中的模块化
28 |
29 | 在我们开发一款软件时,思路和上述的生活案例(电脑)是一样的。例如,我们要开发一款社交网站。
30 |
31 | 那这个网站中,可能包含以下这些功能:
32 |
33 | - 用户注册功能
34 | - 用户登录功能
35 | - 浏览文章功能
36 | - 编写文章功能
37 | - 用户关注功能
38 | - 发送消息功能
39 | 
40 | 
41 |
42 | 我们也可以将上述这些功能,像电脑的各个零件一样,当作**社交网站**的各个“零件”。而零件其实就是我们所谓的**模块化**。
43 |
44 | ### 3. 模块化的概念及特点
45 |
46 | 所谓模块化,就是指根据功能的不同进行划分,每个功能就是一个模块。最终,一个完整的产品是由各个模块组合而成的。
47 |
48 | 模块化的特点:
49 |
50 | - 独立性。可以针对一个模块单独进行设计、研发,相对工作量和难度变小。
51 | - 复用性。一些通用模块(例如登录或注册)可以被重复使用,而不用每次重新开发。
52 | - 解耦性。模块与模块之间,将相互影响降到最低,使得更换、升级或添加某个模块,不影响其他模块的工作。
53 | - 灵活性。通过选择和组合不同的模块,可以快速构建一个新的产品。
54 |
55 | ## Node.js 的模块系统
56 |
57 | 在了解了什么是模块化概念之后,我们再来看看 Node.js 的模块机制。
58 |
59 | ### 1. 模块系统的分类
60 |
61 | Node.js 在设计之初具有了模块化的机制,通过不同的模块来完成不同的功能。
62 |
63 | 在 Node.js 中,一个模块对应一个 JavaScript 文件,文件路径就是模块名。
64 |
65 | Node.js 的模块系统主要分为以下两种:
66 |
67 | - 核心模块。Node.js 提供了一些允许我们直接使用的模块,例如 HTTP 模块等。
68 | - 文件模块。Node.js 还允许我们自定义一些模块,来满足我们的日常开发需求。
69 |
70 | ### 2. 核心模块
71 |
72 | 所谓核心模块,就是指 Node.js 内置的模块。这些模块是由 C/C++ 进行编写,再封装成 JavaScript。
73 |
74 | 这些内置的模块定义在 Node.js 源代码的 lib 目录中,其结构如下图所示:
75 |
76 | 
77 |
78 | [*目前,我们只需要掌握如何使用核心模块即可。*]
79 |
80 | ### 3. 文件模块
81 |
82 | 所谓文件模块,多指我们在开发一款产品时,自定义模块来满足我们的个性化需求。
83 |
84 | 文件模块还可以被分为以下两种:
85 |
86 | - 第三方模块,就是指一些已经完成的通用的模块。这些模块我们可以直接使用,类似于 Node.js 的核心模块。
87 | - 自定义模块,就是指为了完成自己产品所开发的模块。
88 |
89 | #### 1) 第三方模块
90 |
91 | 第三方模块一般是由 npm 进行管理,我们可以通过访问 [npm官网](https://www.npmjs.com/) 进行浏览,然后通过 npm 命令进行操作。
92 |
93 | *这里我们以 [cli-color](https://www.npmjs.com/package/cli-color) 这个模块(用于控制台的颜色、格式和其他工具)为例,讲解第三方模块的使用。*
94 |
95 | - 首先,我们可以通过以下 npm 命令,将 cli-color 模块安装在自己的工程中。
96 |
97 | ```
98 | npm install cli-color
99 | ```
100 |
101 | 安装完成之后,我们就可以得到如下图所示的内容。
102 |
103 | 
104 |
105 | *npm 命令会将第三方模块自动安装在工程目录下的 `node_modules` 中。*
106 |
107 | - 然后,我们创建一个 JavaScript 文件,用于测试 cli-color 模块的内容。并输入以下代码:
108 |
109 | ```javascript
110 | // 引用 cli-color 模块
111 | var clc = require('cli-color');
112 | // 向控制台输出红色的文本内容
113 | console.log(clc.red('Text in red'));
114 | ```
115 |
116 | - 输入后保存当前 JavaScript 文件,并通过 `node` 命令运行该 JavaScript 文件。效果如下:
117 | 
118 | 
119 |
120 | #### 2) 自定义模块
121 |
122 | Node.js 具有一个简单的模块加载系统,我们可以自定义模块并且加载和使用。在 Node.js 中,文件和模块是一一对应的(每个文件都被视为一个单独的模块)。
123 |
124 | 例如,我们可以创建 `foo.js` 文件加载 `circle.js` 模块。(*确保这两个文件在同一目录中*)
125 | `circle.js` 文件的代码如下:
126 |
127 | ```javascript
128 | const PI = Math.PI;
129 |
130 | exports.area = (r) => PI * r * r;
131 |
132 | exports.circumference = (r) => 2 * PI * r;
133 | ```
134 |
135 | `foo.js` 文件的代码如下:
136 |
137 | ```javascript
138 | const circle = require('./circle.js');
139 | console.log(`The area of a circle of radius 4 is ${circle.area(4)}`);
140 | ```
141 |
142 | 然后,我们通过 `node` 命令来运行 `foo.js` 文件,运行结果如下图所示:
143 | 
144 | 
145 |
146 | ## Node.js 的文件模块
147 |
148 | ### 1. 定义文件模块
149 |
150 | 定义文件模块主要通过 Node.js 提供的 Modules(模块)系统的 exports 对象导出。
151 |
152 | 例如,我们可以创建 `helloworld.js` 文件,输入如下所示的代码:
153 |
154 | ```javascript
155 | exports.callme = function(){
156 | console.log('Hello World');
157 | }
158 | ```
159 |
160 | 上述代码定义了一个名为 `helloworld` 的文件模块,提供了一个 `callme()` 函数为公有方法,可以在其他模块中使用。
161 |
162 | *exports 对象表示当前模块的导出对象,用于导出当前模块的公有方法和属性。*
163 |
164 | ### 2. 调用文件模块
165 |
166 | 当编写好一个文件模块后,可以在其他模块中通过 `require()` 函数使用。例如,我们创建一个 `callhello.js` 文件,输入如下所示的代码:
167 |
168 | ```javascript
169 | var hello = require('./helloworld');
170 | hello.callme();
171 | ```
172 |
173 | 上述代码通过 `require()` 函数引用了 `hellworld.js` 文件模块,模块的前缀 `./` 表示相对调用 `require()` 的路径(*也就是说 `helloworld.js` 与当前模块在同一目录中*)。
174 |
175 | 当使用 `require()` 函数引用一个模块时,Node.js 会尝试加载后缀名为 `.js` 或 `.json` 的文件,如果没有找到会尝试加载后缀名为 `.node` 的文件。
176 |
177 | | 后缀名 | 描述 |
178 | | --- | --- |
179 | | `.js`文件 | 被解析为 JavaScript 文件 |
180 | | `.json`文件 | 被解析为 JSON 文件 |
181 | | `.node`文件 | 被解析为编译过的扩展模块 |
182 |
183 | ### 3. 相对与绝对路径
184 |
185 | 使用 `require()` 函数引用模块时,指定引用模块的路径具有以下几种情况:
186 |
187 | * 模块的前缀如果使用 `/` 或 `C:` 表示绝对路径。
188 | * 模块的前缀如果使用 `./` 表示相对 `require()` 的路径。
189 | * 模块没有 `/` 或 `./` 前缀,则表示加载 Node.js 的核心模块。
190 |
191 | *如果指定的路径不存在,`require()` 将会抛出一个 `MODULE_NOT_FOUND` 的异常。*
192 | 
193 | 
194 |
195 | Node.js 定位文件模块的具体文件时制定的查找策略被称之为模块路径。而这个路径的查找规则可以通过 `module.paths` 进行测试:
196 |
197 | * Mac 系统下可能得到的数组内容如下:
198 |
199 | ```javascript
200 | [ '/Users/king/repl/node_modules',
201 | '/Users/king/node_modules',
202 | '/Users/node_modules',
203 | '/node_modules',
204 | '/Users/king/.node_modules',
205 | '/Users/king/.node_libraries',
206 | '/usr/local/lib/node' ]
207 | ```
208 |
209 | * Window 系统下可能得到的数组内容如下:
210 |
211 | ```javascript
212 | [ 'C:\\Users\\JYL\\repl\\node_modules',
213 | 'C:\\Users\\JYL\\node_modules',
214 | 'C:\\Users\\node_modules',
215 | 'C:\\node_modules',
216 | 'C:\\Users\\JYL\\.node_modules',
217 | 'C:\\Users\\JYL\\.node_libraries',
218 | 'C:\\Software\\lib\\node' ]
219 | ```
220 |
221 | ## CommonJS 规范的模块
222 |
223 | Node.js 借鉴了 CommonJS 的 Modules 规范实现了一套简单易用的模块系统。Node.js 与 CommonJS 之间的关系,如下图所示:
224 | 
225 | 
226 |
227 | CommonJS 的 Modules 规范实现了一套简单易用的模块系统,CommonJS 对模块的定义也十分的简单。主要分为模块定义、模块引用及模块标识三个部分:
228 |
229 | - 模块定义
230 | - 模块引用
231 | - 模块标识
232 |
233 | 这三者之间的关系,如下图所示:
234 | 
235 | 
236 |
237 | ### 1. 模块定义
238 |
239 | 在模块中,上下文提供 `exports` 对象用于导出单个模块的方法或属性,并且该对象也是唯一的导出出口。
240 |
241 | 在模块中,还存在一个 module 对象,代表当前模块,而 `exports` 是 `module` 的属性。
242 | CommonJS 规范建议,一个 JavaScript 文件就是一个模块。
243 |
244 | ### 2. 模块引用
245 |
246 | 在 CommonJS 规范中,存在一个 `require()` 方法,该方法接收引用的模块标识,并返回一个该模块的引用。
247 |
248 | ### 3. 模块标识
249 |
250 | 模块标识就是传递给 `require()` 方法的参数。
251 |
252 | CommonJS 规范构建这套模块的导出和引用机制使得我们不必考虑全局空间的污染问题。
--------------------------------------------------------------------------------
/05-create-server.md:
--------------------------------------------------------------------------------
1 | **在本节课中,我们将学习如何通过 HTTP 模块创建一个服务器,并且如何向客户端响应。**
2 |
3 | 在了解了 Node.js 的模块机制后,我们就可以来看看官方示例中,是如何通过使用 HTTP 模块来创建服务器的。
4 |
5 | ```javascript
6 | const http = require('http');
7 |
8 | const hostname = '127.0.0.1';
9 | const port = 3000;
10 |
11 | const server = http.createServer((req, res) => {
12 | res.statusCode = 200;
13 | res.setHeader('Content-Type', 'text/plain');
14 | res.end('Hello World\n');
15 | });
16 |
17 | server.listen(port, hostname, () => {
18 | console.log(`Server running at http://${hostname}:${port}/`);
19 | });
20 | ```
21 |
22 | ## 创建服务器
23 |
24 | 通过官方示例代码,我们可以清晰地看到,Node.js 通过 HTTP 模块提供的 `createServer()` 方法创建服务器。
25 |
26 | `createServer()` 方法的语法结构如下:
27 |
28 | ```javascript
29 | http.createServer([requestListener])
30 | ```
31 |
32 | - 该方法返回一个 `http.Server` 对象。
33 | - [requestListener] 是一个被自动添加到 request 事件上的函数。换言之,当 request 事件被触发时,会调用 [requestListener] 这个函数。
34 |
35 | **值得注意的是:** [requestListener] 这个参数是可选的。也就是说,我们在调用 `createServer()` 方法时,是可以不传递 [requestListener] 这个参数的。
36 |
37 | ### 1. 基于回调函数
38 |
39 | 根据上述语法结构,我们想要创建一个 HTTP 服务器的话,就可以通过如下代码完成。
40 |
41 | ```javascript
42 | const server = http.createServer((req, res) => {
43 | res.statusCode = 200;
44 | res.setHeader('Content-Type', 'text/plain');
45 | res.end('Hello World\n');
46 | });
47 | ```
48 |
49 | ### 2. 基于事件驱动
50 |
51 | 总所周知,Node.js 的特点之一就是**基于事件驱动**。怎么样才是事件驱动的,我们可以通过改造官方示例代码来学习。
52 |
53 | 首先,通过 `createServer()` 方法的帮助说明我们知道,当调用该方法时可以不传递任何参数。
54 |
55 | ```javascript
56 | const server = http.createServer();
57 | ```
58 |
59 | *当调用 `createServer()` 方法表示创建一个服务器,但接收请求时,我们并没有做任何处理。*
60 |
61 | 然后,通过 `createServer()` 方法返回的 `http.Server` 对象,绑定 request 事件,并添加相应的处理逻辑。
62 |
63 | ```javascript
64 | server.on('request', (req, res) => {
65 | res.statusCode = 200;
66 | res.setHeader('Content-Type', 'text/plain');
67 | res.end('Hello World\n');
68 | });
69 | ```
70 |
71 | *request 事件会在服务器端接收到请求时被触发,并且调用对应的回调函数。*
72 |
73 | ## Response 响应对象
74 |
75 | 在绑定 request 事件的回调函数中,接收了两个参数 req 和 res。在官方示例中,使用 res 这个参数。
76 |
77 | res 这个参数,实际上是 `http.ServerResponse` 对象。该对象是由 HTTP 服务器内部创建,专门用来处理向客户端响应数据的。
78 |
79 | **值得注意的是:** `http.ServerResponse` 对象只能由 HTTP 模块自动生成,我们是无法自己创建这个对象的。
80 |
81 | ### 1. 设置响应状态码和响应头部信息
82 |
83 | 在官方示例中,通过 `http.ServerResponse` 对象设置了响应状态码和响应头部信息。
84 |
85 | ```javascript
86 | const server = http.createServer((req, res) => {
87 | res.statusCode = 200;
88 | res.setHeader('Content-Type', 'text/plain');
89 | });
90 | ```
91 |
92 | - statusCode 属性: 用于设置向客户端响应的状态码。
93 | - setHeader(name, value) 方法: 用于设置向客户端响应的头部信息。
94 | - name 参数: 表示响应头部信息的名称。
95 | - value 参数: 表示响应头部信息的值。
96 |
97 | 想要完成上述效果,我们还可以通过 `http.ServerResponse` 对象的 `writeHead()` 方法来完成。
98 |
99 | ```javascript
100 | const server = http.createServer((req, res) => {
101 | res.writeHead(200, {
102 | 'Content-Type' : 'text/plain'
103 | });
104 | });
105 | ```
106 | `writeHead()` 方法的语法结构如下:
107 | ```javascript
108 | response.writeHead(statusCode[, statusMessage][, headers])
109 | ```
110 |
111 | - statusCode 参数: 必要参数,表示 HTTP 的三位状态码。作用等价于 statusCode 属性。
112 | - statusMessage 参数: 可选参数,表示 statusCode 状态码的描述信息。一般默认不设置。
113 | - headers 参数: 可选参数,表示响应头部信息对象。
114 |
115 | ### 2. 设置响应数据
116 |
117 | 在官方示例中,通过 `http.ServerResponse` 对象还设置了向客户端响应的数据内容。
118 |
119 | ```javascript
120 | const server = http.createServer((req, res) => {
121 | res.end('Hello World\n');
122 | });
123 | ```
124 |
125 | `end()` 方法表示向客户端发送的状态码、响应头部信息和响应数据等都已完成。该方法的语法结构如下:
126 |
127 | ```javascript
128 | response.end([data][, encoding][, callback])
129 | ```
130 |
131 | - data 参数: 可选参数,表示响应数据内容。
132 | - encoding 参数: 可选参数,表示响应数据的编码方式。默认值为 UTF-8。
133 | - callback 参数: 可选参数,如果设置了 data 参数,表示结束响应时的回调函数。
134 |
135 | 设置响应数据还可以通过使用 `write()` 方法来完成,该方法的语法结构如下:
136 |
137 | ```javascript
138 | response.write(chunk[, encoding][, callback])
139 | ```
140 |
141 | - chunk 参数: 必要参数,表示响应数据内容。作用等价于 `end()` 方法中的 data 参数。
142 | - encoding 参数: 可选参数,表示响应数据的编码方式。默认值为 UTF-8。作用等价于 `end()` 方法中的 encoding 参数。
143 | - callback 参数: 可选参数,表示写入响应数据时的回调函数。作用等价于 `end()` 方法中的 callback 参数。
144 |
145 | #### 1) 如果响应数据通过 `write()` 方法设置
146 |
147 | 根据上述内容,我们将 `write()` 方法和 `end()` 方法结合使用。
148 |
149 | - 通过 `write()` 方法设置响应数据。
150 | - 通过 `end()` 方法设置响应完成后的回调函数。
151 |
152 | ```javascript
153 | const server = http.createServer((req, res) => {
154 | res.write('Hello World\n');
155 | res.end(() =>{
156 | console.log('Server response end.');
157 | });
158 | });
159 | ```
160 |
161 | #### 2) 如果响应数据和回调函数通过 `write()` 方法设置
162 |
163 | 我们也可以将响应的数据和响应完成后的回调函数通过 `write()` 方法一并完成。
164 |
165 | **值得注意的是:** `end()` 方法是必须调用的。否则,服务器端的响应始终不会结束。
166 |
167 | ```javascript
168 | const server = http.createServer((req, res) => {
169 | res.write('Hello World\n',() =>{
170 | console.log('Server response end.');
171 | });
172 | res.end();
173 | });
174 | ```
175 |
176 | ## Server 对象
177 |
178 | `http.Server` 对象是通过调用 HTTP 模块的 `createServer()` 方法创建服务器时,所返回的服务器对象。
179 |
180 | 在官方示例中,通过 `http.Server` 对象的 `listen()` 方法绑定服务器端的 IP 地址和端口号。
181 |
182 | ```javascript
183 | const hostname = '127.0.0.1';
184 | const port = 3000;
185 | server.listen(port, hostname, () => {
186 | console.log(`Server running at http://${hostname}:${port}/`);
187 | });
188 | ```
189 |
190 | ### 1. 服务器监听
191 |
192 | 上述示例代码中使用的 `listen()` 方法的语法结构如下:
193 |
194 | ```javascript
195 | server.listen([port][, hostname][, backlog][, callback])
196 | ```
197 |
198 | - port 参数: 必要参数,用于指定需要监听的端口号。如果值为 0 将随机一个端口号。
199 | - hostname 参数: 可选参数,用于指定需要监听的地址。如果忽略,将监听任何地址的客户端请求。
200 | - backlog 参数: 可选参数,用于指定位于等待队列中的客户端连接的最大数量。默认值为 511。
201 | - callback 参数: 可选参数,用于指定 listening 事件触发时的回调函数。
202 |
203 | `listen()` 方法的 `callback` 回调函数也可以通过 `http.Server` 对象绑定 `listening` 事件完成。
204 |
205 | ```javascript
206 | const hostname = '127.0.0.1';
207 | const port = 3000;
208 | server.listen(port, hostname);
209 | server.on('listening', () => {
210 | console.log(`Server running at http://${hostname}:${port}/`);
211 | });
212 | ```
213 |
214 | ### 2. 完整流程
215 |
216 | `http.Server` 对象还提供了一系列的事件和方法完成服务器端的完整执行流程,如下图所示:
217 | 
218 | 
219 |
220 | #### 1) 监听是否建立连接
221 |
222 | `http.Server` 对象提供了 `connection` 事件,用于监听客户端与服务器端之间是否建立。
223 |
224 | ```javascript
225 | server.on('connection', (socket) => {
226 | // 当触发 connection 事件时的回调函数
227 | };
228 | ```
229 |
230 | - 回调函数中的 `socket` 参数: 是 `net.Socket` 对象。
231 |
232 | 我们可以在官方示例中,添加用于监听客户端与服务器建立连接的 `connection` 事件。
233 |
234 | ```javascript
235 | const http = require('http');
236 |
237 | const hostname = '127.0.0.1';
238 | const port = 3000;
239 |
240 | // 1. 创建服务器
241 | const server = http.createServer();
242 | server.listen(port, hostname, () => {
243 | console.log(`Server running at http://${hostname}:${port}/`);
244 | });
245 | // 2. 监听客户端与服务器端之间建立连接
246 | server.on('connection', () => {
247 | console.log('Client and server connections');
248 | });
249 | ```
250 |
251 | 通过 `node` 命令运行上述示例代码,并且通过浏览器访问服务器,可以在“终端”或“命令行窗口”看到如下图所示的效果:
252 | 
253 | 
254 |
255 | #### 2) 监听是否发送请求
256 |
257 | `http.Server` 对象提供了 `request` 事件,用于监听客户端是否向服务器端发送请求。
258 |
259 | ```javascript
260 | server.on('request', (req, res) => {
261 | // 当触发 request 事件时的回调函数
262 | });
263 | ```
264 |
265 | - 回调函数中的 `req` 参数: 是 `http.IncomingMessage` 对象,代表客户端请求。
266 | - 回调函数中的 `res` 参数: 是 `http.ServerResponse` 对象,代表服务器端响应。
267 |
268 | #### 3) 监听服务器是否关闭
269 |
270 | `http.Server` 对象提供了 `close()` 方法,用于关闭服务器。该方法的语法结构如下:
271 |
272 | ```javascript
273 | server.close([callback])
274 | ```
275 |
276 | - callback 参数: 表示关闭服务器时的回调函数,一般用于释放服务器资源。
277 |
278 | 在官方示例中,当不再需要服务器时,我们可以通过 `close()` 方法关闭。
279 |
280 | ```javascript
281 | const http = require('http');
282 |
283 | const hostname = '127.0.0.1';
284 | const port = 3000;
285 |
286 | // 1. 创建服务器
287 | const server = http.createServer();
288 | server.listen(port, hostname, () => {
289 | console.log(`Server running at http://${hostname}:${port}/`);
290 | });
291 | // 2. 监听客户端与服务器端之间建立连接
292 | server.on('connection', () => {
293 | console.log('Client and server connections');
294 | });
295 | // 3. 监听客户端向服务器端发送请求
296 | server.on('request', (req, res) => {
297 | console.log('Client sent a request');
298 | res.statusCode = 200;
299 | res.setHeader('Content-Type', 'text/plain');
300 | res.end('Hello World\n');
301 | // 4. 关闭服务器
302 | if(res.finished){// 当调用 end() 方法时,finished 属性的值为 true
303 | server.close(() => {
304 | console.log('Server is down')
305 | });
306 | }
307 | });
308 | ```
309 |
310 | 通过 `node` 命令运行上述示例代码,并且通过浏览器访问服务器,可以在“终端”或“命令行窗口”看
311 | 到如下图所示的效果:
312 | 
313 | 
314 |
315 | 当然,我们也可以通过 `close` 事件来监听 `close()` 方法是否被调用。
316 |
317 | *`close` 事件是用于监听服务器是否关闭。当服务器关闭时会触发该事件。*
318 |
319 | ```javascript
320 | const http = require('http');
321 |
322 | const hostname = '127.0.0.1';
323 | const port = 3000;
324 |
325 | // 1. 创建服务器
326 | const server = http.createServer();
327 | server.listen(port, hostname, () => {
328 | console.log(`Server running at http://${hostname}:${port}/`);
329 | });
330 | // 2. 监听客户端与服务器端之间建立连接
331 | server.on('connection', () => {
332 | console.log('Client and server connections');
333 | });
334 | // 3. 监听客户端向服务器端发送请求
335 | server.on('request', (req, res) => {
336 | console.log('Client sent a request');
337 | res.statusCode = 200;
338 | res.setHeader('Content-Type', 'text/plain');
339 | res.end('Hello World\n');
340 | // 4. 关闭服务器
341 | if(res.finished){// 当调用 end() 方法时,finished 属性的值为 true
342 | server.close();
343 | }
344 | });
345 | server.on('close', () => {
346 | console.log('Server is down')
347 | })
348 | ```
349 |
350 | ### 3. 注意事项
351 |
352 | #### 1) 每次发送两次请求
353 |
354 | 在上述示例中,当客户端向服务器端发送请求,`request` 事件每次都会触发两次。
355 |
356 | - 一次是客户端浏览器向服务器端发送的真正请求。
357 | - 一次是客户端浏览器加载为 `favicon.ico` 图标,自动发送的请求。
358 |
359 | 想要在服务器端的逻辑中只处理来自客户端浏览器的真正请求,我们可以在 `request` 事件的回调函数中,加入以下代码内容:
360 |
361 | ```javascript
362 | server.on('request', (req, res) => {
363 | // 判断当前请求并不是加载 favicon.ico 图标
364 | if(req.url!='/favicon.ico'){
365 | res.statusCode = 200;
366 | res.setHeader('Content-Type', 'text/plain');
367 | res.end('Hello World\n');
368 | }
369 | });
370 | ```
371 |
372 | #### 2) 默认2分钟关闭服务器
373 |
374 | 在上述示例中,当关闭服务器时,需要等待 2分钟,服务器才自动关闭。原因在于 Node.js 设置的服务器默认超时时间为 2 分钟,如果想修改超时时间的话,可以通过以下两种方式实现:
375 |
376 | - `http.Server` 对象的 `timeout` 属性。
377 | - `http.Server` 对象的 `setTimeout()` 方法。
378 |
379 | `setTimeout()` 方法的语法结构如下:
380 |
381 | ```javascript
382 | server.setTimeout(msecs, callback)
383 | ```
384 |
385 | - msecs 参数: 整数,用于设置服务器的超时时间。单位为毫秒。
386 | - callback 参数: 用于设置当服务器超时时的回调函数。
--------------------------------------------------------------------------------
/05-nodejs-repl/README.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstack-kingj/easy-node/42830f0d2280878409d8a54f0e311ea5a451bd68/05-nodejs-repl/README.md
--------------------------------------------------------------------------------
/06-client-request.md:
--------------------------------------------------------------------------------
1 | **在本节课中,我们将学习如何接收客户端发送的请求,并且如何处理这些请求数据。**
2 |
3 | 在官方示例中,我们可以掌握了通过 HTTP 模块的 `createServer()` 方法创建服务器,并且掌握了其回调函数中的 `res` 参数,该参数表示响应对象。
4 |
5 | 但,在其回调函数还包含了另一个参数 `req`,表示客户端请求的对象。
6 |
7 | ```javascript
8 | const server = http.createServer((req, res) => {
9 | res.statusCode = 200;
10 | res.setHeader('Content-Type', 'text/plain');
11 | res.end('Hello World\n');
12 | });
13 | ```
14 |
15 | ## Request 请求对象
16 |
17 | 作为 `http.createServer()` 方法的回调函数的第一个参数 `req` 是 `http.IncomingMessage` 对象,它可用于访问响应状态、标题和数据。
18 |
19 | ### 1. `http.IncomingMessage` 对象的常用属性
20 |
21 | `http.IncomingMessage` 对象用于读取客户端请求流中的数据,该对象提供一系列属性:
22 |
23 | | 属性名称 | 描述 |
24 | | --- | --- |
25 | | url | 请求的 URL 字符串 |
26 | | method | 请求方法,例如 GET 等|
27 | | headers | 请求头信息 |
28 | | httpVersion | HTTP 版本 |
29 |
30 | 通过如下示例代码测试 `IncomingMessage` 对象的上述属性内容:
31 |
32 | ```javascript
33 | const http = require('http');
34 |
35 | const server = http.createServer(function(req, res){
36 | if (req.url != '/favicon.ico'){
37 | console.log('message.url: '+req.url);
38 | console.log('message.method: '+req.method);
39 | console.log('message.headers: '+JSON.stringify(req.headers));
40 | console.log('message.httpVersion: '+req.httpVersion);
41 | res.end();
42 | }
43 | });
44 | server.listen('3000', '127.0.0.1', function(){
45 | console.log('Server is running.');
46 | });
47 | ```
48 |
49 | 上述示例代码,运行后的结果如下图所示:
50 |
51 | 
52 | 
53 | ### 2. `stream.Readable` 接口的事件
54 |
55 | `IncomingMessage` 对象还实现了 `stream.Readable` 接口,`stream.Readable` 接口提供了 data 和 end 事件。
56 |
57 | * data 事件会在从客户端请求流中读取到新数据时触发。
58 | * end 事件会在客户端请求流中的数据读取完毕时触发。
59 |
60 | ```javascript
61 | const http = require('http');
62 |
63 | const server = http.createServer(function(req, res){
64 | if (req.url != '/favicon.ico') {
65 | req.on('data', function (data) {
66 | console.log('Data of the client: ' + decodeURIComponent(data));
67 | });
68 | req.on('end', function () {
69 | console.log('Data stream is readed.');
70 | });
71 | res.end();
72 | }
73 | });
74 | server.listen('3000', '127.0.0.1', function(){
75 | console.log('Server is running.');
76 | });
77 | ```
78 |
79 | 上述示例代码,运行后的结果如下图所示:
80 |
81 | 
82 | 
83 | 如果我们创建一个 HTML 页面,并且请求上述服务器,情况会有所不同。
84 |
85 | ```html
86 |
87 |
88 |
89 |
90 | IncomingMessage
91 |
92 |
93 |
98 |
99 |
100 | ```
101 |
102 | 通过浏览器访问上述 HTML 页面:
103 |
104 | 
105 | 
106 | 输入数据后,点击【提交】按钮,效果如下图所示:
107 | 
108 | 
109 |
110 | ## URL 模块
111 |
112 | 通过 `http.IncomingMessage` 对象的 url 属性可以得到客户端的请求流中的 URL 字符串。而 URL 模块是包含了专门用于分析和解析 URL 字符串的工具。
113 |
114 | 想要掌握 URL 模块的内容,首先需要先对 URL 有个基本的了解。
115 |
116 | ### 1. URL 格式
117 |
118 | 完整的 URL 语法格式如下:
119 |
120 | ```
121 | protocol :// [username:password @] hostname[:port] / path / [;parameters][?query]#fragment
122 | ```
123 |
124 | | 语法内容 | 描述 |
125 | | --- | --- |
126 | | protocol | 协议名称,例如 HTTP 等 |
127 | | username | 登录名称,用于登录认证 |
128 | | password | 登录密码,用于登录认证 |
129 | | hostname | 服务器地址,可以是 IP 地址或者域名 |
130 | | port | 端口号 |
131 | | path | 文件的路径,可以是相对路径或绝对路径 |
132 | | parameters | 请求参数,用于指定特殊参数 |
133 | | query | 查询字符串,用于发送给服务器的数据 |
134 | | fragment | 片段标示符,多指锚点等 |
135 |
136 | 完成的 URL 内容,例如如下示例:
137 |
138 | ```
139 | http://user:pass@host.com:8080/p/a/t/h?query=string#hash
140 | ```
141 |
142 | 在了解了 URL 的完整格式后,再来看看 Node.js 的 URL 模块所提供的方法。
143 |
144 | ### 2. url.parse() 方法
145 |
146 | `url.parse()` 方法的具体语法结构如下:
147 |
148 | ```javascript
149 | url.parse(urlStr[, parseQueryString][, slashesDenoteHost])
150 | ```
151 |
152 | - urlStr 参数: 必要参数,指定需要转换的 URL 字符串。
153 | - parseQueryString 参数: 可选参数,是否使用 Query Strings 模块转换查询字符串。默认为 false,表示不使用 Query Strings 模块转换。
154 | - slashesDenoteHost 参数: 可选参数,是否将 hostname 单独解析。默认为 false,不解析。
155 |
156 | 具体用法可参考如下示例代码:
157 |
158 | ```javascript
159 | const url = require('url');
160 |
161 | console.log(url.parse('http://user:pwd@127.0.0.1:8888/users/user.html?username=jinyunlong&pwd=12345#age'));
162 | ```
163 |
164 | 上述代码示例,运行结果如下:
165 |
166 | ```
167 | Url {
168 | protocol: 'http:',
169 | slashes: true,
170 | auth: 'user:pwd',
171 | host: '127.0.0.1:8888',
172 | port: '8888',
173 | hostname: '127.0.0.1',
174 | hash: '#age',
175 | search: '?username=jinyunlong&pwd=12345',
176 | query: 'username=jinyunlong&pwd=12345',
177 | pathname: '/users/user.html',
178 | path: '/users/user.html?username=jinyunlong&pwd=12345',
179 | href: 'http://user:pwd@127.0.0.1:8888/users/user.html?username=jinyunlong&pwd=12345#age'
180 | }
181 | ```
182 |
183 | 如果指定使用 Query Strings 模块对查询字符串进行解析,调用 `url.parse()` 方法时的第二个参数设置为 true。如下代码所示:
184 |
185 | ```javascript
186 | const url = require('url');
187 |
188 | console.log(url.parse('http://user:pwd@127.0.0.1:8888/users/user.html?username=jinyunlong&pwd=12345#age', true));
189 | ```
190 |
191 | 输出的内容则如下所示:
192 |
193 | ```
194 | Url {
195 | protocol: 'http:',
196 | slashes: true,
197 | auth: 'user:pwd',
198 | host: '127.0.0.1:8888',
199 | port: '8888',
200 | hostname: '127.0.0.1',
201 | hash: '#age',
202 | search: '?username=jinyunlong&pwd=12345',
203 | query: { username: 'jinyunlong', pwd: '12345' },
204 | pathname: '/users/user.html',
205 | path: '/users/user.html?username=jinyunlong&pwd=12345',
206 | href: 'http://user:pwd@127.0.0.1:8888/users/user.html?username=jinyunlong&pwd=12345#age'
207 | }
208 | ```
209 |
210 | 上述两个示例之间的区别仅在于 query 字段的值。
211 |
212 | ### 3. url.format() 方法
213 |
214 | `url.formate()` 方法的具体语法结构如下:
215 |
216 | ```javascript
217 | url.format(urlObj)
218 | ```
219 |
220 | 如上述语法格式,urlObj 参数表示一个解析过的并需要还原的 URL 对象。该方法返回一个还原后的 URL 字符串。如下述示例代码:
221 |
222 | ```javascript
223 | const url = require('url');
224 |
225 | const urlObj = url.parse('http://user:pwd@127.0.0.1:8888/users/user.html?username=jinyunlong&pwd=12345#age',true)
226 |
227 | console.log(url.format(urlObj));
228 | ```
229 |
230 | 上述示例代码运行后,最终会得到一个被还原的 URL 字符串:
231 |
232 | ```
233 | http://user:pwd@127.0.0.1:8888/users/user.html?username=jinyunlong&pwd=12345#age
234 | ```
235 |
236 | ### 4. url.resolve() 方法
237 |
238 | `url.resolve()` 方法的具体语法结构如下:
239 |
240 | ```javascript
241 | url.resolve(from, to)
242 | ```
243 |
244 | 该方法表示将两个路径结合成为一个路径。第一个参数表示起点路径字符串,第二个参数表示参考路径字符串。
245 |
246 | *这两个路径既可以是相对路径,也可以是绝对路径。*
247 |
248 | ## Query Strings 模块
249 |
250 | Node.js 的 Query Strings 模块提供用于处理查询字符串的实用工具。
251 |
252 | ### 1. querystring.parse() 方法
253 |
254 | `querystring.parse()` 方法的具体语法结构如下:
255 |
256 | ```javascript
257 | querystring.parse(str[, sep][, eq][, options])
258 | ```
259 |
260 | - str 参数: 表示需要转换的查询字符串。
261 | - sep 参数: 表示分隔符`&`。
262 | - eq 参数: 表示分隔符`=`。
263 | - options 参数: maxKeys 属性用来限制处理过的健值。默认值为 1000,如果为 0 的话可以去掉键值的数量限制。decodeURIComponent 属性用来设置解析编码格式。
264 |
265 | `querystring.parse()` 方法具体的用法如下:
266 |
267 | ```javascript
268 | > querystring.parse('foo=bar&baz=qux&baz=quux&corge')
269 | { foo: 'bar', baz: [ 'qux', 'quux' ], corge: '' }
270 | ```
271 |
272 | ### 2. querystring.stringify() 方法
273 |
274 | `querystring.stringify()` 方法的具体语法结构如下:
275 |
276 | ```javascript
277 | querystring.stringify(obj[, sep][, eq][, options])
278 | ```
279 |
280 | - obj 参数: 表示需要转换的对象。
281 | - sep 参数: 表示分隔符`&`。
282 | - eq 参数: 表示分隔符`=`。
283 | - options 参数: maxKeys 属性用来限制处理过的健值。默认值为 1000,如果为 0 的话可以去掉键值的数量限制。decodeURIComponent 属性用来设置解析编码格式。
284 |
285 | `querystring.stringify()` 方法具体的用法如下:
286 |
287 | ```javascript
288 | > querystring.stringify({ foo: 'bar', baz: ['qux', 'quux'], corge: '' })
289 | 'foo=bar&baz=qux&baz=quux&corge='
290 | > querystring.stringify({foo: 'bar', baz: 'qux'}, ';', ':')
291 | 'foo:bar;baz:qux'
292 | ```
--------------------------------------------------------------------------------
/06-hello-world/README.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstack-kingj/easy-node/42830f0d2280878409d8a54f0e311ea5a451bd68/06-hello-world/README.md
--------------------------------------------------------------------------------
/07-official-sample/README.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstack-kingj/easy-node/42830f0d2280878409d8a54f0e311ea5a451bd68/07-official-sample/README.md
--------------------------------------------------------------------------------
/08-keywords-const/README.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstack-kingj/easy-node/42830f0d2280878409d8a54f0e311ea5a451bd68/08-keywords-const/README.md
--------------------------------------------------------------------------------
/09-difference-between-var-let-and-const/README.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstack-kingj/easy-node/42830f0d2280878409d8a54f0e311ea5a451bd68/09-difference-between-var-let-and-const/README.md
--------------------------------------------------------------------------------
/10-block-scope/README.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstack-kingj/easy-node/42830f0d2280878409d8a54f0e311ea5a451bd68/10-block-scope/README.md
--------------------------------------------------------------------------------
/11-arrow-function/README.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstack-kingj/easy-node/42830f0d2280878409d8a54f0e311ea5a451bd68/11-arrow-function/README.md
--------------------------------------------------------------------------------
/12-arrow-function-notes/README.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstack-kingj/easy-node/42830f0d2280878409d8a54f0e311ea5a451bd68/12-arrow-function-notes/README.md
--------------------------------------------------------------------------------
/13-template-string/README.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstack-kingj/easy-node/42830f0d2280878409d8a54f0e311ea5a451bd68/13-template-string/README.md
--------------------------------------------------------------------------------
/14-what-is-modularity/README.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstack-kingj/easy-node/42830f0d2280878409d8a54f0e311ea5a451bd68/14-what-is-modularity/README.md
--------------------------------------------------------------------------------
/15-javascript-module/README.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstack-kingj/easy-node/42830f0d2280878409d8a54f0e311ea5a451bd68/15-javascript-module/README.md
--------------------------------------------------------------------------------
/16-ecmascript-2015-module/README.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstack-kingj/easy-node/42830f0d2280878409d8a54f0e311ea5a451bd68/16-ecmascript-2015-module/README.md
--------------------------------------------------------------------------------
/17-node-modular-system/README.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstack-kingj/easy-node/42830f0d2280878409d8a54f0e311ea5a451bd68/17-node-modular-system/README.md
--------------------------------------------------------------------------------
/18-node-file-module/README.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstack-kingj/easy-node/42830f0d2280878409d8a54f0e311ea5a451bd68/18-node-file-module/README.md
--------------------------------------------------------------------------------
/19-nodejs-module-object/README.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstack-kingj/easy-node/42830f0d2280878409d8a54f0e311ea5a451bd68/19-nodejs-module-object/README.md
--------------------------------------------------------------------------------
/20-modular-specification/README.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstack-kingj/easy-node/42830f0d2280878409d8a54f0e311ea5a451bd68/20-modular-specification/README.md
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 金云龙
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | 
2 |
3 | ## 关于课程
4 |
5 | 本套课程意在编写一套最适合入门级学习的 Node.js 资料,以不同于现有的编排顺序和思路。本着互联网的开源共享理念,本套课程所有内容进行免费开源,让所有想学习 Node.js 技术的童鞋可以免费自学。
6 |
7 | ## 课程特点
8 |
9 | 本套课程拒绝简单暴力的罗列 API,因为有些内容在实际开发中并不常用。这些内容即使在实际开发时用到了,查阅一下官方帮助文档就行了。
10 |
11 | 本套课程拒绝抄袭现有内容。简单地整理、总结、重新编排现有的教程或资料,没有多大意义。我们要以一个初学者的角度,以实战为目的的去探索出一套真正适合入门学习的 Node.js 课程,并且可以快速的在实际开发中进行运用。
12 |
13 | 源于 Node.js,又不止于 Node.js。本套课程是以学习 Node.js 技术为主的课程,但在实际开发中会运用到一些相关技术,例如模板引擎。所以,我们不仅仅只学习 Node.js,相关的技术同样需要学习。
14 |
15 | ## 课程目录
16 |
17 | - 第一章 开启 Node 世界的大门
18 | - [第一回 什么是 Node.js](01-what-is-nodejs/README.md)
19 | - [第二回 安装 Node.js](02-install-nodejs/README.md)
20 | - [番外篇 Windows 系统环境安装 Node.js](03-windows-system-environment-installation-nodejs/README.md)
21 | - [番外篇 MacOS 系统环境安装 Node.js](04-macos-system-environment-installation-nodejs/README.md)
22 | - [第三回 Node REPL](05-nodejs-repl/README.md)
23 | - [第四回 Hello World](06-hello-world/README.md)
24 | - 第二章 第一个 Node 应用程序
25 | - [第五回 官方示例](07-official-sample/README.md)
26 | - [第六回 const 关键字](08-keywords-const/README.md)
27 | - [番外篇 var、let 和 const 的区别](09-difference-between-var-let-and-const/README.md)
28 | - [番外篇 块级作用域](10-block-scope/README.md)
29 | - [第七回 箭头函数](11-arrow-function/README.md)
30 | - [番外篇 箭头函数的注意事项](12-arrow-function-notes/README.md)
31 | - [第八回 模板字符串](13-template-string/README.md)
32 | - 第三章 Node 的模块化机制
33 | - [第九回 什么是模块化](14-what-is-modularity/README.md)
34 | - [番外篇 JavaScript 的模块化](15-javascript-module/README.md)
35 | - [番外篇 ECMAScript 2015 的模块](16-ecmascript-2015-module/README.md)
36 | - [第十回 Node 的模块系统](17-node-modular-system/README.md)
37 | - [第十一回 Node的文件模块](18-node-file-module/README.md)
38 | - [番外篇 Node.js 的 Module 对象](19-nodejs-module-object/README.md)
39 | - [番外篇 模块化规范](20-modular-specification/README.md)
40 | - 第四章 创建 HTTP 服务器
41 | - []()
42 |
43 | ## 版权说明
44 |
45 | 本套课程的文本内容免费开源,任何人都可以免费学习、分享,甚至可以进行修改。但需要注明作者及来源,并且不能用于商业。
46 |
47 | 
本套课程采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议进行许可。
--------------------------------------------------------------------------------
/SUMMARY.md:
--------------------------------------------------------------------------------
1 | # Summary
2 |
3 | * [Introduction](README.md)
4 | * [安装 NodeJS](安装-nodejs.md)
5 |
6 |
--------------------------------------------------------------------------------
/cover.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstack-kingj/easy-node/42830f0d2280878409d8a54f0e311ea5a451bd68/cover.png
--------------------------------------------------------------------------------
/images/2016-12-05-16-43-05.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstack-kingj/easy-node/42830f0d2280878409d8a54f0e311ea5a451bd68/images/2016-12-05-16-43-05.png
--------------------------------------------------------------------------------
/images/2016-12-06-14-17-03.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstack-kingj/easy-node/42830f0d2280878409d8a54f0e311ea5a451bd68/images/2016-12-06-14-17-03.jpg
--------------------------------------------------------------------------------
/images/2016-12-06-17-41-46.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstack-kingj/easy-node/42830f0d2280878409d8a54f0e311ea5a451bd68/images/2016-12-06-17-41-46.png
--------------------------------------------------------------------------------
/images/2016-12-10-23-22-23.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstack-kingj/easy-node/42830f0d2280878409d8a54f0e311ea5a451bd68/images/2016-12-10-23-22-23.png
--------------------------------------------------------------------------------
/images/5e10d357716faf0b.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstack-kingj/easy-node/42830f0d2280878409d8a54f0e311ea5a451bd68/images/5e10d357716faf0b.png
--------------------------------------------------------------------------------
/images/Snip20161126_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstack-kingj/easy-node/42830f0d2280878409d8a54f0e311ea5a451bd68/images/Snip20161126_1.png
--------------------------------------------------------------------------------
/images/Snip20161205_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstack-kingj/easy-node/42830f0d2280878409d8a54f0e311ea5a451bd68/images/Snip20161205_1.png
--------------------------------------------------------------------------------
/images/Snip20161205_3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstack-kingj/easy-node/42830f0d2280878409d8a54f0e311ea5a451bd68/images/Snip20161205_3.png
--------------------------------------------------------------------------------
/images/Snip20161205_4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstack-kingj/easy-node/42830f0d2280878409d8a54f0e311ea5a451bd68/images/Snip20161205_4.png
--------------------------------------------------------------------------------
/images/Snip20161206_10.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstack-kingj/easy-node/42830f0d2280878409d8a54f0e311ea5a451bd68/images/Snip20161206_10.png
--------------------------------------------------------------------------------
/images/Snip20161206_11.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstack-kingj/easy-node/42830f0d2280878409d8a54f0e311ea5a451bd68/images/Snip20161206_11.png
--------------------------------------------------------------------------------
/images/Snip20161206_12.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstack-kingj/easy-node/42830f0d2280878409d8a54f0e311ea5a451bd68/images/Snip20161206_12.png
--------------------------------------------------------------------------------
/images/Snip20161206_13.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstack-kingj/easy-node/42830f0d2280878409d8a54f0e311ea5a451bd68/images/Snip20161206_13.png
--------------------------------------------------------------------------------
/images/Snip20161206_5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstack-kingj/easy-node/42830f0d2280878409d8a54f0e311ea5a451bd68/images/Snip20161206_5.png
--------------------------------------------------------------------------------
/images/Snip20161206_6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstack-kingj/easy-node/42830f0d2280878409d8a54f0e311ea5a451bd68/images/Snip20161206_6.png
--------------------------------------------------------------------------------
/images/Snip20161206_9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstack-kingj/easy-node/42830f0d2280878409d8a54f0e311ea5a451bd68/images/Snip20161206_9.png
--------------------------------------------------------------------------------
/images/Snip20161207_14.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstack-kingj/easy-node/42830f0d2280878409d8a54f0e311ea5a451bd68/images/Snip20161207_14.png
--------------------------------------------------------------------------------
/images/Snip20161207_15.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstack-kingj/easy-node/42830f0d2280878409d8a54f0e311ea5a451bd68/images/Snip20161207_15.png
--------------------------------------------------------------------------------
/images/Snip20161207_16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstack-kingj/easy-node/42830f0d2280878409d8a54f0e311ea5a451bd68/images/Snip20161207_16.png
--------------------------------------------------------------------------------
/images/Snip20161211_22.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstack-kingj/easy-node/42830f0d2280878409d8a54f0e311ea5a451bd68/images/Snip20161211_22.png
--------------------------------------------------------------------------------
/images/Snip20161211_23.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstack-kingj/easy-node/42830f0d2280878409d8a54f0e311ea5a451bd68/images/Snip20161211_23.png
--------------------------------------------------------------------------------
/images/Snip20161211_24.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstack-kingj/easy-node/42830f0d2280878409d8a54f0e311ea5a451bd68/images/Snip20161211_24.png
--------------------------------------------------------------------------------
/images/Snip20161211_25.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstack-kingj/easy-node/42830f0d2280878409d8a54f0e311ea5a451bd68/images/Snip20161211_25.png
--------------------------------------------------------------------------------