总结:
通用
- Node.js安装包:http://nodejs.cn/download/。
- API检索网址:API 文档 | Node.js 中文网 (nodejs.cn)
- 第三方模板引擎:art-template官方文档
- Express: 提供了创建 Web 服务器的最简单但功能最强大的方法之一。 它的极简主义方法,专注于服务器的核心功能,是其成功的关键。
- koa: 由 Express 背后的同一个团队构建,旨在变得更简单更轻巧。 新项目的诞生是为了满足创建不兼容的更改而又不破坏现有社区。
- readyState
- 存有 XMLHttpRequest 的状态。从 0 到 4 发生变化。
- 0: 请求未初始化
- 1: 服务器连接已建立
- 2: 请求已接收
- 3: 请求处理中
- 4: 请求已完成,且响应已就绪
- status
- 200, OK,访问正常
- 301, Moved Permanently,永久移动
- 302, Moved temporarily,暂时移动
- 304, Not Modified,未修改
- 307, Temporary Redirect,暂时重定向
- 401, Unauthorized,未授权
- 403, Forbidden,禁止访问
- 404, Not Found,未发现指定网址
- 500, Internal Server Error,服务器发生错误
简介
定义
- 通俗易懂的讲,Node.js是JavaScript的运行平台,Node.js既不是语言,也不是框架,它是一个平台
- Node.js 应用程序运行于单个进程中,无需为每个请求创建新的线程。 Node.js 在其标准库中提供了一组异步的 I/O 原生功能(用以防止 JavaScript 代码被阻塞),并且 Node.js 中的库通常是使用非阻塞的范式编写的(从而使阻塞行为成为例外而不是规范)。
CommonJS 模块系统
Node.js 使用 CommonJS 模块系统,而在浏览器中,则还正在实现 ES 模块标准
在实践中,这意味着在 Node.js 中使用
require()
,而在浏览器中则使用import
。Webpack五大核心
entry:webpack打包的入口,其取值可以是字符串,数组或者一个对象
output:webpack打包的输出
mode:webpack打包分为两种模式,开发模式(development)与生产模式(production),默认为生产模式
选项 描述 development 会将 process.env.NODE_ENV 的值设为 development。启用 NamedChunksPlugin 和 NamedModulesPlugin。 production 会将 process.env.NODE_ENV 的值设为 production。启用 FlagDependencyUsagePlugin, FlagIncludedChunksPlugin, ModuleConcatenationPlugin, NoEmitOnErrorsPlugin, OccurrenceOrderPlugin, SideEffectsFlagPlugin 和 UglifyJsPlugin.
loader:webpack默认只能处理js、json格式的文件,而loader的作用则是将其他格式的文件,转换成webpack能够处理的文件
plugin:webpack插件,每一个插件都有一个特定的功能,它能处理loader无法处理的事情。插件的使用非常简单,在plugins数组中添加插件的实例化对象即可
Node使用:
- EcmaScript语言
- 和浏览器一样,在Node中没有Bom和Dom
- 核心模块
- process
- process.exit()
- process.env.NODE_ENV
- 文件操作的fs
- http服务操作的http
- url路径操作模块
- path路径处理模块
- os操作系统信息
- 第三方模块
- art-template: art-template官方文档
- 必须通过npm来下载才可以使用。node package manage(node包管理器)
- 自己写的模块
- 自己创建的文件
CommonJS 模块规范
- 在Node中的JavaScript还有一个重要的概念,模块系统。
- 模块作用域
- 使用require方法来加载模块
- 使用exports接口对象来导出模板中的成员
package.json
每一个项目都要有一个
package.json
文件(包描述文件,就像产品的说明书一样)这个文件可以通过
npm init
自动初始化出来Express
- 原生的http在某些方面表现不足以应对我们的开发需求,所以就需要使用框架来加快我们的开发效率,框架的目的就是提高效率,让我们的代码高度统一。
Node.js REPL
REPL 也被称为运行评估打印循环,是一种编程语言环境(主要是控制台窗口),它使用单个表达式作为用户输入,并在执行后将结果返回到控制台。
如果在终端中尝试,则会出现如下:
❯ node >
该命令会保持空闲状态,并等待输入内容。
确切地说,REPL 正在等待输入一些 JavaScript 代码。
从简单开始,输入:
> console.log('测试') 测试 undefined >
第一个值
测试
是告诉控制台要打印的输出,然后得到undefined
,它是运行console.log()
的返回值。现在可以输入一行新的 JavaScript。
console
%s
会格式化变量为字符串%d
会格式化变量为数字%i
会格式化变量为其整数部分%o
会格式化变量为对象CLI
- 命令行界面(英语:command-line interface,缩写:CLI)是在图形用户界面得到普及之前使用最为广泛的用户界面,它通常不支持鼠标,用户通过键盘输入指令,计算机接收到指令后,予以执行。也有人称之为字符用户界面(CUI)。
- 通常认为,命令行界面(CLI)没有图形用户界面(GUI)那么方便用户操作。因为,命令行界面的软件通常需要用户记忆操作的命令,但是,由于其本身的特点,命令行界面要较图形用户界面节约计算机系统的资源。在熟记命令的前提下,使用命令行界面往往要较使用图形用户界面的操作速度要快。所以,图形用户界面的操作系统中,都保留着可选的命令行界面。
Node.js 是一个开源与跨平台的 JavaScript 运行时环境。 它是一个可用于几乎任何项目的流行工具!
Node.js 在浏览器外运行 V8 JavaScript 引擎(Google Chrome 的内核)。 这使 Node.js 表现得非常出色。
Node.js 应用程序运行于单个进程中,无需为每个请求创建新的线程。 Node.js 在其标准库中提供了一组异步的 I/O 原生功能(用以防止 JavaScript 代码被阻塞),并且 Node.js 中的库通常是使用非阻塞的范式编写的(从而使阻塞行为成为例外而不是规范)。
当 Node.js 执行 I/O 操作时(例如从网络读取、访问数据库或文件系统),Node.js 会在响应返回时恢复操作,而不是阻塞线程并浪费 CPU 循环等待。
这使 Node.js 可以在一台服务器上处理数千个并发连接,而无需引入管理线程并发的负担(这可能是重大 bug 的来源)。
Node.js 具有独特的优势,因为为浏览器编写 JavaScript 的数百万前端开发者现在除了客户端代码之外还可以编写服务器端代码,而无需学习完全不同的语言。
在 Node.js 中,可以毫无问题地使用新的 ECMAScript 标准,因为不必等待所有用户更新其浏览器,你可以通过更改 Node.js 版本来决定要使用的 ECMAScript 版本,并且还可以通过运行带有标志的 Node.js 来启用特定的实验中的特性。
npm 的简单结构有助于 Node.js 生态系统的激增,现在 npm 仓库托管了超过 1,000,000 个可以自由使用的开源库包。
Node.js 最常见的 Hello World 示例是 Web 服务器:
const http = require('http') //首先引入了 Node.js http 模块。
const hostname = '127.0.0.1'
const port = 3000
const server = http.createServer((req, res) => {
res.statusCode = 200
res.setHeader('Content-Type', 'text/plain')
res.end('你好世界\n')
})
server.listen(port, hostname, () => {
console.log(`服务器运行在 http://${hostname}:${port}/`)
})
此代码首先引入了 Node.js http
模块。
Node.js 具有出色的标准库,包括对网络的一流支持。
http
的 createServer()
方法会创建新的 HTTP 服务器并返回它。
服务器被设置为监听指定的端口和主机名。 当服务器就绪后,回调函数会被调用,在此示例中会通知我们服务器正在运行。
每当接收到新的请求时,request
事件会被调用,并提供两个对象:一个请求(http.IncomingMessage
对象)和一个响应(http.ServerResponse
对象)。
这两个对象对于处理 HTTP 调用至关重要。
第一个对象提供了请求的详细信息。 在这个简单的示例中没有使用它,但是你可以访问请求头和请求数据。
第二个对象用于返回数据给调用方。
在此示例中:
res.statusCode = 200
设置 statusCode 属性为 200,以表明响应成功。
设置 Content-Type 响应头:
res.setHeader('Content-Type', 'text/plain')
关闭响应,添加内容作为 end()
的参数:
res.end('你好世界\n')
Node.js 是一个底层的平台。 为了使开发者做事变得容易又来劲,社区在 Node.js 上构建了数千个库。
久而久之,其中许多已成为受欢迎的选择。 以下是一些值得学习的清单:
浏览器和 Node.js 均使用 JavaScript 作为其编程语言。
构建运行于浏览器中的应用程序与构建 Node.js 应用程序完全不同。
尽管都是 JavaScript,但一些关键的差异使体验相当不同。
从广泛使用 JavaScript 的前端开发者的角度来看,Node.js 应用程序具有巨大的优势:使用单一语言轻松编程所有一切(前端和后端)。
你会拥有巨大的机会,因为全面、深入地学习一门编程语言并通过使用同一语言完成 web(无论是在客户端还是在服务器)上的所有工作是非常困难的,你会处于独特的优势地位。
不同的还有生态系统。
在浏览器中,大多数时候做的是与 DOM 或其他 Web 平台 API(例如 Cookies)进行交互。 当然,那些在 Node.js 中是不存在的。 没有浏览器提供的 document
、window
、以及所有其他的对象。
而且在浏览器中,不存在 Node.js 通过其模块提供的所有不错的 API,例如文件系统访问功能。
另一个很大的不同是,在 Node.js 中,可以控制运行环境。 除非构建的是任何人都可以在任何地方部署的开源应用程序,否则你能知道会在哪个版本的 Node.js 上运行该应用程序。 与浏览器环境(你无法选择访客会使用的浏览器)相比起来,这非常方便。
这意味着可以编写 Node.js 版本支持的所有现代的 ES6-7-8-9 JavaScript。
由于 JavaScript 发展的速度非常快,但是浏览器发展得慢一些,并且用户的升级速度也慢一些,因此有时在 web 上,不得不使用较旧的 JavaScript / ECMAScript 版本。
可以使用 Babel 将代码转换为与 ES5 兼容的代码,再交付给浏览器,但是在 Node.js 中,则不需要这样做。
另一个区别是 Node.js 使用 CommonJS 模块系统,而在浏览器中,则还正在实现 ES 模块标准。
在实践中,这意味着在 Node.js 中使用 require()
,而在浏览器中则使用 import
。
运行 Node.js 程序的常规方法是,运行全局可用的 node
命令(已安装 Node.js)并传入要执行的文件的名称。
比如主 Node.js 应用程序文件是 app.js
,则可以通过键入以下命令调用它:
node app.js
当运行命令时,请确保位于包含 app.js
文件的目录中。
有很多种方法可以终止 Node.js 应用程序。
当在控制台中运行程序时,可以使用 ctrl-C
将其关闭,但是这里要讨论的是以编程的方式退出。
process
核心模块提供了一种便利的方法,可以以编程的方式退出 Node.js 程序:process.exit()
。
当 Node.js 运行此行代码时,进程会被立即强制终止。
这意味着任何待处理的回调、仍在发送中的任何网络请求、任何文件系统访问、或正在写入 stdout
或 stderr
的进程,所有这些都会被立即非正常地终止。
可以传入一个整数,向操作系统发送退出码:
process.exit(1)
默认情况下,退出码为 0
,表示成功。 不同的退出码具有不同的含义,可以在系统中用于程序与其他程序的通信。
有关退出码的信息,详见 http://nodejs.cn/api/process.html#process_exit_codes
退出码#
中英对照
当没有更多异步操作挂起时,Node.js 通常会以
0
状态代码退出。 在其他情况下使用以下状态代码:
1
未捕获的致命异常:存在未捕获的异常,并且其没有被域或'uncaughtException'
事件句柄处理。2
: 未使用(由 Bash 预留用于内置误用)3
内部 JavaScript 解析错误:Node.js 引导过程中的内部 JavaScript 源代码导致解析错误。 这是极其罕见的,通常只能在 Node.js 本身的开发过程中发生。4
内部 JavaScript 评估失败:Node.js 引导过程中的内部 JavaScript 源代码在评估时未能返回函数值。 这是极其罕见的,通常只能在 Node.js 本身的开发过程中发生。5
致命错误:V8 中存在不可恢复的致命错误。 通常将打印带有前缀FATAL ERROR
的消息到标准错误。6
非函数的内部异常句柄:存在未捕获的异常,但内部致命异常句柄不知何故设置为非函数,无法调用。7
内部异常句柄运行时失败:存在未捕获的异常,并且内部致命异常句柄函数本身在尝试处理时抛出错误。 例如,如果'uncaughtException'
或domain.on('error')
句柄抛出错误,就会发生这种情况。8
: 未使用。 在以前版本的 Node.js 中,退出码 8 有时表示未捕获的异常。9
无效参数:指定了未知选项,或者提供了需要值的选项而没有值。10
内部 JavaScript 运行时失败:Node.js 引导过程中的内部 JavaScript 源代码在调用引导函数时抛出错误。 这是极其罕见的,通常只能在 Node.js 本身的开发过程中发生。12
无效的调试参数:设置了--inspect
和/或--inspect-brk
选项,但选择的端口号无效或不可用。13
未完成的顶层等待:在顶层代码中的函数外使用了await
,但传入的Promise
从未解决。>128
信号退出:如果 Node.js 收到致命的信号,例如SIGKILL
或SIGHUP
,则其退出码将是128
加上信号代码的值。 这是标准的 POSIX 实践,因为退出码被定义为 7 位整数,并且信号退出设置高位,然后包含信号代码的值。 例如,信号SIGABRT
的值是6
,因此预期的退出码将是128
+6
或134
。
也可以设置 process.exitCode
属性:
process.exitCode = 1
当程序结束时,Node.js 会返回该退出码。
当进程完成所有处理后,程序会正常地退出。
使用 Node.js 启动服务器,例如 HTTP 服务器:
const express = require('express')
const app = express()
app.get('/', (req, res) => {
res.send('你好')
})
app.listen(3000, () => console.log('服务器已就绪'))
这个程序永远不会结束。 如果调用 process.exit()
,则任何当前等待中或运行中的请求都会被中止。 这不太友好。
在这种情况下,需要向该命令发送 SIGTERM 信号,并使用进程的信号处理程序进行处理:
注意:
process
不需要 “require”,它是自动可用的。
const express = require('express')
const app = express()
app.get('/', (req, res) => {
res.send('你好')
})
const server = app.listen(3000, () => console.log('服务器已就绪'))
process.on('SIGTERM', () => {
server.close(() => {
console.log('进程已终止')
})
})
什么是信号?信号是一个 POSIX 内部通信系统:发送通知给进程,以告知其发生的事件。
SIGKILL
是告诉进程要立即终止的信号,理想情况下,其行为类似于 process.exit()
。
SIGTERM
是告诉进程要正常终止的信号。它是从进程管理者(如 upstart
或 supervisord
)等发出的信号。
可以从程序内部另一个函数中发送此信号:
process.kill(process.pid, 'SIGTERM')
或从另一个正在运行的 Node.js 程序、或从系统中运行的其他任何的应用程序(能知道要终止的进程的 PID)。
Node.js 的 process
核心模块提供了 env
属性,该属性承载了在启动进程时设置的所有环境变量。
这是访问 NODE_ENV 环境变量的示例,该环境变量默认情况下被设置为 development
。
注意:
process
不需要 “require”,它是自动可用的。
process.env.NODE_ENV // "development"
在脚本运行之前将其设置为 “production”,则可告诉 Node.js 这是生产环境。
可以用相同的方式访问设置的任何自定义的环境变量。
node
命令是用来运行 Node.js 脚本的命令:
node script.js
如果省略文件名,则在 REPL 模式中使用它:
node
注意:REPL 也被称为运行评估打印循环,是一种编程语言环境(主要是控制台窗口),它使用单个表达式作为用户输入,并在执行后将结果返回到控制台。
如果在终端中尝试,则会出现如下:
❯ node
>
该命令会保持空闲状态,并等待输入内容。
提示:如果不确定如何打开终端,则百度“如何打开终端”。
确切地说,REPL 正在等待输入一些 JavaScript 代码。
从简单开始,输入:
> console.log('测试')
测试
undefined
>
第一个值 测试
是告诉控制台要打印的输出,然后得到 undefined
,它是运行 console.log()
的返回值。
现在可以输入一行新的 JavaScript。
REPL 酷的是它是交互式的。
在编写代码时,如果按下 tab
键,则 REPL 会尝试自动补全所写的内容,以匹配已定义或预定义的变量。
尝试输入 JavaScript 类的名称,例如 Number
,添加一个点号并按下 tab
。
REPL 会打印可以在该类上访问的所有属性和方法:
通过输入 global.
并按下 tab
,可以检查可以访问的全局变量:
如果在某些代码之后输入 _
,则会打印最后一次操作的结果。
REPL 有一些特殊的命令,所有这些命令都以点号 .
开头。它们是:
.help
: 显示点命令的帮助。.editor
: 启用编辑器模式,可以轻松地编写多行 JavaScript 代码。当处于此模式时,按下 ctrl-D 可以运行编写的代码。.break
: 当输入多行的表达式时,输入 .break
命令可以中止进一步的输入。相当于按下 ctrl-C。.clear
: 将 REPL 上下文重置为空对象,并清除当前正在输入的任何多行的表达式。.load
: 加载 JavaScript 文件(相对于当前工作目录)。.save
: 将在 REPL 会话中输入的所有内容保存到文件(需指定文件名)。.exit
: 退出 REPL(相当于按下两次 ctrl-C)。如果 REPL 能判断出是否正在输入多行的语句,则无需调用 .editor
。
例如,如果开始输入这样的迭代:
[1, 2, 3].forEach(num => {
然后按下 enter
键,则 REPL 会跳到新的一行并以 3 个点号开头,这表示现在可以继续在该块上工作。
... console.log(num)
... })
如果在行尾输入 .break
,则多行模式会停止并且该语句不会被执行。
当使用以下命令调用 Node.js 应用程序时,可以传入任意数量的参数:
node app.js
参数可以是独立的,也可以具有键和值。
例如:
node app.js joe
或
node app.js name=joe
这会改变在 Node.js 代码中获取参数值的方式。
获取参数值的方法是使用 Node.js 中内置的 process
对象。
它公开了 argv
属性,该属性是一个包含所有命令行调用参数的数组。
第一个参数是 node
命令的完整路径。
第二个参数是正被执行的文件的完整路径。
所有其他的参数从第三个位置开始。
可以使用循环迭代所有的参数(包括 node 路径和文件路径):
process.argv.forEach((val, index) => {
console.log(`${index}: ${val}`)
})
也可以通过创建一个排除了前两个参数的新数组来仅获取其他的参数:
const args = process.argv.slice(2)
如果参数没有索引名称,例如:
node app.js joe
则可以这样访问:
const args = process.argv.slice(2)
args[0]
如果是这种情况:
node app.js name=joe
则 args[0]
是 name=joe
,需要对其进行解析。 最好的方法是使用 minimist
库,该库有助于处理参数:
const args = require('minimist')(process.argv.slice(2))
args['name'] //joe
但是需要在每个参数名称之前使用双破折号:
node app.js --name=joe
Node.js 提供了 console
模块,该模块提供了大量非常有用的与命令行交互的方法。
它基本上与浏览器中的 console
对象相同。
最基础、最常用的方法是 console.log()
,该方法会打印传入到控制台的字符串。
如果传入对象,则它会呈现为字符串。
可以传入多个变量到 console.log
,例如:
const x = 'x'
const y = 'y'
console.log(x, y)
Node.js 会全部打印出来。
也可以通过传入变量和格式说明符来格式化用语。
例如:
console.log('我的%s已经%d岁', '猫', 2)
%s
会格式化变量为字符串%d
会格式化变量为数字%i
会格式化变量为其整数部分%o
会格式化变量为对象例如:
console.log('%o', Number)
console.clear()
会清除控制台(其行为可能取决于所使用的控制台)。
console.count()
是一个便利的方法。
使用以下代码:
const x = 1
const y = 2
const z = 3
console.count(
'x 的值为 ' + x + ' 且已经检查了几次?'
)
console.count(
'x 的值为 ' + x + ' 且已经检查了几次?'
)
console.count(
'y 的值为 ' + y + ' 且已经检查了几次?'
)
count 方法会对打印的字符串的次数进行计数,并在其旁边打印计数:
数苹果和橙子:
const oranges = ['橙子', '橙子']
const apples = ['苹果']
oranges.forEach(fruit => {
console.count(fruit)
})
apples.forEach(fruit => {
console.count(fruit)
})
在某些情况下,打印函数的调用堆栈踪迹很有用,可以回答以下问题:如何到达代码的那一部分?
可以使用 console.trace()
实现:
const function2 = () => console.trace()
const function1 = () => function2()
function1()
这会打印堆栈踪迹。 如果在 Node.js REPL 中尝试此操作,则会打印以下内容:
Trace
at function2 (repl:1:33)
at function1 (repl:1:25)
at repl:1:1
at ContextifyScript.Script.runInThisContext (vm.js:44:33)
at REPLServer.defaultEval (repl.js:239:29)
at bound (domain.js:301:14)
at REPLServer.runBound [as eval] (domain.js:314:12)
at REPLServer.onLine (repl.js:440:10)
at emitOne (events.js:120:20)
at REPLServer.emit (events.js:210:7)
可以使用 time()
和 timeEnd()
轻松地计算函数运行所需的时间:
const doSomething = () => console.log('测试')
const measureDoingSomething = () => {
console.time('doSomething()')
//做点事,并测量所需的时间。
doSomething()
console.timeEnd('doSomething()')
}
measureDoingSomething()
console.log 非常适合在控制台中打印消息。 这就是所谓的标准输出(或称为 stdout
)。
console.error
会打印到 stderr
流。
它不会出现在控制台中,但是会出现在错误日志中。
可以使用转义序列在控制台中为文本的输出着色。 转义序列是一组标识颜色的字符。
例如:
console.log('\x1b[33m%s\x1b[0m', '你好')
可以在 Node.js REPL 中进行尝试,它会打印黄色的 你好
。
当然,这是执行此操作的底层方法。 为控制台输出着色的最简单方法是使用库。 Chalk 是一个这样的库,除了为其着色外,它还有助于其他样式的设置(例如使文本变为粗体、斜体或带下划线)。
可以使用 npm install chalk
进行安装,然后就可以使用它:
const chalk = require('chalk')
console.log(chalk.yellow('你好'))
与尝试记住转义代码相比,使用 chalk.yellow
方便得多,并且代码更具可读性。
更多的用法示例,详见上面的项目链接。
Progress 是一个很棒的软件包,可在控制台中创建进度条。 使用 npm install progress
进行安装。
以下代码段会创建一个 10 步的进度条,每 100 毫秒完成一步。 当进度条结束时,则清除定时器:
const ProgressBar = require('progress')
const bar = new ProgressBar(':bar', { total: 10 })
const timer = setInterval(() => {
bar.tick()
if (bar.complete) {
clearInterval(timer)
}
}, 100)
如何使 Node.js CLI 程序具有交互性?
CLI
- 命令行界面(英语:command-line interface,缩写:CLI)是在图形用户界面得到普及之前使用最为广泛的用户界面,它通常不支持鼠标,用户通过键盘输入指令,计算机接收到指令后,予以执行。也有人称之为字符用户界面(CUI)。
- 通常认为,命令行界面(CLI)没有图形用户界面(GUI)那么方便用户操作。因为,命令行界面的软件通常需要用户记忆操作的命令,但是,由于其本身的特点,命令行界面要较图形用户界面节约计算机系统的资源。在熟记命令的前提下,使用命令行界面往往要较使用图形用户界面的操作速度要快。所以,图形用户界面的操作系统中,都保留着可选的命令行界面。
从版本 7 开始,Node.js 提供了 readline
模块来执行以下操作:每次一行地从可读流(例如 process.stdin
流,在 Node.js 程序执行期间该流就是终端输入)获取输入。
const readline = require('readline').createInterface({
input: process.stdin,
output: process.stdout
})
readline.question(`你叫什么名字?`, name => {
console.log(`你好 ${name}!`)
readline.close()
})
这段代码会询问用户名,当输入了文本并且用户按下回车键时,则会发送问候语。
question()
方法会显示第一个参数(即问题),并等待用户的输入。 当按下回车键时,则它会调用回调函数。
在此回调函数中,关闭了 readline 接口。
readline
还提供了其他几个方法,详见上面的文档链接。
如果需要密码,则最好不要回显密码,而是显示 *
符号。
最简单的方式是使用 readline-sync
软件包,其在 API 方面非常相似。
Inquirer.js 软件包则提供了更完整、更抽象的解决方案。
可以使用 npm install inquirer
进行安装,然后复用上面的代码如下:
const inquirer = require('inquirer')
var questions = [
{
type: 'input',
name: 'name',
message: "你叫什么名字?"
}
]
inquirer.prompt(questions).then(answers => {
console.log(`你好 ${answers['name']}!`)
})
Inquirer.js 可以执行许多操作,例如询问多项选择、展示单选按钮、确认等。
所有的可选方案都值得了解,尤其是 Node.js 提供的内置方案,但是如果打算将 CLI 输入提升到更高的水平,则 Inquirer.js 是更优的选择。
Node.js 具有内置的模块系统。
Node.js 文件可以导入其他 Node.js 文件公开的功能。
当想要导入某些东西时,使用
const library = require('./library')
可以导入存在于当前文件夹中的 library.js
文件中公开的功能。
在此文件中,必须先公开功能,然后其他文件才能将其导入。
默认情况下,文件中定义的任何其他对象或变量都是私有的,不会公开给外界。
这就是 module
系统提供的 module.exports
API 可以做的事。
当将对象或函数赋值为新的 exports
属性时,这就是要被公开的内容,因此,可以将其导入应用程序的其他部分或其他应用程序中。
可以通过两种方式进行操作。
第一种方式是将对象赋值给 module.exports
(这是模块系统提供的对象),这会使文件只导出该对象:
const car = {
brand: 'Ford',
model: 'Fiesta'
}
module.exports = car
//在另一个文件中
const car = require('./car')
第二种方式是将要导出的对象添加为 exports
的属性。这种方式可以导出多个对象、函数或数据:
const car = {
brand: 'Ford',
model: 'Fiesta'
}
exports.car = car
或直接
exports.car = {
brand: 'Ford',
model: 'Fiesta'
}
在另一个文件中,则通过引用导入的属性来使用它:
const items = require('./items')
items.car
或
const car = require('./items').car
module.exports
和 export
之间有什么区别?
前者公开了它指向的对象。 后者公开了它指向的对象的属性。