codecamp

Express Tutorial Part 2: Creating a skeleton website

先决条件: 设置节点开发环境 查看快速教程。
目的: 要使用快速应用程序生成器启动您自己的新网站项目。

概述

本文介绍如何使用 Express应用生成器工具创建"骨架"网站, 然后您可以填充站点特定的路由,视图/模板和数据库调用。 在这种情况下,我们将使用该工具为我们的本地图书馆网站创建框架,我们稍后会将所需的所有其他代码添加到 现场。 该过程非常简单,只需要在命令行上使用新的项目名称调用生成器,也可以指定网站的模板引擎和CSS生成器。

以下部分显示如何调用应用程序生成器,并提供有关不同视图/ CSS选项的一些说明。 我们还将解释骨架网站的结构。 最后,我们将展示如何运行网站以验证其是否有效。

注意:Express应用程序生成器不是Express应用程序的唯一生成器,生成的项目不是唯一的 可行的方式来构造您的文件和目录。 然而,生成的站点具有容易扩展和理解的模块化结构。 有关最低 Express应用程序的信息,请参阅 Hello world示例 a>(Express docs)。

使用应用程序生成器

您应该已经将生成器作为设置Node开发环境的一部分安装。 作为一个快速提醒,您可以使用NPM软件包管理器在站点范围内安装生成器工具,如图所示:

npm install express-generator -g

生成器有很多选项,您可以使用 - help (或 -h )命令在命令行中查看这些选项:

> express --help

  Usage: express [options] [dir]

  Options:

    -h, --help           output usage information
        --version        output the version number
    -e, --ejs            add ejs engine support
        --pug            add pug engine support
        --hbs            add handlebars engine support
    -H, --hogan          add hogan.js engine support
    -v, --view <engine>  add view <engine> support (ejs|hbs|hjs|jade|pug|twig|vash) (defaults to jade)
    -c, --css <engine>   add stylesheet <engine> support (less|stylus|compass|sass) (defaults to plain css)
        --git            add .gitignore
    -f, --force          force on non-empty directory

您可以使用 Jade 视图引擎和纯CSS( 目录中简单指定 express 该项目将在具有该名称的子文件夹中创建)。

express

您还可以使用 - view 和/或使用 - css 的CSS生成引擎选择视图(模板)引擎。

注意:选择模板引擎的其他选项(例如 - hgan - ejs - hbs 等等)已被弃用。 使用 - view (或 -v )!

我应该使用什么视图引擎?

Express应用程序生成器 允许您配置一些流行的视图/模板引擎,包括 EJS , Hbs .org / api / getting-started.html"> Pug (Jade), Twig >和 Vash ,但如果您未指定视图选项,则默认选择Jade。 Express本身也可以支持大量其他模板语言开箱即用

注意:如果您要使用生成器不支持的模板引擎,请参阅 -template-engines.html">使用带有Express的模板引擎(Express docs)和目标视图引擎的文档。

一般来说,你应该选择一个模板引擎,提供你需要的所有功能,并允许你更快的生产效率,换句话说,就像你选择任何其他组件一样! 比较模板引擎时需要考虑的一些事情:

  • Time to productivity — If your team already has experience with a templating language then it is likely they will be productive faster using that language. If not, then you should consider the relative learning curve for candidate templating engines.
  • Popularity and activity — Review the populartity of the engine and whether it has an active community. It is important to be able to get support for the engine when you have problems over the lifetime of the website.
  • Style — Some template engines use specific markup to indicate inserted content within "ordinary" HTML, while others construct the HTML using a different syntax (for example, using indentation and block names).
  • Performance/rendering time.
  • Features — you should consider whether the engines you look at have the following features available:
    • Layout inheritence: Allows you to define a base template and then "inherit" just the parts of it that you want to be different for a particular page. This is typically a better approach than building templates by including a number of required components, or building a template from scratch each time.
    • "Include" support: Allows you to build up templates by including other templates.
    • Concise variable and loop control syntax.
    • Ability to filter variable values at template level (e.g. making variables upper-case, or formatting a date value).
    • Ability to generate output formats other than HTML (e.g. JSON or XML).
    • Support for asynchronous operations and streaming.
    • Can be used on the client as well as the server. If a templating engine can be used on the client this allows the possibility of serving data and having all or most of the rendering done client-side.

提示:Internet上有许多资源可帮助您比较不同的选项!

对于此项目,我们将使用 Pug 模板引擎(这是最近更名的Jade 引擎),因为这是最流行的Express / JavaScript模板语言之一,并且由生成器支持开箱即用。

我应该使用什么CSS样式表引擎?

Express应用程序生成器 允许您创建配置为使用最常见的CSS样式表引擎的项目: LESS SASS .org /">指南针 Stylus

注意: CSS有一些限制,使某些任务变得困难。 CSS样式表引擎允许您使用更强大的语法来定义CSS,然后将定义编译为普通CSS以供浏览器使用。

与模板引擎一样,您应该使用样式表引擎,使您的团队最有效率。 对于这个项目,我们将使用普通CSS(默认),因为我们的CSS需求不够复杂,不能使用任何其他东西。

我应该使用什么数据库?

生成的代码不使用/包括任何数据库。 应用程式可以使用任何资料库机制, em> Node ( 本身并没有定义数据库管理的任何特定附加行为/要求)。

我们将在后面的文章中讨论如何与数据库集成。

创建项目

对于我们要创建的示例本地库应用程序,我们将使用 Pug 模板创建一个名为 express-locallibrary-tutorial 的项目 库和没有CSS样式表引擎。

首先导航到您要创建项目的位置,然后在命令提示符下运行 Express Application Generator ,如下所示:

express express-locallibrary-tutorial --view=pug

生成器将创建(并列出)项目的文件。

   create : express-locallibrary-tutorial
   create : express-locallibrary-tutorial/package.json
   create : express-locallibrary-tutorial/app.js
   create : express-locallibrary-tutorial/public/images
   create : express-locallibrary-tutorial/public
   create : express-locallibrary-tutorial/public/stylesheets
   create : express-locallibrary-tutorial/public/stylesheets/style.css
   create : express-locallibrary-tutorial/public/javascripts
   create : express-locallibrary-tutorial/routes
   create : express-locallibrary-tutorial/routes/index.js
   create : express-locallibrary-tutorial/routes/users.js
   create : express-locallibrary-tutorial/views
   create : express-locallibrary-tutorial/views/index.pug
   create : express-locallibrary-tutorial/views/layout.pug
   create : express-locallibrary-tutorial/views/error.pug
   create : express-locallibrary-tutorial/bin
   create : express-locallibrary-tutorial/bin/www

   install dependencies:
     > cd express-locallibrary-tutorial && npm install

   run the app:
     > SET DEBUG=express-locallibrary-tutorial:* & npm start

在输出结束时,生成器提供有关如何安装依赖关系(如 package.json 文件中所列)以及如何运行应用程序的说明(以上说明适用于Windows;在Linux上 / Mac OS X,他们会略有不同)。

运行骨架网站

在这一点上,我们有一个完整的骨架项目。 网站实际上并不实际,但是值得运行它来显示它的工作原理。

  1. First install the dependencies (the install command will fetch all the dependency packages listed in the project's package.json file).
    cd express-locallibrary-tutorial
    npm install
  2. Then run the application.
    • On Windows, use this command:
      SET DEBUG=express-locallibrary-tutorial:* & npm start
    • On Mac OS X or Linux, use this command:
      DEBUG=express-locallibrary-tutorial:* npm start
      
  3. Then load http://localhost:3000/ in your browser to access the app.

您应该会看到如下所示的浏览器页面:

您有一个工作中的Express应用程序,本身服务于 localhost:3000

注意:您也可以使用 npm start 命令启动应用。 如图所示指定DEBUG变量可启用控制台日志记录/调试。 例如,当您访问上述页面时,您将看到如下所示的调试输出:

>SET DEBUG=express-locallibrary-tutorial:* & npm start

> express-locallibrary-tutorial@0.0.0 start D:\express-locallibrary-tutorial
> node ./bin/www

  express-locallibrary-tutorial:server Listening on port 3000 +0ms
GET / 200 288.474 ms - 170
GET /stylesheets/style.css 200 5.799 ms - 111
GET /favicon.ico 404 34.134 ms - 1335

对文件更改启用服务器重新启动

您对Express网站所做的任何更改目前在重新启动服务器之前都不可见。 每次进行更改时,都必须停止并重新启动服务器,所以很有必要花时间在需要时自动重新启动服务器。

用于此目的的最简单的此类工具之一是 nodemon 。 这通常是安装在全局(因为它是一个"工具"),但在这里我们将安装和使用它作为一个开发人员依赖,所以任何开发人员工作时, 安装应用程序。 在骨干项目的根目录中使用以下命令:

npm install --save-dev nodemon

如果您打开项目的 package.json 文件,您将看到一个包含此依赖关系的新部分:

  "devDependencies": {
    "nodemon": "^1.11.0"
  }

由于该工具未全局安装,因此无法从命令行启动(除非将其添加到路径中),但是我们可以从NPM脚本调用它,因为NPM知道所有已安装的软件包。 将粗体显示的线和逗号添加到package.json的scripts部分(注意逗号被添加到上一行!):

  "scripts": {
    "start": "node ./bin/www",
    "devstart": "nodemon ./bin/www"
  },

我们现在可以以与以前几乎完全相同的方式启动服务器,但是以下添加以粗体显示如下:

SET DEBUG=express-locallibrary-tutorial:* & npm run devstart

现在如果编辑项目中的任何文件,服务器将重新启动(或者您可以在任何时候在命令提示符下键入 rs 重新启动它)。 您仍然需要重新加载浏览器以刷新页面。

注意:我们现在必须调用" npm run < scriptname> ",而不是仅仅 npm start "start"实际上是映射到命名脚本的NPM命令。 我们可以替换启动脚本中的命令,但我们只想在开发期间使用 nodemon ,因此创建一个新的脚本命令是有意义的。

生成的项目

让我们来看看我们刚刚创建的项目。

目录结构

生成的项目,现在您已安装依赖项,具有以下文件结构(文件是前缀"/"的项目)。 package.json 文件定义应用程序依赖性和其他信息。 它还定义了一个启动脚本,它将调用应用程序入口点,JavaScript文件 / bin / www 。 这会设置一些应用程序错误处理,然后加载 app.js 以完成其余工作。 应用程序路径存储在 routes / 目录下的单独模块中。 模板存储在/ 视图目录下。

/express-locallibrary-tutorial
    app.js
    /bin
        www
    package.json
    /node_modules
        [about 4,500 subdirectories and files]
    /public
        /images
        /javascripts
        /stylesheets
            style.css
    /routes
        index.js
        users.js
    /views
        error.pug
        index.pug
        layout.pug
    

以下部分将更详细地描述文件。

package.json

package.json 文件定义应用程序依赖性和其他信息:

{
  "name": "express-locallibrary-tutorial",
  "version": "0.0.0",
  "private": true,
  "scripts": {
    "start": "node ./bin/www",
    "devstart": "nodemon ./bin/www"
  },
  "dependencies": {
    "body-parser": "~1.15.2",
    "cookie-parser": "~1.4.3",
    "debug": "~2.2.0",
    "express": "~4.14.0",
    "morgan": "~1.7.0",
    "pug": "~2.0.0-beta6",
    "serve-favicon": "~2.3.0"
  },
  "devDependencies": {
    "nodemon": "^1.11.0"
  }
}

相关性包括 express 包和我们所选视图引擎( pug )的包。 此外,我们有以下包在许多Web应用程序中有用:

  • body-parser: This parses the body portion of an incoming HTTP request and makes it easier to extract different parts of the contained information. For example, you can use this to read POST parameters.
  • cookie-parser: Used to parse the cookie header and populate req.cookies (essentially provides a convenient method for accessing cookie information).
  • debug: A tiny node debugging utility modelled after node core's debugging technique.
  • morgan: An HTTP request logger middleware for node.
  • serve-favicon: Node middleware for serving a favicon (this is the icon used to represent the site next inside the browser tab, bookmarks, etc.).

脚本部分定义了一个" start "脚本,这是我们在调用 npm start 启动服务器时调用的脚本。 从脚本定义中,您可以看到,这实际上会使用节点启动JavaScript文件 ./ bin / www 。 它还定义了一个" devstart "脚本,我们在调用 npm run devstart 时调用它。 这会启动相同的 ./ bin / www 文件,但使用 nodemon 而不是节点

  "scripts": {
    "start": "node ./bin/www",
    "devstart": "nodemon ./bin/www"
  },

www文件

文件 / bin / www 是应用程序入口点! 这样做的第一件事是 require()在项目根目录中的"真实"应用程序入口点( app.js ),设置并返回 express() 应用程序对象。

#!/usr/bin/env node

/**
 * Module dependencies.
 */

var app = require('../app');

注意: require()是一个全局节点函数,用于将模块导入到当前文件中。 在这里,我们使用相对路径并省略可选(。 js )文件扩展名来指定 app.js 模块。

此文件中的其余代码将设置一个节点HTTP服务器,并将 app 设置为特定端口(在环境变量中定义,如果变量未定义,则为3000),并开始侦听和报告 服务器错误和连接。 现在你不需要知道任何关于代码(这个文件中的一切都是"样板"),但随时审查它,如果你有兴趣。

app.js

此文件创建一个 express 应用程序对象(按照惯例名为 app ),使用各种设置和中间件设置应用程序,然后从模块导出应用程序。 下面的代码仅显示了创建和导出应用程序对象的文件部分:

var express = require('express');
var app = express();
...
module.exports = app;

回到上面的 www 入口点文件,这是导入此文件时提供给调用方的 module.exports 对象。

让我们详细了解 app.js 文件。 首先,我们使用 require()将一些有用的节点库导入到文件中,包括 ,,serve-favicon 我们之前使用NPM为我们的应用程序下载的 cookie-parser body-parser path 解析文件和目录路径。

var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');

然后我们从我们的routes目录下的 require()模块。 这些模块/文件包含用于处理相关"路由"(URL路径)的特定集合的代码。 当我们扩展框架应用程序时,例如列出库中的所有图书,我们将添加一个新文件来处理与书相关的路线。

var index = require('./routes/index');
var users = require('./routes/users');

注意:此时,我们只需导入模块; 我们还没有实际使用它的路由(这发生只是一点点下文件)。

接下来,我们使用导入的 express 模块创建 app 对象,然后使用它来设置视图(模板)引擎。 设置发动机有两个部分。 首先,我们设置" views "值来指定存储模板的文件夹(在这种情况下是子文件夹 / views )。 然后我们设置\'视图引擎\'值来指定模板库(在这种情况下为"pug")。

var app = express();

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'pug');

下一组函数调用 app.use()中间件库添加到请求处理链中。 除了我们先前导入的第三方库,我们使用 Express.static 中间件来获取 Express 来提供目录中的所有静态文件 / public / strong>。

// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));

现在所有其他中间件都已设置好,我们将(先前导入的)路由处理代码添加到请求处理链。 导入的代码将定义网站的不同部分的特定路由:

app.use('/', index);
app.use('/users', users);

注意:上面指定的路径(\'/\'和\' / users\')将被视为导入文件中定义的路由的前缀。 因此,例如,如果导入的用户模块为 / profile 定义了一个路由,您将在 / users / profile 访问该路由。 我们将在后面的文章中更多地讨论路由。

文件中的最后一个中间件为错误和HTTP 404响应添加了处理程序方法。

// catch 404 and forward to error handler
app.use(function(req, res, next) {
  var err = new Error('Not Found');
  err.status = 404;
  next(err);
});

// error handler
app.use(function(err, req, res, next) {
  // set locals, only providing error in development
  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');
});

Express应用程序对象(应用程序)现已完全配置。 最后一步是将它添加到模块导出(这是允许它通过 / bin / www 导入)。

module.exports = app;

路线

路线文件 /routes/users.js 如下所示(路线文件共享相似的结构,因此我们不需要也显示 index.js )。 首先它加载 express 模块,并使用它来获取一个 express.Router 对象。 然后它在该对象上指定一个路由,最后从模块中导出路由器(这是允许将文件导入 app.js )的路由器。

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

/* GET users listing. */
router.get('/', function(req, res, next) {
  res.send('respond with a resource');
});

module.exports = router;

路由定义了一个回调,只要检测到具有正确模式的HTTP GET 请求,就会调用该回调。 匹配模式是在导入模块时指定的路由(\' / users \')加上此文件中定义的任何内容(\' / \')。 换句话说,当接收到 / users / 的URL时,将使用此路由。

提示:尝试通过运行带有节点的服务器并访问浏览器中的网址: http: // localhost:3000 / users / 。 您应该看到一条消息:"使用资源响应"。

上面感兴趣的一个事情是回调函数有第三个参数\' next \',因此是一个中间件函数,而不是一个简单的路由回调。 没有明显的原因,因为代码不使用 next 参数,并没有它工作正常。

视图(模板)

视图(模板)存储在 / views 目录中(如 app.js 中所指定),文件扩展名为 .pug 。 方法 Response.render() 是 用于渲染指定的模板以及在对象中传递的命名变量的值,然后将结果作为响应发送。 在下面的 /routes/index.js 代码中,您可以看到该路由如何使用传递模板变量"title"的模板"index"呈现响应。

/* GET home page. */
router.get('/', function(req, res, next) {
  res.render('index', { title: 'Express' });
});

下面给出了上述路线的相应模板( index.pug )。 稍后我们将更多地讨论语法。 所有你需要知道的是,标题变量(值为"Express")插入到模板中指定的位置。

extends layout

block content
  h1= title
  p Welcome to #{title}

挑战自己

/routes/users.js 中创建一个新路线,将在网址 / users / cool / 上显示文字" >。 通过运行服务器并访问 http:// localhost:3000 / users / cool / ,测试它 浏览器

    概要

    您现在已为本地库创建了一个骨架网站项目,并验证其是否使用节点运行。 最重要的是,您也了解项目的结构,所以您有一个好主意,我们需要更改添加路线和视图为我们的本地图书馆。

    接下来,我们将开始修改骨架,使其成为一个图书馆网站。

    也可以看看

    Express Tutorial Part 7: Deploying to production
    Express Tutorial Part 3: Using a Database (with Mongoose)
    温馨提示
    下载编程狮App,免费阅读超1000+编程语言教程
    取消
    确定
    目录
    CSS

    关闭

    MIP.setData({ 'pageTheme' : getCookie('pageTheme') || {'day':true, 'night':false}, 'pageFontSize' : getCookie('pageFontSize') || 20 }); MIP.watch('pageTheme', function(newValue){ setCookie('pageTheme', JSON.stringify(newValue)) }); MIP.watch('pageFontSize', function(newValue){ setCookie('pageFontSize', newValue) }); function setCookie(name, value){ var days = 1; var exp = new Date(); exp.setTime(exp.getTime() + days*24*60*60*1000); document.cookie = name + '=' + value + ';expires=' + exp.toUTCString(); } function getCookie(name){ var reg = new RegExp('(^| )' + name + '=([^;]*)(;|$)'); return document.cookie.match(reg) ? JSON.parse(document.cookie.match(reg)[2]) : null; }