Express/Node introduction

 

在第一篇Express文章中,我们回答问题"什么是节点?" 和"什么是Express?",并概述了Express Web框架的特殊之处. 我们将概述主要功能,并向您展示Express应用程序的一些主要构建块(尽管此时您还没有一个可以对其进行测试的开发环境).

Prerequisites: 基本的计算机知识. 对服务器端网站编程的一般了解,尤其是网站客户端与服务器交互的机制 .
Objective: 为了熟悉Express是什么以及它如何与Node配合,它提供了什么功能以及Express应用程序的主要构造块.

Introducing Node

Node (或更正式地说是Node.js )是一个开放源代码,跨平台的运行时环境,允许开发人员使用JavaScript创建各种服务器端工具和应用程序. 该运行时旨在在浏览器上下文之外使用(即,直接在计算机或服务器OS上运行). 因此,该环境省略了特定于浏览器的JavaScript API,并增加了对更多传统OS API(包括HTTP和文件系统库)的支持.

从Web服务器开发的角度来看,Node具有许多优点:

  • 很棒的演出! Node旨在优化Web应用程序的吞吐量和可伸缩性,并且是解决许多常见Web开发问题(例如实时Web应用程序)的良好解决方案.
  • 代码是用"普通的旧JavaScript"编写的,这意味着在编写客户端和服务器端代码时,花费较少的时间处理语言之间的"上下文转换".
  • JavaScript是一种相对较新的编程语言,与其他传统的网络服务器语言(例如Python,PHP等)相比,它在语言设计方面有所改进.许多其他新的流行语言都可以编译/转换为JavaScript,因此您还可以使用TypeScript, CoffeeScript,ClojureScript,Scala,LiveScript等
  • 节点软件包管理器(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"响应. 如果已经安装了节点,则可以按照以下步骤尝试该示例:

  1. 打开终端(在Windows上,打开命令行实用程序)
  2. 创建要保存程序的文件夹,例如test-node ,然后通过在终端中输入以下命令来输入该文件夹:
cd test-node
  1. 使用您喜欢的文本编辑器,创建一个名为hello.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}/`);
})
  1. 将文件保存在上面创建的文件夹中.
  2. 返回终端并输入以下命令:
node hello.js

最后,在您的Web浏览器中导航到http://localhost:8000 ; 您应该在原本为空的网页的左上方看到文本" Hello World ".

Web Frameworks

Node本身不直接支持其他常见的Web开发任务. 如果要为不同的HTTP动词(例如GETPOSTDELETE等)添加特定的处理方式,请分别处理不同URL路径("路由")上的请求,提供静态文件,或使用模板动态创建响应,即Node本身不会有太多用处. 您将需要自己编写代码,或者可以避免重新发明轮子并使用Web框架!

Introducing Express

Express是最流行的Node Web框架,并且是许多其他流行的Node Web框架的基础库. 它提供了以下机制:

  • 在不同的URL路径(路由)中为具有不同HTTP动词的请求编写处理程序.
  • 与"视图"渲染引擎集成,以便通过将数据插入模板来生成响应.
  • 设置常见的Web应用程序设置,例如用于连接的端口以及用于呈现响应的模板的位置.
  • 在请求处理管道内的任何位置添加其他请求处理"中间件".

尽管Express本身是极简主义的,但是开发人员已经创建了兼容的中间件软件包,以解决几乎所有Web开发问题. 有图书馆与饼干,会话,用户登录,URL参数,工作POST数据,安全头, 等等 . 您可以在Express Middleware中找到Express团队维护的中间件软件包列表(以及一些流行的第三方软件包的列表).

注意:这种灵活性是一把双刃剑. 有中间件软件包可以解决几乎所有问题或要求,但是制定出合适的软件包来使用有时可能是一个挑战. 也没有"正确的方法"来构造应用程序,并且您可能会在Internet上发现许多示例都不是最优的,或者仅展示了开发Web应用程序所需做的一小部分.

Where did Node and Express come from?

Node最初于2009年发布,仅适用于Linux.NPM软件包管理器于2010年发布,2012年增加了对Windows的本地支持.当前LTS版本为Node v12.16.1,而最新版本为Node 13.11.0. 这只是丰富历史的一小部分快照; 如果您想了解更多信息,请浏览Wikipedia .

Express最初于2010年11月发布,目前使用的API版本为4.17.1. 您可以查看更改日志以获取有关当前版本中更改的信息,可以查看GitHub以获得更详细的历史发布说明.

Web框架的普及很重要,因为它可以指示它是否将继续得到维护,以及从文档,附加库和技术支持方面可能会获得哪些资源.

关于服务器端框架的流行程度,没有任何现成的和明确的度量标准(尽管像Hot Frameworks这样的网站尝试使用诸如计算GitHub项目数和每个平台的StackOverflow问题之类的机制来评估流行度). 更好的问题是Node和Express是否"足够流行",以避免平台不受欢迎的问题. 他们正在继续发展吗? 如果需要可以得到帮助吗? 如果您学习Express,是否有机会获得有偿工作?

根据使用Express的知名公司的数量,向代码库做出贡献的人数以及提供免费和付费支持服务的人数,那么, Express是一个受欢迎的框架!

Is Express opinionated?

Web框架通常称自己为"有意见的"或"无意见的".

有观点的框架是那些对处理任何特定任务的"正确方法"有看法的框架. 他们通常支持在特定领域中的快速发展(解决特定类型的问题),因为正确的做法通常都被很好地理解和有据可查. 但是,他们在解决其主要领域之外的问题时可能不太灵活,并且倾向于为他们可以使用的组件和方法提供较少的选择.

相比之下,未提出意见的框架对将组件粘合在一起以实现目标的最佳方法甚至应该使用什么组件的限制都少得多. 它们使开发人员可以更轻松地使用最合适的工具来完成特定任务,尽管这需要您自己找到这些组件.

快递没有意见. 您可以按照您喜欢的几乎任何顺序将几乎任何您喜欢的兼容中间件插入到请求处理链中. 您可以使用一个目录结构将应用程序构造为一个文件或多个文件. 有时您可能会觉得自己有太多选择!

What does Express code look like?

在传统的数据驱动的网站中,Web应用程序等待来自Web浏览器(或其他客户端)的HTTP请求. 收到请求后,应用程序将根据URL模式以及POST数据或GET数据中可能包含的相关信息,确定需要采取什么措施. 然后,根据需要的内容,它可以从数据库读取或写入信息,或执行满足请求所需的其他任务. 然后,应用程序将响应返回到Web浏览器,通常是通过将检索到的数据插入HTML模板中的占位符来动态创建HTML页面供浏览器显示.

Express提供了一些方法来指定对特定HTTP动词( GETPOSTSET等)和URL模式(" Route")调用的函数,以及指定使用哪种模板(" view")引擎的方法,其中模板找到文件,以及用于呈现响应的模板. 您可以使用Express中间件来添加对cookie,会话和用户的支持,获取POST / GET参数等.您可以使用Node支持的任何数据库机制(Express不定义任何与数据库相关的行为).

The following sections explain some of the common things you'll see when working with Express and Node code.

Helloworld Express

首先,让我们考虑标准的Express Hello World示例(我们将在下面以及以下各节中讨论该示例的每个部分).

提示:如果已经安装了Node和Express(或者如下一篇文章中所示安装它们),则可以将此代码保存在名为app.js的文本文件中,并通过调用以下命令在bash命令提示符下运行:

node ./app.js

var express = require('express');
var app = express();

app.get('/', function(req, res) {
  res.send('Hello World!');
});

app.listen(3000, function() {
  console.log('Example app listening on port 3000!');
});

前两行require() (导入)express模块​​并创建Express应用程序 . 该对象的传统名称为app ,具有用于路由HTTP请求,配置中间件,呈现HTML视图,注册模板引擎以及修改控制应用程序行为的应用程序设置的方法(例如,环境模式,路由定义是否区分大小写)等)

代码的中间部分(以app.get开头的app.get )显示了路由定义 . app.get()方法指定一个回调函数,只要存在带有相对于网站根目录的路径( '/' )的HTTP GET请求,就会调用该回调函数. 回调函数将请求和响应对象作为参数,并仅在响应上调用send()以返回字符串" Hello World!".

最后一块在端口" 3000"上启动服务器,并将日志注释打印到控制台. 在服务器运行的情况下,您可以在浏览器中转到localhost:3000以查看返回的示例响应.

Importing and creating modules

模块是一个JavaScript库/文件,您可以使用Node的require()函数将其导入其他代码. Express本身是一个模块,我们在Express应用程序中使用的中间件和数据库库也是一个模块.

下面的代码以Express框架为例,说明如何按名称导入模块. 首先,我们调用require()函数,将模块名称指定为字符串( 'express' ),然后调用返回的对象以创建Express应用程序 . 然后,我们可以访问应用程序对象的属性和功能.

var express = require('express');
var app = express();

您也可以创建自己的模块,并以相同的方式导入.

提示:您将需要创建自己的模块,因为这使您可以将代码组织为可管理的部分-单一的单文件应用程序难以理解和维护. 使用模块还可以帮助您管理名称空间,因为在使用模块时,仅导入显式导出的变量.

为了使对象在模块外部可用,您只需要在exports对象上将它们作为其他属性公开即可. 例如,下面的square.js模块是一个文件,该文件导出area()perimeter()方法:

exports.area = function(width) { return width * width; };
exports.perimeter = function(width) { return 4 * width; };

我们可以使用require()导入此模块,然后调用导出的方法,如下所示:

var 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 ,如下所示(您也可以这样做,以使导出对象的根成为构造函数或其他函数) :

module.exports = {
  area: function(width) {
    return width * width;
  },
       
  perimeter: function(width) {
    return 4 * width;
  }
};

注意:您可以将exports视为给定模块中module.exports快捷方式 . 实际上, exports只是一个变量,在评估模块之前,它会初始化为module.exports的值. 该值是对对象(在这种情况下为空对象)的引用. 这意味着, exports保存由引用的同一对象的引用module.exports . 这也意味着通过为exports分配另一个值,它不再绑定到module.exports .

有关模块的更多信息,请参见模块 (Node API文档).

Using asynchronous APIs

JavaScript代码通常使用异步API而不是同步API来完成可能需要一些时间才能完成的操作. 同步API是其中每个操作必须先完成,然后才能开始下一个操作的API. 例如,以下日志功能是同步的,并将按顺序(第一,第二)将文本打印到控制台.

console.log('First');
console.log('Second');

相比之下,异步API是一种API,其中该API将启动操作并立即返回(在操作完成之前). 操作完成后,API将使用某种机制来执行其他操作. 例如,下面的代码将打印出"第二,第一",因为即使首先调用setTimeout()方法并立即返回,该操作也不会在几秒钟内完成.

setTimeout(function() {
   console.log('First');
   }, 3000);
console.log('Second');

在Node上使用非阻塞异步API比在浏览器中更为重要,因为Node是一个单线程事件驱动的执行环境. "单线程"表示对服务器的所有请求都在同一线程上运行(而不是派生到单独的进程中). 该模型在速度和服务器资源方面非常高效,但是它确实意味着,如果您的任何函数调用花费很长时间才能完成的同步方法,它们将不仅阻塞当前请求,而且还会阻塞其他所有正在处理的请求.您的Web应用程序.

异步API通过多种方式通知您的应用程序已完成. 最常见的方法是在调用异步API时注册一个回调函数,该回调函数将在操作完成时被回调. 这是上面使用的方法.

提示:如果必须按顺序执行一系列相关的异步操作,则使用回调可能会非常"混乱",因为这会导致嵌套回调的多个级别. 此问题通常称为"回调地狱". 可以通过良好的编码习惯(请参见http://callbackhell.com/ ),使用诸如async之类的模块甚至移至诸如Promises之类的ES6功能来减少此问题.

注意: Node和Express的通用约定是使用错误优先的回调. 按照这种约定, 回调函数中的第一个值是错误值,而后续参数包含成功数据. 关于此方法为何在此博客中有用的一个很好的解释: Node.js方式-理解错误优先回调 (fredkschott.com).

Creating route handlers

在我们的Hello World Express示例(请参见上文)中,我们定义了到站点根( '/' )的HTTP GET请求的(回调)路由处理函数.

app.get('/', function(req, res) {
  res.send('Hello World!');
});

回调函数将请求和响应对象作为参数. 在这种情况下,该方法仅在响应上调用send()即可返回字符串" Hello World!". 还有许多其他响应方法可用于结束请求/响应周期,例如,您可以调用res.json()发送JSON响应,或者调用res.sendFile()发送文件.

JavaScript技巧:您可以在回调函数中使用所需的任何参数名称; 当回调被调用时,第一个参数将始终是请求,第二个参数将始终是响应. 命名它们很有意义,以便您可以在回调主体中标识正在使用的对象.

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', function(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

var express = require('express');
var router = express.Router();

// Home page route
router.get('/', function(req, res) {
  res.send('Wiki home page');
});

// About page route
router.get('/about', function(req, res) {
  res.send('About this wiki');
});

module.exports = router;

注意:将路由添加到Router对象就像将路由添加到app对象(如上所示).

要在我们的主应用程序文件中使用路由器,我们require()路由模块( wiki.js ),然后在Express应用程序上调用use()将路由器添加到中间件处理路径. 然后可以从/wiki//wiki/about/访问两条路线.

var wiki = require('./wiki.js');
// ...
app.use('/wiki', wiki);

稍后在链接部分Routes and controllers中 ,我们将向您展示有关使用路由的更多信息,尤其是有关使用Router .

Using middleware

中间件在Express应用程序中得到广泛使用,其任务从提供静态文件到错误处理,再到压缩HTTP响应. 路由功能通过向HTTP客户端返回一些响应来结束HTTP请求-响应周期,而中间件功能通常会对请求或响应执行某些操作,然后在"堆栈"中调用下一个功能,这可能是更多中间件或路由处理程序. 调用中间件的顺序取决于应用程序开发人员.

注意:中间件可以执行任何操作,执行任何代码,对请求和响应对象进行更改,并且还可以结束请求-响应周期 . 如果没有结束循环,则必须调用next()将控制权传递给下一个中间件函数(否则该请求将被挂起).

大多数应用程序将使用第三方中间件来简化常见的Web开发任务,例如使用Cookie,会话,用户身份验证,访问请求POST和JSON数据,日志记录等.您可以找到Express团队维护的中间件软件包列表 (还包括其他流行的第三方套餐). NPM软件包管理器上提供了其他Express软件包.

To use third party middleware you first need to install it into your app using NPM. For example, to install the morgan HTTP request logger middleware, you'd do this:

$ npm install morgan

然后,您可以在Express应用程序对象上调用use()以将中间件添加到堆栈中:

var express = require('express');
var logger = require('morgan');
var app = express();
app.use(logger('dev'));
...

注意:中间件和路由功能按声明的顺序调用. 对于某些中间件,顺序很重要(例如,如果会话中间件依赖于cookie中间件,则必须首先添加cookie处理程序). 几乎总是在设置路由之前调用中间件的情况,否则您的路由处理程序将无法访问中间件添加的功能.

您可以编写自己的中间件功能,并且可能必须这样做(如果仅是为了创建错误处理代码). 中间件函数和路由处理程序回调之间的唯一区别在于,中间件函数具有第三个参数next ,如果中间件函数不是完成请求周期的函数,则期望该中间件函数被调用(当调用中间件函数时,该中间件包含下一个必须调用的函数).

您可以使用app.use()app.add()将中间件功能添加到处理链中,具体取决于您是将中间件应用于所有响应还是具有特定HTTP动词( GETPOST等)的响应). 尽管在调用app.use()时该路由是可选的,但在两种情况下都可以指定相同的路由.

下面的示例显示了如何使用这两种方法以及是否使用路由来添加中间件功能.

var express = require('express');
var app = express();

// An example middleware function
var a_middleware_function = function(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(a_middleware_function);

// Function added with use() for a specific route
app.use('/someroute', a_middleware_function);

// A middleware function added for a specific HTTP verb and route
app.get('/', a_middleware_function);

app.listen(3000);

JavaScript技巧:上面我们分别声明了中间件函数,然后将其设置为回调. 在先前的路由处理程序函数中,我们在使用回调函数时声明了该函数. 在JavaScript中,这两种方法都是有效的.

Express文档提供了许多有关使用编写 Express中间件的出色文档.

Serving static files

您可以使用express.static中间件来提供静态文件,包括图像,CSS和JavaScript( static()是实际上实际上是Express 一部分的唯一中间件函数). 例如,您将使用以下行在与调用节点相同的级别上提供名为" public"的目录中的图像,CSS文件和JavaScript文件:

app.use(express.static('public'));

通过将文件名( 对于基本"公共"目录而言)添加到基本URL,可以提供公共目录中的所有文件. 因此,例如:

http://localhost:3000/images/dog.jpg
http://localhost:3000/css/style.css
http://localhost:3000/js/app.js
http://localhost: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目录中的文件.

http://localhost:3000/media/images/dog.jpg
http://localhost:3000/media/video/cat.mp4
http://localhost:3000/media/cry.mp3

有关更多信息,请参见在Express中提供静态文件 .

Handling errors

错误由一个或多个特殊的中间件函数处理,这些函数具有四个参数,而不是通常的三个参数: (err, req, res, next) . 例如:

app.use(function(err, req, res, next) {
  console.error(err.stack);
  res.status(500).send('Something broke!');
});

它们可以返回所需的任何内容,但必须在所有其他app.use()之后调用并路由调用,以便它们成为请求处理过程中的最后一个中间件!

Express带有内置的错误处理程序,可处理应用程序中可能遇到的所有其他错误. 该默认的错误处理中间件功能添加在中间件功能堆栈的末尾. 如果将错误传递给next()而不在错误处理程序中进行处理,则它将由内置错误处理程序进行处理; 错误将与堆栈跟踪一起写入客户端.

注意:堆栈跟踪不包含在生产环境中. 要在生产模式下运行它,您需要将环境变量NODE_ENV设置为' production' .

注意: HTTP404和其他"错误"状态代码不会被视为错误. 如果要处理这些,则可以添加中间件功能. 有关更多信息,请参见FAQ .

有关更多信息,请参见错误处理 (Express docs).

Using databases

Express应用程序可以使用Node支持的任何数据库机制( Express本身并未定义数据库管理的任何其他特定行为/要求). 有很多选项,包括PostgreSQL,MySQL,Redis,SQLite,MongoDB等.

为了使用这些,您必须首先使用NPM安装数据库驱动程序. 例如,要为流行的NoSQL MongoDB安装驱动程序,可以使用以下命令:

$ npm install mongodb

数据库本身可以安装在本地或云服务器上. 在Express代码中,您需要驱动程序,连接到数据库,然后执行创建,读取,更新和删除(CRUD)操作. 下面的示例(来自Express文档)展示了如何使用MongoDB查找"哺乳动物"记录.

//this works with older versions of  mongodb version ~ 2.2.33
var MongoClient = require('mongodb').MongoClient;

MongoClient.connect('mongodb://localhost:27017/animals', function(err, db) {
  if (err) throw err;

  db.collection('mammals').find().toArray(function (err, result) {
    if (err) throw err;

    console.log(result);
  });
});


//for mongodb version 3.0 and up
let MongoClient = require('mongodb').MongoClient;
MongoClient.connect('mongodb://localhost:27017/animals', function(err, client){
   if(err) throw err;
   
   let db = client.db('animals');
   db.collection('mammals').find().toArray(function(err, result){
     if(err) throw err;
     console.log(result);
     client.close();
   });
});

另一种流行的方法是通过对象关系映射器(" ORM")间接访问数据库. 在这种方法中,您将数据定义为"对象"或"模型",并且ORM将这些数据映射到基础数据库格式. 这种方法的好处是,作为开发人员,您可以继续以JavaScript对象而不是数据库语义来思考,并且有明显的位置可以执行验证和检查传入数据. 我们将在以后的文章中进一步讨论数据库.

有关更多信息,请参见数据库集成 (Express docs).

Rendering data (views)

模板引擎( Express称为Express的 "视图引擎")允许您使用占位符指定将在生成页面时填充的数据,从而在模板中指定输出文档的结构 . 模板通常用于创建HTML,但也可以创建其他类型的文档. Express支持许多模板引擎 ,并且这里有一些比较流行的引擎的有用比较: 比较JavaScript模板引擎:Jade,Mustache,Dust等 .

在应用程序设置代码中,您设置了要使用的模板引擎以及Express使用"视图"和"视图引擎"设置查找模板的位置,如下所示(您还必须安装包含模板库的软件包!)

var express = require('express');
var 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('/', function(req, res) {
  res.render('index', { title: 'About dogs', message: 'Dogs rock!' });
});

有关更多信息,请参阅将模板引擎与Express结合使用 (Express docs).

File structure

Express不对结构或使用的组件做任何假设. 路由,视图,静态文件和其他特定于应用程序的逻辑可以存在于具有任何目录结构的任意数量的文件中. 虽然完全可以将整个Express应用程序放在一个文件中,但是通常可以根据功能(例如帐户管理,博客,讨论区)和体系结构问题域(例如模型,视图或控制器)将应用程序拆分为多个文件您碰巧正在使用MVC架构 ).

在后面的主题中,我们将使用Express Application Generator ,它创建了模块化的应用程序框架,我们可以轻松地扩展该框架以创建Web应用程序.

Summary

恭喜,您已经完成Express / Node旅程的第一步! 现在,您应该了解Express和Node的主要优点,以及Express应用程序主要部分的外观(路由,中间件,错误处理和模板代码). 您还应该了解,由于Express是不受限制的框架,因此将这些部分组合在一起的方式以及所使用的库在很大程度上取决于您!

当然,Express故意是一个非常轻量级的Web应用程序框架,因此它的很多好处和潜力都来自第三方库和功能. 我们将在以下文章中更详细地介绍这些内容. 在我们的下一篇文章中,我们将研究如何设置Node开发环境,以便您可以开始观看一些Express代码.

See also

In this module