图书前言

前言

当前,几乎所有的编程开发岗位都要求对全栈开发有基本的认识,但如果你是初学者,可能很难找到合适的入门途径来理解这个庞大的主题。你甚至可能不知道“全栈开发”这个术语的具体含义。

简而言之,全栈 Web 开发就是利用 JavaScript 及众多框架来构建完整的网页应用。全栈开发不仅要求开发者精通前端和后端开发的传统技术,还需要能够编写中间件和不同类型的应用接口。

最终,技能全面的全栈开发者不仅能够管理数据库,还应具备诸如编写自动化测试和独立部署代码的专业技能。为此,开发者需要熟悉 HTML、CSS 和 JavaScript,以及这些技术的类型化版本 TypeScript。想要快速了解这些术语,可以参考导读中“全栈应用的组成部分”一节的内容。

如果你觉得全栈开发过于庞杂,那么本书正是为你准备的。本书将为读者逐一剖析现代应用的各个组件,并教授如何运用最流行的技术创建组件。

目标读者

本书主要面向两类读者群体。首先是希望借助全栈开发技能提升职业水平的资深前端或后端工程师,其次是对 Web 开发感兴趣且处于入门阶段的开发新手。

本书虽然涵盖了许多技术的基础知识,但假定读者已经对 HTML、CSS、JavaScript及 Web 应用的客户端/服务器架构有所了解。如果你需要复习这些基础知识,推荐阅读Sam Taylor 所著的 The Coding Workbook(No Starch Press,2020 年),这本书将指导你如何使用 HTML 和 CSS 构建网站。同时,为了提升 CSS 技能,可以参阅 Peter Gasston 的 The Book of CSS3, 2nd edition(No Starch Press,2014 年)。对于 JavaScript 的学习,我推荐 Nick Morgan 的 JavaScript Crash Course(No Starch Press,2024 年),这是一本为初学者设计的JavaScript 快速入门图书,以及 Marijn Haverbeke 的 Eloquent JavaScript, 3rd edition(No Starch Press,2018 年),该书深入探讨了 JavaScript 的各个方面。

内容提要

本书分为两篇。第一篇涵盖了第 1 章至第 10 章的内容,向读者介绍构建现代技术栈的关键组件。每章深入探讨一项具体技术,并指出全栈开发者在掌握该技术时需要了解的核心知识点。书中的练习旨在激励读者从第 1 章起就开始着手编写应用代码。

第 1 章“Node.js”将引导你进入 Node.js 及其生态,这使得 JavaScript 代码得以在浏览器之外执行。接着,你将利用 Node.js 和 Express.js 框架,通过 JavaScript 来搭建一个简单的 Web 服务器。本章旨在为你打下基础,了解如何使用 Node.js 来开发服务端应用。

第 2 章“现代 JavaScript”着重介绍全栈开发者所需的最新 JavaScript 语法,涵盖使用模块编写可维护代码包的方法。本章将深入讲解变量和常量的声明方式、箭头函数的运用,以及处理异步代码的多种技巧。你将应用这些知识点来优化和重构你的 JavaScript 服务器代码。

第 3 章“TypeScript”向读者介绍 TypeScript,它是一种 JavaScript 的扩展语言,并阐述现代全栈开发中使用 TypeScript 的优势。本章将讨论 JavaScript 的局限性和潜在问题,以及如何利用 TypeScript 的类型推断功能来增强代码的健壮性。你将学习如何通过添加类型注解、自定义类型定义和接口来改进你的 JavaScript 服务器代码,从而完成本章的学习。

第 4 章“React”深入探讨 React 这一在构建用户界面组件时广泛使用的库。本章将介绍 React 组件如何助力全栈开发流程,并教你如何利用 JSX 语法、虚拟 DOM 机制以及React 的钩子(hooks)功能。学完这些知识后,你将进一步把 React 应用到你的 Express.js服务器上,为其添加一个动态且即时响应的用户界面。

第 5 章“Next.js”重点介绍基于 React 的前沿 Web 应用框架 Next.js。你将使用Next.js 的基于文件的路由创建页面和自定义 API 路由,然后学习在框架内以不同方式渲染页面。最后,作为练习,你将把 Express.js 服务器迁移到 Next.js。

第 6 章“REST 和 GraphQL API”将深入探讨 API 的相关知识,包括它们的定义、重要性以及在全栈 Web 开发中的运用。还会探索两种类型的 API:REST 和 GraphQL。你将通过在 Next.js 全栈应用中添加 Apollo GraphQL 服务器来完成本章的学习。

第 7 章“MongoDB 和 Mongoose”讨论传统关系型数据库与非关系型数据库(如MongoDB)之间的差异。你将把 Mongoose 对象数据建模工具添加到你的技术栈中,以简化与数据库的协作。然后,你会通过 GraphQL API 连接到你自己的 MongoDB 数据库。

第 8 章“使用 Jest 框架进行测试”解释自动化测试和测试驱动开发对全栈开发的重要性。我们会探讨不同类型的测试、常见的测试模式,以及测试替身、存根、假对象和模拟的概念。最后,你将使用 Jest 框架为你的 Next.js 应用添加一些基本的快照测试。

第 9 章“OAuth 授权”介绍认证与授权的概念,以及全栈开发者如何利用 OAuth 协议与第三方服务的结合来执行这些任务。我们将深入探讨 OAuth 授权流程及其组成部分。为了更深入地理解每一步,你将通过命令行体验一次完整的 OAuth 交互过程。

第 10 章“使用 Docker 进行容器化”向读者介绍如何使用 Docker 部署应用。涵盖微服务架构的概念,以及涵盖 Docker 生态中所有相关组件:宿主机、Docker 守护进程、Dockerfile、镜像、容器、卷和 Docker Compose。你将通过把自己的应用拆分成自包含的微服务来完成本章的学习。

在第二篇中,你将运用新学的知识来构建一个运用第一篇介绍的概念、工具和框架的Web 应用。Food Finder 应用是一个位置搜索服务,允许用户使用其 GitHub 账户登录,并维护一个想要访问的地方的愿望清单。

第 11 章“设置 Docker 环境”教你使用你所掌握的 Docker 和容器化的知识,给你的Food Finder 应用创建基础,搭建你的开发环境。你会通过 Docker Compose 将应用开发与你的本地系统进行解耦,然后添加一个 MongoDB 服务器作为它的服务。

第 12 章“构建中间件”教你创建 Food Finder 应用中间件的第一部分。在这里,你将把 Mongoose 连接到 MongoDB 服务,并创建其模式、模型、服务和自定义类型。有了这些组件,你能够在数据库中创建、读取、更新和删除数据。

第 13 章“构建 GraphQL API”教你运用你所掌握的 GraphQL 的知识,为你的 Food Finder 应用添加一个 Apollo GraphQL 服务器,然后实现一个公共的 GraphQL API。你能够通过 Apollo 沙盒在你的 MongoDB 服务器上使用 GraphQL 读取和更新数据。

第 14 章“构建前端界面”教你使用 React 组件和 Next.js 框架来构建 Food Finder 应用的前端。到这里,你将会实现一个完整的现代全栈应用,它通过你的自定义中间件从数据库读取数据,并将数据渲染到应用的前端。

第 15 章“添加 OAuth 认证”教你向你的应用添加 OAuth 流程,以便访客通过登录来维护个人的位置愿望清单。你会使用 Auth.js 的 next-auth 包来使用 GitHub 添加登录选项。

第 16 章“在 Docker 中运行自动化测试”教你使用 Jest 设置自动化快照测试,并配置一个新的服务来自动运行这些测试。

然后,在附录中,你将获得有关 TypeScript 编译器选项和最常用的 Jest 匹配器的详细信息。此外,你将运用你新获得的知识来探索和理解 Next.js 的现代应用目录方法。

附录 A“TypeScript 编译器选项”展示最常见的 TypeScript 编译器(TSC)选项,让你可以根据自己的喜好定制自己的 TypeScript 项目。

附录 B“Next.js 应用目录”探讨 Next.js 在版本 13 中引入的使用 app 目录的新的路由模式。然后,你可以选择在新的项目中使用传统的页面方法(第 5 章已覆盖)或现代的app 目录。

附录 C“通用匹配器”展示使用 Jest 和 Jest DOM 对应用进行测试时最常用的匹配器。

全栈应用的组成部分

本书将带领读者深入探讨应用的各个组成部分。在下文中,我们将提供一个速成课程,阐释“前端”(frontend)、“中间件”(middleware)和“后端”(backend)这些术语在应用开发中的具体含义和作用。

前端

前端是用户直接交互的网站或 Web 应用部分,通常在用户的设备上通过 Web 浏览器运行。它是用户与网站内容和功能直接接触的界面。

前端开发者专注于用户的参与度、体验和界面。他们依赖于 HTML 来构建网站界面的元素,CSS 用于样式设计,JavaScript 用于用户交互,还会借助像 Next.js 这样的框架来整合一切。

中间件

中间件是连接应用前端和后端的桥梁,负责处理诸如与第三方服务集成、数据传输和更新等任务。你可以把它想象成公司里负责协调各项工作的员工。

作为全栈开发者,我们经常编写中间件来为应用进行路由,这包括为特定的 URL 提供正确的数据、处理数据库连接和执行授权。然后,中间件的另一部分会检查用户是否已登录,如果是,则决定显示哪些个人数据。与此同时,中间件的第三部分整合这些数据流中的信息,并用正确的 HTML 响应服务器的请求。

全栈应用中间件的一个重要组成部分是其 API 层,它负责暴露应用的 API。一般来说,API 是用于连接两台计算机的代码,通常允许前端代码(或第三方)访问应用的后端。在以 JavaScript 为主的开发中,REST 和 GraphQL 是两种主要的架构框架,用于创建API,这两种框架在第 6 章中有详细介绍。

你可以使用任何编程语言编写中间件。大多数全栈开发者使用现代 JavaScript 或TypeScript,但他们也可以选择 PHP、Ruby 或 Go 等其他语言。

后端

后端是 Web 应用的幕后部分。在一个以 JavaScript 为主的应用中,后端通常在服务器上运行,常见的框架是 Express.js,尽管其他人可能会使用 Apache 或 NGINX。你可以把它想象成 Web 应用的“后台支持”。

具体来说,后端负责处理所有与应用数据相关的操作。它对数据库中的数据执行创建、读取、更新和删除(CRUD)操作,并通过中间件的 API 层将用户请求的数据集返回给前端。中间件会将这些搜索结果与其他相关信息结合起来。然后前端会渲染出用户看到的搜索结果页面。

后端开发可以使用任何编程语言来完成。全栈开发者通常选择现代 JavaScript 或TypeScript。其他选项包括 PHP、Ruby、Elixir、Python、Java,以及像 Symfony、Ruby on Rails、Phoenix 和 Django 这样的框架。

JavaScript 历史与全栈开发

每位开发者都应了解所使用工具的背景。在我们着手开发之前,不妨先回顾一下有关全栈开发的历史。

全栈开发者这一角色是随着 JavaScript 的发展而逐渐形成的,JavaScript 最初仅作为一种在用户浏览器中运行的脚本语言。开发者利用它为网站添加诸如手风琴式菜单、弹出菜单和覆盖层等元素,这些元素能够即时响应用户操作,不需要向应用服务器发送请求。

直到 21 世纪头十年的末期,大多数 JavaScript 库的主要功能是为不同浏览器的特定问题提供统一的解决方案。当时,JavaScript 引擎的运行速度通常较慢,尤其是在与HTML 进行交互、更新或修改时。因此,JavaScript 在前端开发者中被视为一种不太稳定的脚本语言,而后端开发者对其兴趣不大。

尽管有多个项目试图推动 JavaScript 在后端的使用,但在 2009 年 Node.js 发布之前,这些尝试均未获得广泛关注。Node.js(在第 1 章中有详细介绍)是一个用于后端开发的JavaScript 工具。随后,Node.js 包管理器 npm 完善了全栈 JavaScript 开发所需要的生态。

这个生态涵盖了众多 JavaScript 库,用于操作数据库、构建用户界面以及编写服务器端代码(本书将探讨其中许多库)。这些新工具使开发者能够在客户端和服务器端可靠地使用 JavaScript。特别值得一提的是,Google 在 2010 年发布了 Angular 框架,而 Meta(当时名为 Facebook)在 2013 年发布了 React。这些互联网巨头对 JavaScript 工具的投入,使得全栈 Web 开发成为一个备受青睐的岗位。