每日一博 | 利用 Express.js 写 To-Do 应用

声明

  1. 本系列教程是博主学习Express.js的笔记。结合了 Pro Express.jsGetting MEANLearning JavaScript, 3nd Edition 三部书的内容。

  2. 本系列教程的主要内容是利用Express.js写一个待办清单(To-Do)网络应用。详细的项目说明见下一节。

  3. 各节点和最终代码见 本项目的Github页面

项目要求(Project Specifications)

  1. 本网页应用一共有三个页面:“主页”,“待办事项”,“已完成”。有一个始终置顶的导航条以供在各页面间跳转。
  2. “主页”上显示欢迎和说明。
  3. “待办事项”上逐行显示所有待办的事项;如果列表为空,则显示“无待办事项”。用户可以添加新事:所添加的会即时显示到清单最后;也可以删除/完成已有事项:所操作事项会从清单中移除。
  4. “已完成”上依照完成的时间顺序现实用户完成的事项。

建立开发环境

使用技术

  1. MEAN架构:除了Angular.js
  2. Jade
  3. Mongoose
  4. Less
  5. AJAX/XHR

安装Node.js

请参考 Node.js官网 。本教程使用的是4.40 LTS版本。安装完成后,运行

node --version

npm --version

,如果能得到正确的版本信息,则安装成功。

安装Express.js

`bash
sudo npm install -g express

`

express --version

正确返回版本信息则说明安装成功。本教程所用的版本是4.13.1。

初始化应用

为应用新建根目录

todo-express

并进入其下,本系列教程中的所有命令,除非特别指出,都是在该目录下执行的。

新建

package.json

文件,写入如下内容:

`json
{
"name": "todo-express",
"version": "0.1.0",
"private": true,
"scripts": {
"start": "node dist/app.js"
},
"dependencies": {
"express": "~4.8.1",
"jade": "~1.5.0",
"morgan": "~1.2.3"
}
}

`

然后运行

npm install

,安装所有的依赖包。

安装并配置Babel

本应用将使用ECMAScript 2015开发,并用Babel来转译成ES5。

`bash
npm install --save-dev babel-preset-es2015

`

新建

.babelrc

文件,其内容为:

`json
{ "presets": ["es2015"] }

`

安装并配置ESlint

ESlint 能帮我们统一代码风格、找出潜在的bug。

`bash
sudo npm install -g eslint

`

然后运行

eslint --init

,如下回答所提问题:

  • Answer questions about your style
  • 使用ES6特性
  • 使用ES6 modules
  • 全选Node和Browser
  • 不使用CommonJS
  • 不使用JSX
  • 空格缩进(依自己的风格设定)
  • 双引号string(依自己的风格设定)
  • Unix行尾(依自己的环境设定)
  • 不能省略分号(依自己的风格设定)
  • 配置文件用JSON格式

这会新建一个

.eslintrc.json

文件,打开这个文件,在

"rules"

的最后添加如下规则:

`json
"rules": {
...,
"no-unused-vars": [
2,
{
"vars": "all",
"args": "after-used",
"varsIgnorePattern": "_UNUSED$",
"argsIgnorePattern": "^_"
}
]
}

`

安装并配置Gulp

`bash
sudo npm install -g gulp
npm install --save-dev gulp
npm install --save-dev gulp-babel
npm install --save-dev gulp-eslint

`

新建

gulpfile.js

文件,其内容为:

```js const gulp = require("gulp"); const babel = require("gulp-babel"); const eslint = require("gulp-eslint");

// 所有es6文件夹所在的位置 const folders = [];

gulp.task("default", () => { folders.map(folder => { gulp.src(

${folder}/es6/**/*.js

) .pipe(eslint()) .pipe(eslint.format()) .pipe(babel()) .pipe(gulp.dest(

${folder}/dist

)); }); }); // end of "default" task ```

这之后运行

gulp

,就可以自动完成代码风格检查和转移。

安装nodemon

开发过程中,每次修改代码都需要停止再重启应用,太过麻烦,所以我们需要安装nodemon。

`bash
sudo npm install -g nodemon

`

之后运行应用不再使用

npm start

,而是用

nodemon

。这样当代码发生变化时,nodemon可以自动重启应用。我们只需要在另一个命令行里执行

gulp

命令就行,非常方便。

版本控制

运行

git init

,之后新建

.gitignore

文件,其内容为:

```

logs

.log

dependencies

node_modules

temporary files

* / .tmp * / ~

transcompiled files

**/dist ```

再然后

add

commit

,我们就建成了一个空白的Express应用的模版,接下来开始正式写代码了。

Hello Express.js

我们分四步来完成这个应用: 1. 写一个简单的主页。借此熟悉Express应用的主要结构和Jade基本语法。 2. 写个静态的网站。包括所有三个页面,但此时数据都在view层。 3. 把数据移到controller层,完成大部分controller 4. 把数据移到数据库中,写RESTful API,完成model层及整个应用。

这一节先来写一个简单的主页。

首先在应用根目录下新建

es6

views

文件夹,然后如下修改

gulpfile.js

中的一行:

`js
// 所有es6文件夹所在的位置
const folders = ["."];

`

es6

下新建

app.js

文件,这是应用的入口和主体。

Express应用的主体一般需要(依照顺序)完成下面几个任务: 1. 导入依赖模块(module) 2. 实例化应用对象及其他对象 3. 联接数据库 4. 配置应用设定(例如使用什么模版引擎等) 5. 配置中间件 6. 配对URL和controller 7. 启动应用

导入依赖模块

使用Node.js的

require

函数来导入依赖模块(第三方的+自己的):

```js "use strict";

// 导入第三方模块 const express = require("express"); const http = require("http"); const path = require("path"); const logger = require("morgan"); const bodyParser = require("body-parser"); const errorHandler = require("errorhandler");

// 导入自己所写的模块 // 暂无 ```

实例化

在做任何其他工作之前(配置及使用Express),必须要先实例化应用对象。同时,其它对象(例如数据库对象)也建议在此一并实例化。

`js
// Express应用对象
const todoApp = express();
// 其它对象
// 暂无

`

联接数据库

`js
// 联接数据库
// 暂略

`

配置应用设定

首先设定应用的监听端口。下面这句代码将我们应用的端口设定为3000,除非在运行时使用

PORT

环境变量另作设定。

`js
// 端口
todoApp.set("port", process.env.PORT || 3000);

`

然后设定模版文件的地址,以及它们的扩展名(也就决定了模版引擎)。

`js
// 模版相关
todoApp.set("views", path.join(__dirname, "..", "views"));
todoApp.set("view engine", "jade");

`

上面代码中,

__dirname

是一个全局变量,代表当前文件所在的文件夹地址。很显然,我们的模版文件会是

.jade

文件、且会保存在上面新建的

views

文件夹中。

最后,出于安全考虑,将

x-powered-by

停用,这样别人就无法知道本应用是用Express写成的。

`js
todoApp.disable("x-powered-by");

`

实际上,Express有两类设定:系统设定和个人设定。以上配置的都是系统设定。它们一般都有默认值,比如

x-powered-by

的默认值就是

true

。我们也可以依照自己的需求和意愿做一些个人设定。比如我们可以把应用的名字存起来,以便在整个应用的任何地方使用。

`js
// 个人设定
todoApp.locals.appName = "To-Do List by Express.js";

`

如此一来,我们就新建了一个应用级别的变量

appName

,在应用的整个生命周期里的任何地方(包括Jade模版文件里)都能被访问。

配置中间件

所谓 中间件 (middleware),简单来说就是Express用来 预处理 网络请求的函数。“预处理”工作一般包括:解析HTTP请求,解析cookie,处理session,决定响应头,处理错误。

中间件有如下几个特点: 1. 都有三个参数,依照其所代表的对象,一般分别命名为

request

response

next

2. 依照来源可以分为三类:Express自带的,第三方导入的,和应用开发者自写的 3. 用Express的

app.use()

方法来配置中间件 4. 中间件配置的顺序决定了调用的顺序,而且每个中间价的最后必须要

next()

,表示调用下一个中间件,否则应用不会继续处理请求。

当所有的中间件依照顺序成功地执行完毕后,我们就会有一对request和response对象,以供我们在下一步真正实现应用逻辑的时候使用。

比如这里,我们并不想做任何预处理工作,只是想在开发环境下先把收到的网络请求输出到端口。可以用第三方模块morgan提供的中间件:

`js
// 开发环境下输出日志
todoApp.use(logger("dev"));

logger("dev")

会返回满足要求的中间件(也就是一个function)。其中

logger

是在一开始导入的第三方模块的对象,传入的参数

"dev"`确保只在开发环境下输出日志。

实现应用逻辑

网络应用的逻辑主要就是针对不同的请求回复不同的响应。

我们这一步的目标是当用户访问我们的网页时,不管后面带什么样的路径,我们都显示主页:

`js
// 实现应用逻辑
todoApp.get("*", homepageHandler);
function homepageHandler(request, response) {
response.render("index", {
message: "Welcome to the world of Express.js!"
});
}

"*"

表示通配所有的URL路径,"response.render(..)"则表示利用模版文件

index.jade`和后面的信息来生成返回给用户的HTML页面。

Jade基础

接下来我们写两个

.jade

文件。

使用模版文件和模版引擎的一个最大的好处就是能够重复利用代码。Jade模版经常会有一个主要的大体布局文件,包括大多数页面都用到的header、footer、menu等部分,而留出可以“扩展”的区域让别的文件来发挥。在

views

文件夹下新建

layout.jade

文件,这就是我们的布局文件,其内容如下:

`jade
doctype html
html
head
title= appName + " - " + pageHeader.title
body
block content

`

Jade文件里并不直接包含HTML式的标签,而是只有区域的名字,并靠缩进来表示从属关系。可以看到,这个文件里,有惯常的

head

body

两大区域。

head

里有

title

元素,而

body

里的

block content

就是定义了一个叫做

content

block

好让别的Jade文件来拓展。

然后在同一文件夹下新建

index.jade

文件,其内容是:

```jade extends layout

block content h1= appName h2= pageHeader.title p= message ```

第一行代码表示这个文件是对另一个文件(这里是

layout.jade

)的拓展。接下来

block content

表示其下的所有内容都将用来填充所拓展文件的同名

block

。请注意,

appName

是上面我们在配置应用时的一个个人设定,这里可以方便地访问。

  1. 启动应用

我们还剩下最后一步,就是让应用跑起来!回到

es6/app.js

文件,在最后加上下面的代码:

`js
// 启动应用
http.createServer(todoApp).listen(app.get("port"));

`

然后在命令行中运行:

`bash
gulp && nodemon dist/app.js

`

如果看到类似于下面的信息:

`bash
[nodemon] starting `node dist/app.js`

` 则说明应用启动成功。

浏览器(推荐Chrome)打开 http://localhost:3000 ,则可以看到我们刚刚写好的简单的主页了。

结语

以上就是本系列教程的第一节。要获得以上所有代码,可以执行

git clone -b setp1 https://github.com/qiao-zhang/todo-express.git

。下一节里,我们将用重构本节的代码,使用本节所学到的知识先把静态的网页搭建出来。敬请期待。

我来评几句
登录后评论

已发表评论数()

相关站点

+订阅
热门文章