Express/Node 介绍
在本篇关于 Express 的第一篇文章中,我们将回答“什么是 Node?”和“什么是 Express?”这两个问题,并向您概述 Express Web 框架的独特之处。我们将列出主要功能,并向您展示 Express 应用程序的一些主要组成部分(尽管此时您还没有可用于测试的开发环境)。
| 预备知识 | 对服务器端网站编程,特别是网站中客户端-服务器交互的机制有一个大致的了解。 |
|---|---|
| 目标 | 熟悉 Express 是什么,它如何与 Node 协同工作,它提供了哪些功能,以及 Express 应用程序的主要构建模块。 |
Node 简介
Node(更正式的名称是 Node.js)是一个开源、跨平台的运行时环境,允许开发者使用 JavaScript 创建各种服务器端工具和应用程序。该运行时旨在用于浏览器上下文之外(即直接在计算机或服务器操作系统上运行)。因此,该环境省略了浏览器特定的 JavaScript API,并增加了对更传统的操作系统 API 的支持,包括 HTTP 和文件系统库。
从 Web 服务器开发的角度来看,Node 具有许多优点:
- 卓越的性能!Node 旨在优化 Web 应用程序的吞吐量和可伸缩性,是许多常见 Web 开发问题(例如,实时 Web 应用程序)的良好解决方案。
- 代码是用“普通 JavaScript”编写的,这意味着在编写客户端和服务器端代码时,花费在处理语言“上下文切换”上的时间更少。
- JavaScript 是一种相对较新的编程语言,与传统 Web 服务器语言(例如 Python、PHP 等)相比,它受益于语言设计的改进。许多其他新的流行语言编译/转换为 JavaScript,因此您也可以使用 TypeScript、CoffeeScript、ClojureScript、Scala、LiveScript 等。
- Node 包管理器(npm)提供了对数十万个可重用包的访问。它还具有一流的依赖项解析功能,并且还可以用于自动化大多数构建工具链。
- Node.js 是可移植的。它可在 Microsoft Windows、macOS、Linux、Solaris、FreeBSD、OpenBSD、WebOS 和 NonStop OS 上使用。此外,它受到许多 Web 主机提供商的良好支持,这些提供商通常为托管 Node 站点提供特定的基础设施和文档。
- 它拥有一个非常活跃的第三方生态系统和开发者社区,许多人都乐于提供帮助。
您可以使用 Node.js 结合 Node HTTP 包创建一个简单的 Web 服务器。
Hello Node.js
以下示例创建了一个 Web 服务器,它监听 URL http://127.0.0.1:8000/ 上的任何 HTTP 请求——当收到请求时,脚本将返回字符串:“Hello World”。如果您已经安装了 Node,可以按照以下步骤尝试该示例:
-
打开终端(在 Windows 上,打开命令行实用程序)
-
创建要保存程序的文件夹,例如
test-node,然后通过在终端中输入以下命令进入该文件夹bashcd test-node -
使用您喜欢的文本编辑器,创建一个名为
hello.js的文件,并将以下代码粘贴到其中js// Load HTTP module const http = require("http"); const hostname = "127.0.0.1"; const port = 8000; // Create HTTP server const server = http.createServer((req, res) => { // Set the response HTTP header with HTTP status and Content type res.writeHead(200, { "Content-Type": "text/plain" }); // Send the response body "Hello World" res.end("Hello World\n"); }); // Prints a log once the server starts listening server.listen(port, hostname, () => { console.log(`Server running at http://${hostname}:${port}/`); }); -
将文件保存到您上面创建的文件夹中。
-
回到终端并输入以下命令
bashnode hello.js
最后,在您的网络浏览器中导航到 https://:8000;您应该在空白网页的左上角看到文本“Hello World”。
注意:如果您想在无需任何本地设置的情况下使用一些 Node.js 代码,Scrimba 的附录:HTTP 模块 MDN 学习合作伙伴 提供了一个交互式演练,介绍了如何使用 Node HTTP 包设置一个基本的服务器。
Web 框架
Node 本身并不直接支持其他常见的 Web 开发任务。如果您想为不同的 HTTP 动词(例如 GET、POST、DELETE 等)添加特定处理,分别处理不同 URL 路径(“路由”)的请求,提供静态文件,或者使用模板动态创建响应,Node 自身将派不上用场。您要么需要自己编写代码,要么可以避免重复造轮子,使用 Web 框架!
Express 简介
Express 是最流行的 Node.js Web 框架,也是许多其他流行 Node.js 框架的底层库。它提供了以下机制:
- 为具有不同 HTTP 动词和不同 URL 路径(路由)的请求编写处理程序。
- 与“视图”渲染引擎集成,通过将数据插入模板来生成响应。
- 设置常见的 Web 应用程序设置,例如用于连接的端口,以及用于渲染响应的模板位置。
- 在请求处理管道的任何一点添加额外的请求处理“中间件”。
尽管 Express 本身相当简约,但开发者已经创建了兼容的中间件包来解决几乎所有 Web 开发问题。有用于处理 cookie、会话、用户登录、URL 参数、POST 数据、安全头等许多其他方面的库。您可以在Express 中间件上找到由 Express 团队维护的中间件包列表(以及一些流行的第三方包列表)。
注意:这种灵活性是一把双刃剑。有中间件包可以解决几乎所有问题或需求,但找出要使用的正确包有时可能是一个挑战。也没有“正确”的方法来构建应用程序,您在 Internet 上可能找到的许多示例都不是最优的,或者只显示了您开发 Web 应用程序所需的一小部分内容。
Node 和 Express 的起源?
Node 最初于 2009 年发布,仅支持 Linux。npm 包管理器于 2010 年发布,并在 2012 年添加了原生 Windows 支持。如果您想了解更多信息,可以深入研究维基百科。
Express 最初于 2010 年 11 月发布,目前 API 版本为 5。您可以查看更新日志了解当前版本中的更改信息,并在GitHub上查看更详细的历史发布说明。
Node 和 Express 有多受欢迎?
Web 框架的流行度很重要,因为它表明该框架是否会持续维护,以及在文档、附加库和技术支持方面可能提供哪些资源。
目前还没有任何现成的、明确的服务器端框架流行度衡量标准(尽管您可以使用诸如计算每个平台的 GitHub 项目数量和 Stack Overflow 问题数量等机制来估计流行度)。一个更好的问题是,Node 和 Express 是否“足够流行”以避免不受欢迎平台的问题。它们是否在持续发展?您是否能在需要时获得帮助?如果您学习 Express,是否有机会获得有偿工作?
根据使用 Express 的知名公司数量、代码库贡献者数量以及提供免费和付费支持的人数,是的,Express 是一个流行的框架!
Express 有自己的“主见”吗?
Web 框架通常将自己称为“有主见的”或“无主见的”。
有主见的框架是指对如何处理任何特定任务有“正确方式”的框架。它们通常支持特定领域(解决特定类型的问题)的快速开发,因为做任何事情的正确方式通常是众所周知且有详细文档的。然而,它们在解决其主要领域之外的问题时可能缺乏灵活性,并且往往提供的组件和方法选择较少。
相比之下,无主见的框架在如何将组件组合在一起以实现目标,甚至应该使用哪些组件方面,限制要少得多。它们使开发者更容易使用最合适的工具来完成特定任务,尽管代价是您需要自己找到这些组件。
Express 是无主见的。您几乎可以将任何兼容的中间件以几乎任何顺序插入到请求处理链中。您可以将应用程序组织在一个文件或多个文件中,并使用任何目录结构。您有时可能会觉得选择太多!
Express 代码是什么样的?
在一个传统的、数据驱动的网站中,Web 应用程序等待来自网络浏览器(或其他客户端)的 HTTP 请求。收到请求后,应用程序会根据 URL 模式以及可能包含在 POST 数据或 GET 数据中的相关信息,确定需要执行的操作。根据需要,它可能会从数据库中读取或写入信息,或执行满足请求所需的其他任务。然后,应用程序将向网络浏览器返回一个响应,通常通过将检索到的数据插入 HTML 模板中的占位符来动态创建一个 HTML 页面供浏览器显示。
Express 提供了指定针对特定 HTTP 动词(GET、POST、PUT 等)和 URL 模式(“路由”)调用哪个函数的方法,以及指定使用哪个模板(“视图”)引擎、模板文件位于何处以及使用哪个模板渲染响应的方法。您可以使用 Express 中间件来添加对 cookie、会话和用户的支持,获取 POST/GET 参数等。您可以使用 Node 支持的任何数据库机制(Express 不定义任何与数据库相关的行为)。
以下部分解释了在使用 Express 和 Node 代码时会看到的一些常见内容。
HelloWorld Express
首先,让我们考虑标准的 Express Hello World 示例(我们将在下面以及后续章节中讨论其各个部分)。
注意:如果您已经安装了 Node 和 Express(或者按照下一篇文章中所示安装),您可以将此代码保存到一个名为 app.js 的文本文件中,并在 bash 命令行中通过调用以下命令来运行它
node ./app.js
const express = require("express");
const app = express();
const port = 3000;
app.get("/", (req, res) => {
res.send("Hello World!");
});
app.listen(port, () => {
console.log(`Example app listening on port ${port}!`);
});
前两行 require()(导入)express 模块并创建一个 Express 应用程序。这个对象通常命名为 app,它具有路由 HTTP 请求、配置中间件、渲染 HTML 视图、注册模板引擎以及修改控制应用程序行为的应用程序设置(例如,环境模式、路由定义是否区分大小写等)的方法。
代码的中间部分(以 app.get 开头的三行)显示了一个路由定义。app.get() 方法指定了一个回调函数,该函数将在收到路径('/')相对于站点根目录的 HTTP GET 请求时被调用。回调函数将请求和响应对象作为参数,并调用响应上的 send() 返回字符串“Hello World!”
最后一段启动指定端口('3000')上的服务器,并向控制台打印日志注释。服务器运行后,您可以在浏览器中访问 localhost:3000 查看返回的示例响应。
导入和创建模块
模块是 JavaScript 库/文件,您可以使用 Node 的 require() 函数将其导入到其他代码中。Express 本身就是一个模块,我们在 Express 应用程序中使用的中间件和数据库库也是如此。
下面的代码展示了我们如何按名称导入模块,以 Express 框架为例。首先,我们调用 require() 函数,将模块名称指定为字符串('express'),然后调用返回的对象创建一个 Express 应用程序。然后,我们可以访问应用程序对象的属性和函数。
const express = require("express");
const app = express();
您也可以创建自己的模块,并以相同的方式导入。
注意:您会希望创建自己的模块,因为这允许您将代码组织成可管理的部分——一个庞大的单文件应用程序难以理解和维护。使用模块还可以帮助您管理命名空间,因为在使用模块时,只有您明确导出的变量才会被导入。
要使对象在模块外部可用,您只需将它们作为附加属性公开到 exports 对象上。例如,下面的 square.js 模块是一个导出 area() 和 perimeter() 方法的文件
exports.area = function (width) {
return width * width;
};
exports.perimeter = function (width) {
return 4 * width;
};
我们可以使用 require() 导入此模块,然后调用导出的方法,如下所示
const square = require("./square"); // Here we require() the name of the file without the (optional) .js file extension
console.log(`The area of a square with a width of 4 is ${square.area(4)}`);
注意:您也可以指定模块的绝对路径(或名称,如我们最初所做)。
如果您想一次性导出完整的对象,而不是逐个属性构建它,请将其分配给 module.exports,如下所示(您也可以这样做,使 exports 对象的根成为构造函数或其他函数)
module.exports = {
area(width) {
return width * width;
},
perimeter(width) {
return 4 * width;
},
};
注意:您可以将 exports 视为给定模块中 module.exports 的快捷方式。实际上,在模块求值之前,exports 只是一个被初始化为 module.exports 值的变量。该值是对一个对象(在这种情况下为空对象)的引用。这意味着 exports 持有对 module.exports 引用的同一对象的引用。这也意味着通过将另一个值赋给 exports,它不再绑定到 module.exports。
有关模块的更多信息,请参阅 Modules (Node API 文档)。
使用异步 API
JavaScript 代码经常使用异步而非同步 API 进行可能需要一些时间才能完成的操作。同步 API 是指每个操作必须在下一个操作开始之前完成。例如,以下日志函数是同步的,并将按顺序(First, Second)将文本打印到控制台。
console.log("First");
console.log("Second");
相比之下,异步 API 是一种 API,它会启动一个操作并立即返回(在操作完成之前)。一旦操作完成,API 将使用某种机制来执行其他操作。例如,下面的代码将打印出“Second, First”,因为尽管 setTimeout() 方法首先被调用并立即返回,但操作在几秒钟内并未完成。
setTimeout(() => {
console.log("First");
}, 3000);
console.log("Second");
在 Node 中使用非阻塞异步 API 比在浏览器中更重要,因为 Node 应用程序通常被编写为单线程事件驱动的执行环境。“单线程”意味着所有对服务器的请求都在同一个线程上运行(而不是派生到单独的进程中)。这种模型在速度和服务器资源方面非常高效。然而,它确实意味着,如果您的任何函数调用耗时长的同步方法,它们不仅会阻塞当前请求,还会阻塞您的 Web 应用程序正在处理的每个其他请求。
异步 API 有多种方式可以通知您的应用程序它已完成。历史上,使用的方法是在调用异步 API 时注册一个回调函数,该函数在操作完成时被调用(这是上面使用的方法)。
注意:如果您有一系列必须按顺序执行的依赖异步操作,使用回调函数可能会非常“混乱”,因为这会导致多层嵌套回调。这个问题通常被称为“回调地狱”。
注意:Node 和 Express 的一个常见约定是使用错误优先回调。在此约定中,回调函数中的第一个值是错误值,而后续参数包含成功数据。这篇博客很好地解释了为什么这种方法很有用:The Node.js Way - Understanding Error-First Callbacks (fredkschott.com)。
现代 JavaScript 代码更常使用 Promises 和 async/await 来管理异步程序流。您应尽可能使用 Promise。如果与使用回调的代码一起工作,您可以使用 Node.js utils.promisify 函数以符合人体工程学的方式处理回调 → Promise 转换。
创建路由处理程序
在我们的 Hello World Express 示例(见上文)中,我们为网站根目录 ('/') 的 HTTP GET 请求定义了一个(回调)路由处理函数。
app.get("/", (req, res) => {
res.send("Hello World!");
});
回调函数接受请求和响应对象作为参数。在这种情况下,该方法调用响应上的 send() 返回字符串“Hello World!”。还有许多其他响应方法用于结束请求/响应周期,例如,您可以调用 res.json() 发送 JSON 响应或 res.sendFile() 发送文件。
注意:您可以在回调函数中使用任何您喜欢的参数名称;当回调被调用时,第一个参数将始终是请求,第二个参数将始终是响应。给它们命名,以便您可以在回调主体中识别您正在处理的对象,这是有意义的。
Express 应用程序对象还提供了为所有其他 HTTP 动词定义路由处理程序的方法,这些方法的使用方式大致相同
checkout(), copy(), delete(), get(), head(), lock(), merge(), mkactivity(), mkcol(), move(), m-search(), notify(), options(), patch(), post(), purge(), put(), report(), search(), subscribe(), trace(), unlock(), unsubscribe()。
有一个特殊的路由方法 app.all(),它将响应任何 HTTP 方法而被调用。它用于在特定路径为所有请求方法加载中间件函数。以下示例(来自 Express 文档)展示了一个处理程序,它将针对对 /secret 的请求执行,无论使用何种 HTTP 动词(前提是它受 http 模块支持)。
app.all("/secret", (req, res, next) => {
console.log("Accessing the secret section…");
next(); // pass control to the next handler
});
路由允许您匹配 URL 中的特定字符模式,并从 URL 中提取一些值,然后将它们作为参数传递给路由处理程序(作为作为参数传递的请求对象的属性)。
通常,将网站特定部分的路由处理程序分组在一起,并使用一个共同的路由前缀访问它们(例如,一个拥有 Wiki 的网站可能将所有与 Wiki 相关的路由放在一个文件中,并通过 /wiki/ 的路由前缀访问它们)很有用。在 Express 中,这通过使用 express.Router 对象来实现。例如,我们可以在名为 wiki.js 的模块中创建我们的 wiki 路由,然后导出 Router 对象,如下所示
// wiki.js - Wiki route module
const express = require("express");
const router = express.Router();
// Home page route
router.get("/", (req, res) => {
res.send("Wiki home page");
});
// About page route
router.get("/about", (req, res) => {
res.send("About this wiki");
});
module.exports = router;
注意:向 Router 对象添加路由就像向 app 对象添加路由一样(如前所示)。
要在主应用程序文件中使用路由器,我们首先需要 require() 路由模块(wiki.js),然后调用 Express 应用程序上的 use() 将路由器添加到中间件处理路径。然后,这两个路由将可通过 /wiki/ 和 /wiki/about/ 访问。
const wiki = require("./wiki.js");
// …
app.use("/wiki", wiki);
我们将在链接部分路由和控制器中向您展示更多关于使用路由,尤其是使用 Router 的内容。
使用中间件
中间件在 Express 应用程序中被广泛使用,从提供静态文件到错误处理,再到压缩 HTTP 响应。路由函数通过向 HTTP 客户端返回一些响应来结束 HTTP 请求-响应周期,而中间件函数通常对请求或响应执行一些操作,然后调用“堆栈”中的下一个函数,这可能是更多的中间件或路由处理程序。中间件的调用顺序由应用程序开发者决定。
注意:中间件可以执行任何操作、运行任何代码、更改请求和响应对象,并且它还可以结束请求-响应周期。如果它不结束周期,那么它必须调用 next() 将控制权传递给下一个中间件函数(否则请求将一直挂起)。
大多数应用程序将使用第三方中间件来简化常见的 Web 开发任务,例如处理 cookie、会话、用户认证、访问请求 POST 和 JSON 数据、日志记录等。您可以在Express 团队维护的中间件包列表中找到(其中还包括其他流行的第三方包)。其他 Express 包可在 npm 包管理器上找到。
要使用第三方中间件,您首先需要使用 npm 将其安装到您的应用程序中。例如,要安装 morgan HTTP 请求日志记录中间件,您可以这样做
npm install morgan
然后,您可以在 Express 应用程序对象上调用 use() 将中间件添加到堆栈中。
const express = require("express");
const logger = require("morgan");
const app = express();
app.use(logger("dev"));
// …
注意:中间件和路由函数按照它们声明的顺序被调用。对于某些中间件,顺序很重要(例如,如果会话中间件依赖于 cookie 中间件,那么必须首先添加 cookie 处理程序)。几乎总是这样,中间件在设置路由之前被调用,否则您的路由处理程序将无法访问中间件添加的功能。
您可以编写自己的中间件函数,并且您很可能需要这样做(如果只是为了创建错误处理代码)。中间件函数和路由处理程序回调之间唯一的区别是中间件函数有第三个参数 next,如果中间件函数没有完成请求周期,则预期会调用它(当中间件函数被调用时,它包含必须调用的下一个函数)。
您可以使用 app.use() 将中间件函数添加到所有响应的处理链中,或使用关联的方法(app.get()、app.post() 等)为特定的 HTTP 动词添加。在两种情况下,路由的指定方式相同,尽管在调用 app.use() 时路由是可选的。
下面的示例展示了如何使用这两种方法以及有/无路由来添加中间件函数。
const express = require("express");
const app = express();
// An example middleware function
function middlewareFunction(req, res, next) {
// Perform some operations
next(); // Call next() so Express will call the next middleware function in the chain.
}
// Function added with use() for all routes and verbs
app.use(middlewareFunction);
// Function added with use() for a specific route
app.use("/some-route", middlewareFunction);
// A middleware function added for a specific HTTP verb and route
app.get("/", middlewareFunction);
app.listen(3000);
注意:上面我们单独声明了中间件函数,然后将其设置为回调。在我们之前的路由处理程序函数中,我们在使用时声明了回调函数。在 JavaScript 中,这两种方法都有效。
提供静态文件
您可以使用 express.static 中间件来提供静态文件,包括您的图像、CSS 和 JavaScript(static() 是唯一一个实际属于 Express 的中间件函数)。例如,您可以使用下面的行来从名为“public”的目录中提供图像、CSS 文件和 JavaScript 文件,该目录与您调用 Node 的目录处于同一级别。
app.use(express.static("public"));
public 目录中的任何文件都通过将它们的文件名(相对于基本“public”目录)添加到基本 URL 来提供。例如
https://:3000/images/dog.jpg https://:3000/css/style.css https://:3000/js/app.js https://:3000/about.html
您可以多次调用 static() 以提供多个目录。如果一个中间件函数找不到文件,它将被传递给后续的中间件(中间件的调用顺序基于您的声明顺序)。
app.use(express.static("public"));
app.use(express.static("media"));
您还可以为静态 URL 创建一个虚拟前缀,而不是将文件添加到基本 URL。例如,在这里我们指定一个挂载路径,以便文件以“/media”前缀加载
app.use("/media", express.static("public"));
现在,您可以从 /media 路径前缀加载 public 目录中的文件。
https://:3000/media/images/dog.jpg https://:3000/media/video/cat.mp4 https://:3000/media/cry.mp3
注意:另请参阅 在 Express 中提供静态文件。
处理错误
错误由一个或多个特殊的中间件函数处理,这些函数有四个参数,而不是通常的三个:(err, req, res, next)。例如
app.use((err, req, res, next) => {
console.error(err.stack);
res.status(500).send("Something broke!");
});
它们可以返回任何所需的内容,但必须在所有其他 app.use() 和路由调用之后调用,以便它们是请求处理过程中的最后一个中间件!
Express 自带内置错误处理程序,它负责处理应用程序中可能遇到的任何剩余错误。此默认错误处理中间件函数添加到中间件函数堆栈的末尾。如果您将错误传递给 next() 但未在错误处理程序中处理它,它将由内置错误处理程序处理;错误将随堆栈跟踪一起写入客户端。
注意:堆栈跟踪不包含在生产环境中。要在生产模式下运行,您需要将环境变量 NODE_ENV 设置为 "production"。
注意:HTTP404 和其他“错误”状态码不被视为错误。如果您想处理这些,可以添加一个中间件函数来执行此操作。有关更多信息,请参阅常见问题解答。
有关更多信息,请参阅错误处理(Express 文档)。
使用数据库
Express 应用程序可以使用 Node 支持的任何数据库机制(Express 本身不定义任何特定的附加行为/数据库管理要求)。有许多选项,包括 PostgreSQL、MySQL、Redis、SQLite、MongoDB 等。
为了使用这些,您必须首先使用 npm 安装数据库驱动程序。例如,要安装流行的 NoSQL MongoDB 的驱动程序,您将使用以下命令
npm install mongodb
数据库本身可以安装在本地或云服务器上。在您的 Express 代码中,您导入驱动程序,连接到数据库,然后执行创建、读取、更新和删除(CRUD)操作。下面的示例展示了如何使用 MongoDB 查找“哺乳动物”记录
const { MongoClient } = require("mongodb");
const uri = "mongodb://:27017";
const client = new MongoClient(uri);
async function run() {
try {
await client.connect();
const db = client.db("animals");
const mammals = await db.collection("mammals").find().toArray();
console.log(mammals);
} finally {
await client.close();
}
}
run().catch(console.error);
另一种流行的方法是通过对象关系映射器(“ORM”)间接访问数据库。在这种方法中,您将数据定义为“对象”或“模型”,ORM 将这些数据映射到底层数据库格式。这种方法的优点是,作为开发人员,您可以继续以 JavaScript 对象的角度思考,而不是数据库语义,并且有一个明确的地方可以执行传入数据的验证和检查。我们将在后面的文章中讨论更多关于数据库的内容。
有关更多信息,请参阅数据库集成(Express 文档)。
渲染数据(视图)
模板引擎(在 Express 中也称为“视图引擎”)允许您在模板中指定输出文档的结构,使用占位符来存储数据,这些数据将在生成页面时填充。模板通常用于创建 HTML,但也可以创建其他类型的文档。
Express 支持许多模板引擎,其中最著名的是 Pug(以前称为“Jade”)、Mustache 和 EJS。每个模板引擎都有其独特的优势,适用于特定的用例(通过互联网搜索可以轻松找到相对比较)。Express 应用程序生成器默认使用 Jade,但也支持其他几个。
在您的应用程序设置代码中,您可以使用“views”和“view engine”设置来设置要使用的模板引擎以及 Express 应该查找模板的位置,如下所示(您还需要安装包含您的模板库的包!)。
const express = require("express");
const path = require("path");
const app = express();
// Set directory to contain the templates ('views')
app.set("views", path.join(__dirname, "views"));
// Set view engine to use, in this case 'some_template_engine_name'
app.set("view engine", "some_template_engine_name");
模板的外观将取决于您使用的引擎。假设您有一个名为 "index.<template_extension>" 的模板文件,其中包含名为 'title' 和 "message" 的数据变量占位符,您将在路由处理程序函数中调用 Response.render() 来创建并发送 HTML 响应
app.get("/", (req, res) => {
res.render("index", { title: "About dogs", message: "Dogs rock!" });
});
有关更多信息,请参阅在 Express 中使用模板引擎(Express 文档)。
文件结构
Express 在结构或您使用的组件方面没有任何假设。路由、视图、静态文件和其他应用程序特定逻辑可以存在于任意数量的文件中,并具有任何目录结构。虽然将整个 Express 应用程序放在一个文件中是完全可能的,但通常按功能(例如,账户管理、博客、论坛)和架构问题领域(例如,如果您碰巧使用 MVC 架构,则为模型、视图或控制器)将应用程序拆分为文件是有意义的。
在后面的主题中,我们将使用 Express 应用程序生成器,它创建了一个模块化的应用程序骨架,我们可以轻松扩展它来创建 Web 应用程序。
总结
恭喜,您已完成 Express/Node 之旅的第一步!您现在应该了解 Express 和 Node 的主要优点,以及 Express 应用程序的主要部分可能是什么样子(路由、中间件、错误处理和模板代码)。您还应该了解,Express 是一个无主见的框架,因此您如何将这些部分组合在一起以及您使用的库在很大程度上取决于您!
当然,Express 刻意是一个非常轻量级的 Web 应用程序框架,因此它的许多优点和潜力都来自第三方库和功能。我们将在后续文章中更详细地探讨这些。在我们的下一篇文章中,我们将着手设置 Node 开发环境,以便您可以看到一些 Express 代码的实际运行。
另见
- Scrimba 的学习 Node.js MDN 学习合作伙伴 提供了一个有趣、交互式的 Node.js 入门教程。
- Scrimba 的学习 Express.js MDN 学习合作伙伴 在前一个链接的基础上,展示了如何开始使用 Express 框架构建服务器端网站。
- 模块(Node API 文档)
- Express(主页)
- 基本路由(Express 文档)
- 路由指南(Express 文档)
- 在 Express 中使用模板引擎(Express 文档)
- 使用中间件(Express 文档)
- 为 Express 应用程序编写中间件(Express 文档)
- 数据库集成(Express 文档)
- 在 Express 中提供静态文件(Express 文档)
- 错误处理(Express 文档)