Professional Documents
Culture Documents
TypeScript■React■Node.js■webpack
■ Docker Frank Zammetti
Visit to download the full and correct content document:
https://ebookmass.com/product/%e7%8e%b0%e4%bb%a3%e5%85%a8%e6%a0%8
8%e5%bc%80%e5%8f%91-%e4%bd%bf%e7%94%a8-typescript%e3%80%81react
%e3%80%81node-js%e3%80%81webpack-%e5%92%8c-docker-frank-zammetti/
现代全栈开发 使用 TypeScript、
React、Node.js、webpack 和
Docker
封面
捐赠
捐赠支持译者,翻译更多书籍
微信
支付宝
现代全栈开发
弗兰克·扎梅蒂
美国宾夕法尼亚州波茨敦
在本书中,我们将构建两个完整的应用程序,它们将以实际的方式演示我
们将在此过程中讨论的所有概念。这不仅仅是简单的、人为的代码,而是
两个功能强大且有用的完整应用程序(甚至很有趣,因为其中一个是游
戏,它将为您提供一种全新的编码方式)。当我们这样做时,您将深入了
解它们的想法,它们的设计和架构,因此您可以全面了解构建这两个应用
程序所涉及的内容。你甚至会在这里和那里得到一些关于我遇到的问题以
及我如何解决这些问题的笔记,这些事情几乎肯定会帮助你在你继续进入
自己的项目时实现你的目标。
首先,我们将看看服务器端最常见的(虽然不是唯一的,正如您将了解的
那样!)的范围。请记住,我们在这里谈论的是“全栈”开发,这意味着您将
学习编码客户端以及它们使用的服务器代码,以形成一个有凝聚力的整体
应用程序。在本章中,我们将首先介绍两个非常流行的服务器开发工具:
Node.js和NPM。
JavaScript运行时和构建(大部分)服务器
Ryan nodejs的创建者。Ryan于2009年在欧洲JSConf上首次展示了Node,
并很快被公认为潜在的游戏规则改变者,他的演讲获得了起立鼓掌(我认
为Ryan通常也是一位出色的演讲者)。
Node 是一个主要(但不完全)运行服务器端代码的平台,具有高性能,能
够轻松处理大型请求负载。它基于当今地球上使用最广泛的语言:
JavaScript。它很容易上手和理解,但它为开发人员带来了巨大的力量,这
在很大程度上要归功于其异步和事件驱动的编程模型。在 Node 中,您所
做的几乎所有事情都是非阻塞的,这意味着代码不会阻止其他请求线程的
处理。大多数类型的 I/O 是阻塞发挥作用最多的地方,在 Node 中都是异
步的,无论是网络调用、文件系统调用还是数据库调用。这一点,再加上
为了执行代码,Node使用谷歌流行且高度调优的V8 JavaScript引擎,与
Chrome浏览器的引擎相同,使其性能非常高,能够处理大量的请求负载
(假设你作为开发人员当然不会搞砸事情!)。
还值得注意的是,尽管听起来很奇怪,但Node是单线程的。乍一看,这似
乎是一个性能瓶颈,但实际上,这是一个净好处,因为它避免了上下文切
换。但是,这有点用词不当,因为更正确的说法是 Node 是事件驱动的,
并且是具有后台工作者的单线程。当你发出某种类型的 I/O 请求时,Node
通常会为此生成一个新线程。但是,当它完成工作时,单个事件驱动的线
程会继续执行您的代码。所有这些都通过事件队列机制进行管理,以便在
响应返回时,这些 I/O 操作的回调将触发,并返回到该单个线程上。所有
这些都意味着线程之间没有(或至少最少)上下文切换,而且单个线程永
远不会闲置(当然,除非实际上没有工作要做),所以你最终会得到我提
到的净积极的好处。
请注意,在后面的章节中,您将看到node并非特定于等式的服务器端,事
实上,您并不总是使用 node 构建应用程序;有时,您可以使用它在您自己
的开发计算机上安装和执行用于各种目的的工具。
作为 Node 开发人员,这些技术细节都不是特别重要,但它产生的性能使
得如此多的重要参与者和网站都以某种方式采用 Node 也就不足为奇了。
这些不是我们正在谈论的小公司,我们谈论的是你无疑知道的名字,包括
DuckDuckGo,eBay,LinkedIn,Microsoft,Netflix,PayPal,沃尔玛和雅
虎,仅举几个例子。这些是需要顶级性能的大型企业,而Node可以实现这
一承诺(再次警告,作为开发人员,您不要把事情搞砸,因为这总是可能
的)。
Node 是一流的运行时环境,这意味着您可以执行诸如与本地文件系统交
互、访问关系数据库、调用远程系统等操作。过去,您必须使用“适当的”运
行时(例如 Java 或 .Net)来完成所有这些操作;JavaScript不是这个领域的
参与者。对于 Node,这不再是真的。它不仅可以在性能上竞争,还可以在
为开发人员提供的功能方面竞争。如果你能想到它,你很可能可以用 Node
做到这一点,而 JavaScript 并不总是如此。
需要明确的是,Node本身并不是一个服务器。你不能只是启动 Node 并从
Web 浏览器向它发出 HTTP 请求。默认情况下,它不会执行任何操作来响
应您的请求。不,要将 Node 用作服务器,您必须编写一些(如您所见,
简单明了)代码,然后在 Node “运行时”上运行。是的,你可以有效地编写
自己的Web服务器和应用程序服务器,ftp等服务器。作为开发人员,这是
一件非常奇怪的事情——我们通常会对这样的事情应用“不要重新发明轮
子”的口头禅,并从数百个现有选项中取出一个。另外,编写这样的服务器
听起来(可能实际上是)对大多数开发人员来说都是令人生畏的,这是有
充分理由的!可以肯定的是,如果您尝试用许多其他语言从头开始编写
Web服务器,那绝对是这样,特别是如果您希望它不仅仅提供静态内容文
件。
请注意,正如你将看到的,react,Webpack和typeScript,三件事是本书的
主要焦点(docker是简要提及),使用node来运行和/或安装(好吧,如果
我们准确的话,npM被用来安装它们,但我们稍后会谈到npM)。这些是工
具,而不是服务器,这是重点:Node的用处远不止创建服务器!
Node允许您在客户端和服务器上使用相同的语言和知识,这在以前很难完
成。事实上,除了Java和一些Microsoft技术(如果你好奇的话,请参阅
Blazor项目,它试图用C#做同样的事情),在Node出现之前,从来没有真
正有机会这样做。这是一个非常有吸引力的机会。
Node的另一个关键方面是项目的驱动设计目标,即将其核心功能保持在绝
对最低限度,并通过API(以JavaScript模块的形式)提供扩展功能,您可
以根据需要进行选择。Node尽可能地避开你,只允许你在需要时引入你真
正需要的复杂性。Node 附带了广泛的此类模块库,但每个模块都必须导入
到您的代码中,然后您可以根据需要引入数千个其他模块,随着本书的进
展,您将看到其中一些模块。
安装node
首先,只需记住一个地址:
http://nodejs.org
下载node如图:
通常,我会告诉您安装可用的最新版本,但在这种情况下,最好选择长期
支持 (LTS) 版本,因为它们往往更稳定。
jack@jack:~$ node
Welcome to Node.js v20.5.1.
Type ".help" for more information.
> console.log("hello world")
hello world
执行test.js
node test.js
Node的包管理器NPM
NPM,代表Node Package Manager,是一个与Node一起安装的配套应用程
序(尽管它是单独开发的,可以按照与Node不同的时间表进行更新)。有
了它,您可以从中央仓库(或私有存储库,如果有的话)下载可重用的
JavaScript 模块(以及它们可能需要的任何支持内容)。您可以在以下位置
找到的中央存储库
https://www.npmjs.com/
您可以通过网络浏览器访问它并查看所有可用的软件包,这使得找到您需
要的东西变得容易。
如果你这样做,你会发现已经创建了一个叫做node-modules的目录,里面
会有很多......好吧,很多东西你通常不需要太担心!简而言之,不过,构成
Express 模块的所有代码(现在无关紧要,但它是一个 JavaScript 模块,或
者如果你愿意的话,可以打包,我们将在 MailBag 应用程序中使用它,但是
我们将在适当的时候进入该应用程序,在此之前我们还有很多内容要介
绍,所以现在只需说它是我们将使用前六章中讨论的技术构建的两个应用
程序之一),再加上Express本身所依赖的任何模块(以及它们可能依赖的
任何模块, 等等)。NPM 负责为您获取所有这些依赖项。您还会注意到已
经创建了一个名为 package-lock.json 的文件,出于我们在这里的目的,您
无需担心这一点,除了知道不要删除它,因为 NPM 需要它来完成它的工
作。
更多 NPM 命令
除了安装之外,还有许多其他 NPM 命令,但您可能大多数时候只会使用子
集。例如,要了解项目中安装了哪些模块,可以发出以下命令:
npm ls
如果要查看全局缓存中安装了什么,可以执行
npm -g ls
更新模块
npm update express
只需提供要更新的模块的名称,NPM 就会处理它,更新到最新的可用版
本。如果您不提供软件包名称,则 NPM 将尽职尽责地更新所有软件包。是
的,您可以在其上放置 -g 以针对全局缓存。
当然,您也可以卸载软件包:
npm uninstall express
初始化新的 NPM/node项目
现在,在所有这些中,我确实跳过了一个步骤,这显然是可选的,但实际
上是典型的,那就是初始化一个新项目。对于大多数 Node/NPM 项目,您
还将在项目的根目录中拥有一个名为 package.json 的文件。此文件是项目
清单文件,它向 NPM(和 Node,至少间接)提供有关项目执行某些操作
所需的元数据信息。它会告诉 NPM 如果还没有安装什么模块,它会告诉它
们要安装什么(这使得将项目交给另一个开发人员非常容易!它还将包含
项目的名称和版本、其主入口点以及许多其他信息(其中大部分是可选
的,但我们将在下一章中详细介绍)。
虽然您可以手动编写此文件,甚至可以完全没有它,但拥有它是一个好主
意,最好让 NPM 为您创建它,您可以通过执行以下命令来执行此操作:
npm init
或者
npm init -y
如果您正在继续操作,请确保您从中运行此目录为空(删除node_modules
和package-lock.json(如果存在),这两者都将在后面描述)。这将触发一
个交互式过程,引导您完成 package.json 文件的创建
这将引导您完成一个交互式的分步过程,您可以在其中输入与您的项目相
关的任何信息(如果有)。您只需在每个选项上按 Enter 即可使用默认值
(或空白值,以适用者为准),也可以输入适合您的值。不过,出于我们
在这里的目的,您确实可以并且应该简单地在过程中的每个提示符上按
Enter 键。
添加依赖关系
现在,假设您想将我提到的 Express 包添加到此项目中。有两种选择。首
先,您可以自己编辑package.json,添加以下元素:
"dependencies": {
"express": "^4.16.1"
}
但是,这样做不会有任何影响。模块未安装,为此,您现在必须发出一个命
令:
npm install
另一种方式是使用npm安装模块
这一切很重要的原因是,现在,假设你想把这个项目交给别人。您通常不
希望向他们提供项目所需的所有依赖项、node_modules的所有内容,如果
没有其他原因,该目录可以迅速增长到很大。相反,他们可以使用
package.json 文件重新创建它,只需执行以下操作:
npm install
package.json文件内某些符号的语义
最重要的是,波浪号 (~)、插入符号 (^) 和星号 (*) 字符具有特殊
含义。
注 意 使 用 npm install 命 令 时 , 可 以 在 软 件 包 名 称 后 添 加
@major.minor.patch,以使用前面文本中描述的所有 Semver 规则指定要安
装的版本。
第一个node web服务器
既然您对Node和NPM有了一些了解,至少在最基本的方面,让我们写一些
实际代码,除了前面显示的简单示例之外,也就是说,并使用Node运行
它。
server.js
require("http").createServer((request, response) => {
response.end("Hello World!");
}).listen(3000);
node server.js
在package.json
添加
"start": "node src/server.js"
npm start
浏览器打开:
显然,这是一个简单的例子,但它应该足够好地理解基本思想。但是,在
代码级别,这个简单示例中究竟发生了什么?碰巧的是,相当多,其中大
部分是 Node 工作方式的关键。
第一个概念是导入模块的想法。在示例代码中,http 是一个模块。这是
Node 开箱即用的核心 Node 模块之一,因此,它直接编译到 Node 二进制
文件中。因此,您不会在它的 Node 安装目录中找到单独的 JavaScript 文
件。所有 Node 核心模块都是如此,您可以在 Node 站点上的 Node 文档中
找到所有这些模块。
注意 我们将在下一章中介绍一些更常用的模块。
您也可以通过将其他.js文件添加到项目中并 require 它们来创建自己的模
块。这涉及到更多,讨论范围和导出等问题,我们将及时讨论所有这些问
题。但是现在,我想提一下,至少以防您真的对 Node 完全陌生,以便如
果您想跳到前面,您可以在 Node 文档中找到适当的部分来描述这一点。
奖金示例
让我们把这个 Web 服务器代码更进一步,以提供更多的 NPM 优点,只是
为了使用到目前为止讨论的几乎所有内容。
首先,让我们向项目添加一个依赖项。我们将使用命名不是非常有创意但
非常准确的请求模块,它将为我们的服务器提供一个基本的 HTTP 客户
端,供它用于进行远程调用:
npm install request --save
server_time.js
require("http").createServer((inRequest, inResponse) => {
const requestModule = require("request");
requestModule(
"https://www.baidu.com",
function (inErr, inResp, inBody) {
inResponse.end(
`Hello from my first Node Web server: ${inBody}`
);
}
);
}).listen(3000);
我们现在要做的是首先导入请求模块并为其命名 requestModule(只是为了
帮助消除它与传递给回调函数的 inRequest 对象的歧义)。此模块的 API
很简单:将 URL 传递给构造函数,加上一个回调,然后将调用该 URL,并
且当对该调用的响应返回时,将执行提供的回调。我们得到的是百度网页
数据,然后将其写入返回到浏览器的响应中。
总结
在本章中,我们研究了 Node 和 NPM,并讨论了它们使用的基础知识。但
是,因为 Node 和 NPM 在概念上非常简单,所以总的来说,这些基础知识
是编写实际应用程序所需的全部内容。您现在知道如何执行 JavaScript 代
码,如何创建 NPM 项目以及如何添加依赖项。您了解全局缓存和本地(项
目)缓存之间的区别,甚至知道如何编写基本的Web服务器!
在下一章中,我们将继续更详细地研究这两个工具,使用它们进行一些稍
微更高级的东西,以扩展我们将在本书后面构建两个应用程序的基础。
第二章,高级node和npm
NPM:更多关于package.json
在上一章中,您学习了如何使用 NPM 初始化项目,它会生成一个
package.json 文件。我当时说它的大部分内容都是可选的,这绝对是
真的,但让我们谈谈该文件中可用的内容,讨论每个可用的键(记住
它只是一个 JSON 文件,这意味着它正在定义一个 JavaScript 对象,
它有键或属性)
author 作者,由具有三个潜在属性的对象定义:名称、电子邮件和
URL(其中名称是必需的,电子邮件和 URL 都是可选的)。
bin – 某些包需要安装可执行文件才能完成其工作并添加到路径中。
bundledDependencies – 某些项目需要在本地或通过单个下载保留
NPM 包。对于这些,此元素允许您指定一个包名称数组,这些名称将
在发布包时与包捆绑在一起。
description – 描述包的自由格式字符串。
devDependencies – 同样,我在上一章中提到过的一个,它与依赖项
相同,但它命名了仅在开发过程中需要的包。
directories – 此元素允许您描述包的结构、库组件二进制内容的位
置、手册页、Markdown 文档、示例和测试。有关此内容的详细信
息,请参阅 Common JS 包规范。
homepage – 如果您的项目有一个网站,则可以使用此元素指定其主
页的 URL。
keywords – 关键字元素是任意字符串数组,可用于帮助人们找到您的
包。
icense – 许可证元素的值是发布包时使用的许可证。
man – 使用此元素,您可以指定单个文件或文件名数组,以便 Linux
man 程序为您的软件包显示。
main – 这 是 包 的 主 要 入 口 点 。 例 如 , 如 果 您 的 软 件 包 名 为
super_duper_cool_package,则用户希望在安装后能够执行 require
(“super_duper_cool_package”)。若要允许此操作,main 元素必须
指向导出包的主导出对象的文件。
os – 就像 cpu 一样,如果您的软件包仅适用于某些操作系统,那么您
可以在此元素中拥有一个字符串数组来命名它运行的字符串。
peerDependencies – 有时,一个包将充当其他包的插件,因此您需要
一种方法来定义您的软件包与哪些其他软件包兼容。
peerDependencies 元素允许您执行此操作。
NPM:其他命令
虽然您已经看到了基本的 NPM 命令,但让我们谈谈您可能发现自己
需要不时使用的更多命令。与上一节一样,这不是一个深入的参考指
南,也不是每个可用 NPM 命令的列表。但是,在上一章中显示的内
容和本节的内容之间,我相信您将在大部分时间接触到大约 95% 的
命令(随着我们在后面的章节中的进展,可能会再显示一两个命
令)。
审核包安全性
可悲的现实是,有时,您使用的软件包会被发现存在安全漏洞,就像
您使用的任何其他软件一样。但是,意识到这一点,NPM 团队构建了
一个有用的命令来处理这个问题:
npm audit
运 行 此 命 令 将 扫 描 您 的 package.json 文 件 ( 如 果 使 用 -g 或 全 局
包),并将依赖项列表提交到默认 NPM 仓库,请求报告其中的任何
已知漏洞。此报告还将包含有关如何修正的信息。但是,如果您想要
快速答案,请执行以下命令:
npm audit fix
或者,如果您更喜欢纯文本
npm audit --readable
最后,如果你想看看npm审计修复会做什么,但没有真正做到
它,你可以使用
npm audit fix --dry-run
重复数据删除和修剪
你经常看到的关于NPM和Node的抱怨之一是node_modules目录的大
小可能会迅速膨胀。幸运的是,您很少需要深入研究它,但这仍然是
磁盘空间的问题,虽然现在磁盘空间很便宜,但浪费仍然不时髦!
NPM 提供了两个命令来处理这种情况,首先是
npm dedup
此命令将检查已安装的软件包并查找可能不再需要的任何软件包。这
通常发生在卸载软件包时,尤其是当您在某个时候执行了重复数据删
除时。任何未在父包的依赖项列表中列出的包都被视为“无关紧要”,
因此可能会被修剪。
注意 在常规操作中,只要你安装东西,修剪就会自动运行,所以你不
需要手动运行它,但有时,俗话说,便便会发生,所以无论如何了解
它都是很好的。
不通过浏览器查找/搜索包
通过 Web 浏览器浏览中央 NPM 注册表以查找感兴趣的包很容易,但
这不是您唯一的选择。NPM 本身提供了搜索功能,如图 2-1 所示。
npm search express --registry https://registry.npmjs.com/
更新软件包
npm update
更新所有包
是的,就是这样!NPM 将关闭并将所有软件包更新到最新版本,尊重
您的 SemVer 设置。当然,您也可以在其中粘贴 -g 以更新全局包。
发布/取消发布包
首先注册:
Another random document with
no related content on Scribd:
XIV
SUURI ONNETTOMUUS.
»Kuka tuo mies on, Gyuri»? kysyi kreivi Kantássy, joka myöskin oli
katsellut talonpoikaa jonkun aikaa ja ihaillut aito unkarilaisen tapaan
tuota hyvän hevosen selässä olevaa mainiota ratsastajaa.
HYVITYS.
Sillä aikaa oli András melkein jo saapunut kylään. Hän tiesi yhtä
hyvin kuin kreivikin, että illan hävitys oli ihmisten eikä Jumalan
toimeenpanema, ja aavisti, että noissa taloissa asuvat taikauskoiset
säikähtyneet raukat olivat tehneet tuo raukkamaisen teon ja
aiheuttaneet rikollisessa hulluudessaan tuon peloittavan
onnettomuuden, jonka estämisestä he nyt äreästi ja uhmaavasti
kokonaan kieltäytyivät.
»Älkää puhuko heille enää mitään, isä», sanoi äkkiä muudan ääni
pimeydestä. »He eivät ansaitse, että teidän ystävälliset silmänne
katselevat heidän ilkeitä kasvojaan sekuntiakaan enää».
»Niin onkin, mies, mutta ei puoleksikaan niin ilkeä kuin tuo synkkä
ja murhaava teko, jonka teidän rikolliset kätenne ovat panneet
toimeen tänä iltana. Peräytykää heti»! lisäsi hän, kun pari
talonpoikaa lähimmästä ryhmästä aikoi lähestyä häntä. »Kiellän teitä
puhumasta minulle, lähestymästä minua ja laskemasta kättänne
Csillagin lautasille, sillä teidän saastainen kosketuksenne voi sen
tappaa».