diff options
Diffstat (limited to 'files/zh-cn/learn/server-side/express_nodejs/skeleton_website/index.html')
-rw-r--r-- | files/zh-cn/learn/server-side/express_nodejs/skeleton_website/index.html | 476 |
1 files changed, 476 insertions, 0 deletions
diff --git a/files/zh-cn/learn/server-side/express_nodejs/skeleton_website/index.html b/files/zh-cn/learn/server-side/express_nodejs/skeleton_website/index.html new file mode 100644 index 0000000000..077b7a3862 --- /dev/null +++ b/files/zh-cn/learn/server-side/express_nodejs/skeleton_website/index.html @@ -0,0 +1,476 @@ +--- +title: Express 教程 2:创建站点框架 +slug: learn/Server-side/Express_Nodejs/skeleton_website +tags: + - Express + - Node + - node.js + - npm + - 入门 + - 初学者 + - 学习 + - 开发环境 + - 服务器端 + - 服务器端编程 +translation_of: Learn/Server-side/Express_Nodejs/skeleton_website +--- +<div>{{LearnSidebar}}</div> + +<p>{{PreviousMenuNext("Learn/Server-side/Express_Nodejs/Tutorial_local_library_website", "Learn/Server-side/Express_Nodejs/mongoose", "Learn/Server-side/Express_Nodejs")}}</p> + +<p class="summary">本节将演示如何创建一个可添加路由、模板/视图、和数据库调用的“骨架”站点。</p> + +<table class="learn-box standard-table"> + <tbody> + <tr> + <th scope="row">预备知识:</th> + <td><a href="/zh-CN/docs/Learn/Server-side/Express_Nodejs/development_environment">配置 Node 开发环境</a>。复习 Express 教程。</td> + </tr> + <tr> + <th scope="row">目标:</th> + <td>掌握用 <strong>Express 应用生成器</strong> 创建站点的方法。</td> + </tr> + </tbody> +</table> + +<h2 id="概览">概览</h2> + +<p>本节演示了如何使用 <a href="http://www.expressjs.com.cn/starter/generator.html">Express 应用生成器</a> 创建一个可添加路由、模板/视图和数据库调用的“骨架”网站。这里我们将使用该生成器为 <a href="/zh-CN/docs/Learn/Server-side/Express_Nodejs/Tutorial_local_library_website">本地图书馆网站</a> 创建框架,以便在以后章节添加其它代码。过程非常简单,只需要在命令行运行 “生成器 + 项目名称” 即可,此外还可以指定站点的模板引擎和 CSS 生成器。</p> + +<p>以下内容介绍了应用生成器的用法,以及视图 / CSS 的一些不同选项。还介绍了骨架站点的组织结构。最后,我们将介绍站点的运行方法,从而对其进行验证。</p> + +<div class="note"> +<p><strong>注:</strong>Express 应用生成器并非唯一的 Express 应用生成工具,而且生成项目的结构也不是组织文件和目录的唯一可行方式。但生成项目具有易于扩展和理解的模块化结构。最简单的 Express 应用请参阅 <a href="http://expressjs.com.cn/starter/hello-world.html">Hello world 示例</a>(Express 镜像站)。</p> +</div> + +<h2 id="使用应用生成器">使用应用生成器</h2> + +<div class="blockIndicator note"> +<p><strong>译注:</strong>本教程中命令操作基于 Linux/macOS 的 bash 终端,Windows 的命令提示符 cmd/PowerShell 与 bash 的概念和用法略有不同, 为在 Windows 上获得一致的体验,可以:</p> + +<ul> + <li>自己弄懂 cmd/PowerShell 与 bash 的区别。</li> + <li>使用 <a href="https://git-scm.com/">Git</a> 或 <a href="http://www.msys2.org/">MSYS2</a> 为 Windows 提供的 bash。(推荐)</li> + <li>使用 Windows 的 Linux 子系统。(到 Microsoft Store 中搜索“Linux”,安装喜欢的版本(Ubuntu 18.04、openSUSE 42、Debian 等),仅限 Windows 10,使用前需要先安装 <a href="https://docs.microsoft.com/en-us/windows/wsl/install-win10">WSL</a>)</li> +</ul> +</div> + +<div class="blockIndicator note"> +<p><strong>译注:</strong>你可能已经发现国内用 NPM 太慢了!这是由众所周知的不可抗力造成的。可用淘宝提供的 <a href="https://npm.taobao.org/">CNPM</a> 代替之,功能和用法基本一致(只是不能上传自己的包)。</p> +</div> + +<p>你应该已经安装好了生成器,它是 <a href="/zh-CN/docs/Learn/Server-side/Express_Nodejs/development_environment">设置 Node 开发环境</a> 的一部分。可以使用 NPM 来安装全局的生成器,如下所示:</p> + +<pre class="brush: bash notranslate">$ sudo npm install express-generator -g</pre> + +<p>生成器有许多选项,可以使用 <code>--help</code>(或 <code>-h</code>)命令进行查看:</p> + +<p><img alt="express 生成器的帮助信息" src="https://mdn.mozillademos.org/files/16407/express-help.png"></p> + +<p>大意如下:</p> + +<pre class="brush: bash notranslate">$ express --help + + 用法:express [选项] [目录] + + 选项: + + --version 打印版本号 + -e, --ejs 添加 ejs 引擎支持 + --pug 添加 pug 引擎支持 + --hbs 添加 handlebars 引擎支持 + -H, --hogan 添加 hogan.js 引擎支持 + -v, --view <engine> 添加 <engine> 试图引擎支持 (ejs|hbs|hjs|jade|pug|twig|vash) (默认为 jade) + -c, --css <engine> 添加 <engine> 样式表引擎支持 (less|stylus|compass|sass) (默认为纯 css) + --git 添加 .gitignore + -f, --force 对非空文件夹强制执行 + -h, --help 打印帮助信息 +</pre> + +<p>可以直接运行 express 命令,将使用 Jade 视图引擎和纯 CSS 在当前目录中创建项目。(如果指定目录名,则在子目录中创建项目)。</p> + +<pre class="brush: bash notranslate">$ express</pre> + +<p>还可以使用 <code>--view</code> 选择视图(模板)引擎,并且/或者使用 <code>--css</code> 选择 CSS 生成引擎。</p> + +<div class="note"> +<p><strong>注:</strong>不推荐用 <code>--hogan</code>、<code>--ejs</code>、<code>--hbs</code> 等参数选用模板引擎。请使用 <code>--view</code>(或 <code>-v</code>)。</p> +</div> + +<h3 id="我应该用哪个视图引擎?">我应该用哪个视图引擎?</h3> + +<p>Express 应用生成器支持多款流行的视图/模板引擎,包括 <a href="https://www.npmjs.com/package/ejs">EJS</a>、<a href="http://github.com/donpark/hbs">Hbs</a>、<a href="https://pugjs.org/api/getting-started.html">Pug</a> (Jade)、<a href="https://www.npmjs.com/package/twig">Twig</a> 和 <a href="https://www.npmjs.com/package/vash">Vash</a>,缺省选项是 Jade。Express 本身也支持大量其他模板语言,<a href="https://github.com/expressjs/express/wiki#template-engines">开箱即用</a>。</p> + +<div class="note"> +<p><strong>注:</strong>如果要使用生成器不支持的模板引擎,请参阅 <a href="http://expressjs.com.cn/guide/using-template-engines.html">在 Express 中使用模板引擎</a>(Express 文档)和所选视图引擎的文档。</p> +</div> + +<p>一般来说,你应该选择一个大而全的模板引擎,可以尽快进入生产状态。就像你选择其他组件一样!选用模板引擎需要考虑以下因素:</p> + +<ul> + <li>进入生产状态的时间——如果你的团队已经有某个模板语言的经验,那么用它可能更快进入生产状态。否则你应该考虑所选模板引擎的学习曲线。</li> + <li>流行度和活跃度——要评估所选引擎的流行程度,以及它是否拥有活跃的社区。在网站的生命周期中遇到问题时,是否能够获得相关支持非常重要。</li> + <li>风格——某些模板引擎使用特定标记,来标识插入“普通” HTML 中的内容,而另一些模板引擎使用不同的语法(例如使用缩进和块名称)构造 HTML。</li> + <li>性能/渲染时间。</li> + <li>功能——你应该考虑所选引擎是否具有以下功能: + <ul> + <li>布局继承:可以定义基本模板,然后 “继承” 它的一部分,使不同页面可以有不同的呈现。这通常比包含大量所需组件,或每次从头开始构建模板更好。</li> + <li>“包含”支持:可以通过包含其他模板来构建新模板。</li> + <li>简明的变量和循环控制语法。</li> + <li>能够在模板级别过滤变量值(例如,将变量设置为大写,或格式化日期值)。</li> + <li>能够生成 HTML 以外的输出格式(例如 JSON 或 XML)。</li> + <li>支持异步操作和流。</li> + <li>可以在同时在客户端和服务器上使用。如果一款模板引擎可以在客户端使用,那么就使在客户端托管数据并完成所有(或大多数)渲染成为可能。</li> + </ul> + </li> +</ul> + +<div class="note"> +<p><strong>提示:</strong>互联网上有许多资源,可帮助你选择合适的视图/模板引擎。</p> +</div> + +<p>本项目选用<a href="https://pugjs.org/api/getting-started.html"> Pug </a>模板引擎(Jade 是它不久前的曾用名),它是最流行的 Express / JavaScript 模板语言之一,且对 Express 生成器 <a href="https://github.com/expressjs/express/wiki#template-engines">开箱即用</a>。</p> + +<h3 id="我应该用哪个_CSS_引擎?">我应该用哪个 CSS 引擎?</h3> + +<p>Express 应用生成器支持最常见的 CSS 引擎:<a href="http://lesscss.org/">LESS</a>, <a href="http://sass-lang.com/">SASS</a>, <a href="http://compass-style.org/">Compass</a>, <a href="http://stylus-lang.com/">Stylus</a>。</p> + +<div class="note"> +<p><strong>注:</strong>CSS 的一些限制导致某些任务完成起来非常困难。CSS 引擎提供了更强大的语法来定义 CSS,然后将定义编译为纯 CSS 供浏览器使用。</p> +</div> + +<p>与模板引擎一样,你也应该使用样式表引擎,这可以最大化团队生产力。本项目将使用原始 CSS(默认的),因为我们对 CSS 要求不复杂,没有必要使用引擎。</p> + +<h3 id="我应该用哪个数据库?">我应该用哪个数据库?</h3> + +<p>生成器生成的代码不使用、也不包含任何数据库。 Express 应用可以使用 Node 支持的所有 <a href="https://expressjs.com/en/guide/database-integration.html">数据库</a>(Express 本身不提供数据库管理机制)。</p> + +<p>我们后续讨论数据库集成问题。</p> + +<h2 id="创建项目">创建项目</h2> + +<p>我们为本地图书馆应用创建一个名为 express-locallibrary-tutorial 的项目,使用 Pug 模板库,不使用 CSS 引擎。</p> + +<p>首先,进入准备放置项目的目录,然后在命令提示符运行 Express 应用生成器,生成器将创建(并列出)项目的文件:</p> + +<p><img alt="用 express 生成器生成一个应用" src="https://mdn.mozillademos.org/files/16408/express.png"></p> + +<p>生成器在最后还告诉你如何安装(<strong>package.json</strong> 中所列的)依赖,以及如何运行该应用。</p> + +<h2 id="运行骨架网站">运行骨架网站</h2> + +<p>现在我们已经拥有一个完整的项目骨架。虽然这个网站现在还做不了什么,但运行一下,展示一下工作原理也是值得的。</p> + +<ol> + <li>首先,安装依赖项(<code>install</code> 命令将获取项目的 <strong>package.json</strong> 文件中列出的所有依赖项包)。 + + <pre class="brush: bash notranslate">$ npm install</pre> + </li> + <li>然后运行该应用。 + <pre class="brush: bash notranslate">$ DEBUG=express-locallibrary-tutorial:* npm start</pre> + </li> + <li>最后在浏览器中导航至 <a href="http://localhost:3000/">http://localhost:3000/</a> ,就可以访问该应用。你应该可以看到: <img alt="Express 应用生成器生成的应用启动成功" src="https://mdn.mozillademos.org/files/16410/success.png"></li> +</ol> + +<p>一个 Express 应用就配置成功了,它托管于 localhost:3000。</p> + +<div class="note"><strong>注:</strong>指定 DEBUG 变量可启用控制台日志记录/调试。例如,当你访问上面的页面时,你会看到像这样的调试输出: <img alt="用 npm start 启动这个应用" src="https://mdn.mozillademos.org/files/16409/npm-start.png"> 直接通过 <code>npm start</code> 命令启动应用也可以,但不会看到调试信息。</div> + +<h2 id="文件改动时重启服务器">文件改动时重启服务器</h2> + +<p>只有重启服务器才能看到 Express 网站所做的改动。每次改动后手动启停服务器实在太烦人了,有必要花点时间让这项工作自动化。</p> + +<p><a href="https://github.com/remy/nodemon">nodemon</a> 是最简便的自动化工具之一。通常将其全局安装(因为它是一个“工具”):</p> + +<pre class="brush: bash notranslate">$ sudo npm install -g nodemon</pre> + +<p>这里还可以把它作为开发依赖将安装在本地,于是使用这个项目的开发人员只要安装这个应用就能自动获得。通过以下命令将其安装在骨架项目的根目录:</p> + +<pre class="brush: bash notranslate">$ npm install --save-dev nodemon</pre> + +<p>项目的 <strong>package.json</strong> 文件将自动添加一个新的属性:</p> + +<pre class="brush: json notranslate"> "devDependencies": { + "nodemon": "^1.18.9" + } +</pre> + +<p>如果没有全局安装该工具,就无法从命令行启动它(除非我们将其添加到路径中),但是可以在 NPM 脚本中调用它,因为 NPM 掌握所有已安装包的信息。找到 package.json 的 <code>scripts</code> 部分。在 <code>"start"</code> 一行的末尾添加逗号,并在新的一行中添加 <code>"devstart"</code>,如下所示:</p> + +<pre class="brush: json notranslate"> "scripts": { + "start": "node ./bin/www"<strong>,</strong> +<strong> "devstart": "nodemon ./bin/www"</strong> + }, +</pre> + +<p>现在可以用新建的 <code>devstart</code> 命令启动服务器:</p> + +<pre class="brush: bash notranslate">$ DEBUG=express-locallibrary-tutorial:* npm <strong>run devstart</strong></pre> + +<p>现在,如果编辑项目中的任何文件,服务器将自动重启(或者可以随时使用 rs 命令来重启)。查看更新后的页面需要点击浏览器的“刷新”按钮。</p> + +<div class="note"> +<p><strong>注:</strong>这里必须使用“<code>npm <strong>run <em><scriptname></em></strong></code>”命令,而不是 <code>npm start</code>,因为 “start” 本质上是映射到脚本的一条 NPM 命令。我们可以在 <code>start</code> 脚本中替换它,但我们只想在开发期间使用 nodemon,因此有必要创建一条新的脚本命令。</p> +</div> + +<h2 id="生成的项目">生成的项目</h2> + +<p>我们来看看刚刚创建的项目。</p> + +<h3 id="目录结构">目录结构</h3> + +<p>安装好依赖项的生成项目具有如下文件结构(<strong>不</strong>带 “/” 前缀的是文件):</p> + +<pre class="notranslate">/express-locallibrary-tutorial + <strong>app.js</strong> + /bin + <strong>www</strong> + <strong>package.json</strong> + /node_modules + [约 4,500 个子文件夹和文件] + /public + /images + /javascripts + /stylesheets + <strong>style.css</strong> + /routes + <strong>index.js</strong> + <strong>users.js</strong> + /views + <strong>error.pug</strong> + <strong>index.pug</strong> + <strong>layout.pug</strong> + +</pre> + +<p><strong>package.json </strong>文件定义依赖项和其他信息,以及一个调用应用入口(<strong>/bin/www</strong>,一个 JavaScript 文件)的启动脚本,脚本中还设置了一些应用的错误处理,加载 <strong>app.js </strong>来完成其余工作。<strong>/routes</strong> 目录中用不同模块保存应用路由。/<strong>views</strong> 目录保存模板。</p> + +<p>下面来详细介绍这些文件。</p> + +<h3 id="package.json">package.json</h3> + +<p><strong>package.json </strong>文件中定义了应用依赖和其他信息:</p> + +<pre class="brush: json notranslate">{ + "name": "express-locallibrary-tutorial", + "version": "0.0.0", + "private": true, + "scripts": { + "start": "node ./bin/www" + "devstart": "nodemon ./bin/www" + }, + "dependencies": { + "cookie-parser": "~1.4.3", + "debug": "~2.6.9", + "express": "~4.16.0", + "http-errors": "~1.6.2", + "morgan": "~1.9.0", + "pug": "2.0.0-beta11" + }, + "devDependencies": { + "nodemon": "^1.18.9" + } +} +</pre> + +<p>依赖包括 <em>express</em> 包,和选用的视图引擎包(<em>pug</em>)。还有以下一些实用的包:</p> + +<ul> + <li><a href="https://www.npmjs.com/package/cookie-parser">cookie-parser</a>:用于解析 cookie 头来填充 <code>req.cookies</code>(提供了访问 cookie 信息的便捷方法)。</li> + <li><a href="https://www.npmjs.com/package/debug">debug</a>:一个小型 node 调试程序,仿照 node 核心的调试技术建立。</li> + <li><a href="https://www.npmjs.com/package/http-errors">http-errors</a>:处理错误中间件。</li> + <li><a href="https://www.npmjs.com/package/morgan">morgan</a>:node 专用 HTTP 请求记录器中间件。</li> +</ul> + +<p>"<code>scripts</code>" 部分,定义了一个 "<code>start</code>" 脚本,当运行 <code>npm start</code> 时会调用它来启动服务器。在脚本定义中可以看到 <code>start</code> 实际上运行了 "node <strong>./bin/www"</strong>。还有一个 "<code>devstart</code>" 脚本,可以通过运行 <code>npm run devstart</code> 来运行 "nodemon <strong>./bin/www</strong>"。</p> + +<pre class="brush: json notranslate"> "scripts": { + "start": "node ./bin/www", + "devstart": "nodemon ./bin/www" + }, +</pre> + +<h3 id="www_文件">www 文件</h3> + +<p>文件 <strong>/bin/www </strong>是应用入口!它做的第一件事是 <code>require()</code> “真实” 的应用入口(即项目根目录中的 <strong>app.js</strong> ),<strong>app.js </strong>会设置并返回 <code><a href="http://expressjs.com/en/api.html">express()</a></code><a href="http://expressjs.com/en/api.html"> </a>应用对象。</p> + +<pre class="brush: js notranslate">#!/usr/bin/env node + +/** + * Module dependencies. + * 模块依赖项。 + */ + +<strong>var app = require('../app');</strong> +</pre> + +<div class="note"> +<p><strong>注:</strong><code>require()</code> 是一个全局的 node 函数,可将模块导入当前文件。这里使用相对路径指定<strong> app.js</strong> 模块,并省略了 .<strong>js</strong> 扩展名(可选)。</p> +</div> + +<p>文件的其余部分先为 <code>app</code> 设置端口(环境变量中的预定义值或默认值 3000),再创建一个 HTTP 服务器,然后开始监听请求,报告服务器错误和连接信息。其它内容可暂时忽略(这里所有内容都是机器生成的模板),但感兴趣的话可以随时回来看看。</p> + +<h3 id="app.js">app.js</h3> + +<p>此文件创建一个 <code>express</code> 应用对象(依照惯例命名为 <code>app</code>),通过各种设置选项和中间件来设置这个应用,然后从该模块中导出。以下代码只展示了文件中创建和导出应用对象的部分:</p> + +<pre class="brush: js notranslate"><code>var express = require('express'); +var app = express(); +... +</code>module.exports = app; +</pre> + +<p>上文的<strong> www</strong> 入口文件中 <code>require()</code> 的 <code>app</code> 就是这里导出的 。</p> + +<p>我们来详细了解一下<strong> app.js</strong> 文件。首先,它使用 <code>require()</code> 导入了一些实用 node 库,其中包括之前用 NPM 下载的 <code>express</code>,<code>http-errors</code>,<code>morgan</code> 和 <em><code>cookie-parser</code>,还有一个 </em><em><code>path</code> </em>库,它是用于解析文件和目录的核心 node 库。</p> + +<pre class="brush: js notranslate">var express = require('express'); +var createError = require('http-errors'); +var logger = require('morgan'); +var cookieParser = require('cookie-parser'); +var path = require('path'); +</pre> + +<p>然后 <code>require()</code> 的是用户路由目录中的模块。这些模块/文件用于处理特定的“路由”(URL 路径)。可以通过添加新文件来扩展骨架应用,比如添加图书相关的路由来列出所有馆藏书目。</p> + +<pre class="brush: js notranslate">var indexRouter = require('./routes/index'); +var usersRouter = require('./routes/users'); +</pre> + +<div class="note"> +<p><strong>注意:</strong> 此时我们刚刚导入了模块;还没有真正使用过其中的路由(稍后会使用)。</p> +</div> + +<p>下面我们用导入的 <code>express</code> 模块来创建 <code>app</code> 对象,然后使用它来设置视图(模板)引擎。设置引擎分两步:首先设置 '<code>views</code>' 以指定模板的存储文件夹(此处设为子文件夹 <strong>/views</strong>)。然后设置 '<code>view engine</code>' 以指定模板库(本例中设为 “pug” )。</p> + +<pre class="brush: js notranslate">var app = express(); + +// view engine setup +// 视图引擎设定 +app.set('views', path.join(__dirname, 'views')); +app.set('view engine', 'pug'); +</pre> + +<p>下一组 <code>app.use()</code> 调用将中间件库添加进请求处理链。除了之前导入的第三方库之外,我们还使用 <code>express.static</code> 中间件将项目 <strong>/public</strong> 目录下所有静态文件托管至根目录。</p> + +<pre class="brush: js notranslate">app.use(logger('dev')); +app.use(express.json()); +app.use(express.urlencoded({ extended: false })); +app.use(cookieParser()); +<strong>app.use(express.static(path.join(__dirname, 'public')));</strong> +</pre> + +<p>所有中间件都已设置完毕,现在把(之前导入的)路由处理器添加到请求处理链中。从而为网站的不同部分定义具体的路由:</p> + +<pre class="brush: js notranslate">app.use('/', indexRouter); +app.use('/users', usersRouter); +</pre> + +<div class="note"> +<p><strong>注:</strong>这些路径(<code>'/'</code> 和 '<code>/users'</code>)将作为导入路由的前缀。如果导入的模块 <code>users<font face="x-locale-heading-primary, zillaslab, Palatino, Palatino Linotype, x-locale-heading-secondary, serif"><span style="background-color: #fff3d4;">在</span></font></code><code>/profile</code> 定义了路由,则可以在 <code>/users/profile</code> 访问该路由。我们将在后面的文章中,详细讨论路由。</p> +</div> + +<p>最后一个中间件为错误和 HTTP 404 响应添加处理方法。</p> + +<pre class="brush: js notranslate">// catch 404 and forward to error handler +// 捕获 404 并抛给错误处理器 +app.use(function(req, res, next) { + next(createError(404)); +}); + +// error handler +// 错误处理器 +app.use(function(err, req, res, next) { + // set locals, only providing error in development + // 设置 locals,只在开发环境提供错误信息 + res.locals.message = err.message; + res.locals.error = req.app.get('env') === 'development' ? err : {}; + + // render the error page + // 渲染出错页面 + res.status(err.status || 500); + res.render('error'); +}); +</pre> + +<p>Express 应用对象(<code>app</code>)现已完成配置。最后一步是将其添加到 <code>exports</code> 模块(使它可以通过 <strong>/bin/www </strong>导入)。</p> + +<pre class="brush: js notranslate">module.exports = app;</pre> + +<h3 id="路由">路由</h3> + +<p>路由文档 <strong>/routes/users.js </strong>如下所示(由于路由文件均使用类似结构,所以 <strong>index.js</strong> 略过不讲)。首先加载 <code>express</code> 模块并获取 <code>express.Router</code> 对象(命名为 <code>router</code>)。然后为 <code>router</code> 指定路由,最后导出 <code>router</code>(就可以导入 <strong>app.js</strong> 了)。</p> + +<pre class="brush: js notranslate">var express = require('express'); +var router = express.Router(); + +/* GET users listing. */ +<strong>router.get('/', function(req, res, next) { + res.send('respond with a resource'); +});</strong> + +module.exports = router; +</pre> + +<p>该路由定义了一个回调,在检测到正确模式的 HTTP <code>GET</code> 请求时将调用该回调。正确模式即导入模块时指定的路由('<code>/users</code>')加该模块('<code>/</code>')中定义的任何内容。换句话说,在收到 <code>/users/</code> URL 时使用此路由。</p> + +<div class="note"> +<p><strong>提示:</strong>用 node 启动该应用并访问 <a href="http://localhost:3000/users/">http://localhost:3000/users/</a>,浏览器会返回一条消息:'respond with a resource'。</p> +</div> + +<p>值得注意的是,上述回调函数有第三个参数 '<code>next</code>',因此它是一个中间件函数,而不是简单的路由回调。<code>next</code> 参数暂时还用不到,在 <code>'/'</code> 路径中添加多个路由处理器时才会涉及。</p> + +<h3 id="视图(模板)">视图(模板)</h3> + +<p>视图(模板)存保存在 <strong>/views</strong> 目录中( <strong>app.js</strong> 中指定),使用 <strong>.pug </strong>扩展名。 <code><a href="http://expressjs.com/en/4x/api.html#res.render">Response.render()</a></code> 方法用某对象的某个变量值一同来渲染一个特定的模板,然后将结果作为响应发送。在 <strong>/routes/index.js</strong> 中可以看到,该路由使用 '<code>index</code>' 模板和一个模板变量 <code>title</code> 来渲染响应。</p> + +<pre class="brush: js notranslate">/* GET home page. */ +router.get('/', function(req, res) { + res.render('index', { title: 'Express' }); +}); +</pre> + +<p>以下是上文代码中涉及到的模板(<strong>index.pug</strong>)。pug 语法稍后再详细讨论。现在只需要知道:<code>title</code> 变量将以 <code>'Express'</code> 作为值插入模板的指定位置。</p> + +<pre class="notranslate">extends layout + +block content + h1= title + p Welcome to #{title} +</pre> + +<h2 id="挑战自我">挑战自我</h2> + +<p>在 <strong>/routes/users.js</strong> 中添加一个新路由,在URL <code>/users/cool/</code> 处显示文本 "你好酷"。运行服务器,并在浏览器中访问 <a href="http://localhost:3000/users/cool/">http://localhost:3000/users/cool/ </a>,测试一下是否成功。</p> + +<ul> +</ul> + +<h2 id="小结">小结</h2> + +<p>现在你已经为 <a href="/zh-CN/docs/Learn/Server-side/Express_Nodejs/Tutorial_local_library_website">本地图书馆</a> 创建好了骨架,并且成功在 node 上运行起来。同时最重要的是,你了解了项目的结构,从而了解了如何为本地图书馆添加路由和视图。</p> + +<p>下一节我们开始修改骨架,让它具备一些图书馆网站的功能。</p> + +<h2 id="另请参阅">另请参阅</h2> + +<ul> + <li><a href="http://www.expressjs.com.cn/starter/generator.html">Express 应用生成器</a> (Express 中文镜像文档)</li> + <li><a href="http://www.expressjs.com.cn/guide/using-template-engines.html">在 Express 中使用模板引擎</a>(Express 镜像文档)</li> +</ul> + +<p>{{PreviousMenuNext("Learn/Server-side/Express_Nodejs/Tutorial_local_library_website", "Learn/Server-side/Express_Nodejs/mongoose", "Learn/Server-side/Express_Nodejs")}}</p> + +<h2 id="本章目录">本章目录</h2> + +<ul> + <li><a href="/zh-CN/docs/Learn/Server-side/Express_Nodejs/Introduction">Express/Node 入门</a></li> + <li><a href="/zh-CN/docs/Learn/Server-side/Express_Nodejs/development_environment">设置 Node(Express)开发环境</a></li> + <li><a href="/zh-CN/docs/Learn/Server-side/Express_Nodejs/Tutorial_local_library_website">Express 教程:本地图书馆网站</a></li> + <li><a href="/zh-CN/docs/Learn/Server-side/Express_Nodejs/skeleton_website">Express 教程 2:创建站点框架</a></li> + <li><a href="/zh-CN/docs/Learn/Server-side/Express_Nodejs/mongoose">Express 教程 3:使用数据库(Mongoose)</a></li> + <li><a href="/zh-CN/docs/Learn/Server-side/Express_Nodejs/routes">Express 教程 4:路由和控制器</a></li> + <li><a href="/zh-CN/docs/Learn/Server-side/Express_Nodejs/Displaying_data">Express 教程 5:显示图书馆数据</a></li> + <li><a href="/zh-CN/docs/Learn/Server-side/Express_Nodejs/forms">Express 教程 6:使用表单</a></li> + <li><a href="/zh-CN/docs/Learn/Server-side/Express_Nodejs/deployment">Express 教程 7:部署至生产环境</a></li> +</ul> |