二十三、附录 A:相关阅读和资源
这个简短的附录提供了几个最有用的 Node.js 资源,供进一步学习使用:
- 其他 Node.js 框架
- Node.js 书籍
- JavaScript 经典
其他 Node.js 框架
毫无疑问,Express.js 框架是 Node.js web 服务中最成熟、最流行、最健壮、经过测试和使用最多的项目。截至本文撰写之时,Express.js 也是来自 NPM 社区的明星数量最多的 NPM 知识库,如图图 A-1 所示。依赖 Express.js 2.x 和 3.x 的真实制作 app 有很多,包括 Storify 1 (被 LiveFyre 2 收购)、DocuSign、 3 新 MySpace、 4 LearnBoost、 5 Geeklist、6 10
图 A-1 。Express.js 是最受欢迎的 NPM 知识库
尽管如此,Express.js 还有很多可供选择的 Node.js 框架。为了帮助开发人员浏览众多选项,我创建了一个类似于 TodoMVC 集合(http://todomvc.com
):Node 框架(http://nodeframework.com
),其 MVC 框架页面如图图 A-2 所示。顺便说一下,一些更全面的框架依赖于 Express.js(例如,SailsJS 11 ),所以您开始了解 Express.js 是件好事!
图 A-2 。Node Frameworks 提供了 Node.js 框架及其统计信息的列表
Node.js 书籍
有关 Node.js 堆栈的其他组件(如数据库和 WebSockets)的更多核心概述和/或信息,请参考以下资源:
- Azat Mardan (Apress,2014 年)的《实用 Node.js:构建真实世界的可扩展 web 应用》:这是一个循序渐进的指南,帮助您学习如何构建可扩展的真实世界的 web 应用,从安装 Express.js 到编写全栈 Web 应用。
- JS 快速原型:敏捷 JavaScript 开发12(Azat Mardan,2013):一本关于 Node.js、MongoDB 和 Backbone.js 的初级到中级书籍
- JavaScript 和 Node 基础知识:基本知识集锦13(Azat Mardan,2014):关于浏览器 JS 和 Node 的简单但重要的概念的简短阅读。
- 用 Node.js 介绍 OAuth:Twitter API OAuth 1.0,OAuth2.0,OAuth Echo,Everyauth 和 OAuth 2.0 服务器示例14(Azat Mardan,2014):一本关于不同 OAuth 场景的迷你书。
- Colin J. Ihrig (Apress,2013 年)为开发人员编写的 Pro Node.js):这是一本关于 Node.js 的综合性低级书籍,没有任何非核心模块。
- Node.js in Action ,作者 Mike Cantelon 等人(Manning Publications,2013):一本由多位作者撰写的关于 Express.js 和其他主题的书。
- 学习 Node,作者 Shelley Powers (O’Reilly Media,2012):涵盖了 Express、MongoDB、Mongoose 和 Socket.IO。
- Node 食谱,作者 David Mark Clements(Packt Publishing,2012):涵盖了数据库和 WebSockets。
- Node:启动并运行,作者汤姆·休斯-克劳奇和迈克·沃森(O’Reilly Media,2012):Node . js 的简要概述
- Smashing node . js:JavaScript Everywhere,作者 Guillermo Rauch (Wiley,2012):涵盖了 Express.js、Jade 和 Stylus,作者是 Mongoose ORM for MongoDB 的创建者。
JavaScript 经典
要想更深入地了解 JavaScript 这种最容易被误解也是最流行的编程语言,请务必阅读以下经典著作:
- 雄辩的 JavaScript,第二版,作者 Marijn Haverbeke(无淀粉出版社,2014):JavaScript 编码中的编程基础。
- 道格拉斯·克洛克福特(O’Reilly Media,2008 年)的《JavaScript:好的部分》(The Good Parts )讲述了 JavaScript 语言中棘手的部分。
课程
如果你喜欢这本书,那么可以看看 Azat 的 Node.js 课程:Node Program ( http://nodeprogram.com
)和 Mongoose 课程(http://mongoosecourse.com
)。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
二十四、附录 B:将 Express.js 3.x 迁移到 4.x:中间件、路由和其他变化
Express.js 4 ( http://expressjs.com
)是针对 web 应用、服务和 API 的最流行、最成熟、最健壮的 Node.js 框架的最新(截至 2014 年 5 月)主要版本。在从 3.x 到 4.x 的过渡中有一些突破性的变化,因此本附录作为一个简短的迁移指南,包括以下内容:
- 在 Express.js 4 中引入非捆绑中间件
- 从 Express.js 4 应用中删除不推荐使用的方法
- Express.js 4 的其他更改
- 探索新的 Express.js 4 路由实例以及如何链接它
- 更多 Express.js 4 迁移阅读链接
即使您不打算使用版本 3,本指南也可能对您有用,因为它阐明了从 Express 3 到 4 进行更改的基本原理,以及这些更改背后的哲学。
在 Express.js 4 中引入非捆绑中间件
让我们从最大的改变开始,这个改变将打破你的大多数 Express.js 3.x 项目。这也是讨论最多的(也是期待已久的?)网上的 Express.js 新闻。是的,它是非捆绑的中间件。
就我个人而言,我不确定这是好消息还是坏消息,因为我喜欢不必声明额外的依赖项。然而,我也看到了支持非绑定的理由,包括好处,比如保持 Express.js 模块小,独立升级中间件包,等等。
那么,什么是非捆绑中间件呢?还记得我们能够简单地通过键入app.use(express.middlwarename())
来使用的神奇中间件吗?嗯,它们来自于Connect
库,但现在它们不再是 Express.js 的一部分。例如,习惯上用 Express.js 3.x 编写app.use(express.cookieParser())
。这些模块对于几乎任何 web 应用都是必不可少的。它们是Connect
库的一部分,但是 Express.js 4.x 没有Connect
作为依赖项。这意味着,如果我们想使用中间件(我们确实这么做了!),我们需要明确地包含中间件,就像这样:
$ npm install body-parse@1.0.2 --save
然后,在 Express.js 主配置文件(如app.js
)中,我们这样使用包含的模块:
var bodyParser = require('body-parse')
// ... other dependencies
app.use(bodyParser())
// ... some other Express.js app configuration
表 B-1 描述了开发人员将不得不替换的非捆绑中间件:除了静态之外的所有中间件。没错,静电被遗漏了(为了方便?).下表列出了 Express.js 3.x 中间件名称及其在 Express.js 4.x 中的 NPM 模块对应项。
表 B-1 。中间件比较
|
Express.js 3.x
|
Express.js 4.x
|
github link(github 链接)
|
| — | — | — |
| express.bodyParser
| body-parser
| https://github.com/expressjs/body-parser
|
| express.compress
| compression
| https://github.com/expressjs/compression
|
| express.timeout
| connect-timeout
| https://github.com/expressjs/timeout
|
| express.cookieParser
| cookie-parser
| https://github.com/expressjs/cookie-parser
|
| express.cookieSession
| cookie-session
| https://github.com/expressjs/cookie-session
|
| express.csrf
| csurf
| https://github.com/expressjs/csurf
|
| express.error-handler
| errorhandler
| https://github.com/expressjs/errorhandler
|
| express.session
| express-session
| https://github.com/expressjs/session
|
| express.method-override
| method-override
| https://github.com/expressjs/method-override
|
| express.logger
| morgan
| https://github.com/expressjs/morgan
|
| express.response-time
| response-time
| https://github.com/expressjs/response-time
|
| express.favicon
| serve-favicon
| https://github.com/expressjs/serve-favicon
|
| express.directory
| serve-index
| https://github.com/expressjs/serve-index
|
| express.static
| serve-static
| https://github.com/expressjs/serve-static
|
| express.vhost
| vhost
| https://github.com/expressjs/vhost
|
让事情变得更复杂的是,Express.js/Connect 团队放弃了对表 B-2 中所示模块的支持,并建议您使用替代方案:
表 B-2 。丢弃模块及其替代品
|丢弃的模块
|
可供选择的事物
|
| — | — |
| cookieParser
| cookies
和keygrip
|
| limit
| 生体 |
| multipart
| connect-multiparty
和connect-busboy
|
| query
| qs
|
| staticCache
| st
和connect-static
|
这些未捆绑的 Express.js/Connect 模块很多都需要维护者1;这是您在 Node.js 领域取得进展的机会!
从 Express.js 4 应用中删除不推荐使用的方法
本节讨论那些不推荐使用的方法以及如何替换它们。
app.configure()
大多数人可能从来没有使用过app.configure()
,这是一个很好但不重要的方法,主要用于设置环境。如果你用过,就把app.configure('name', function(){...})
换成if (process.env.NODE_ENV === 'name') {...}
。例如,这个旧的 Express.js 3 生产配置
app.configure('production', function() {
app.set('port', 80)
})
在 Express.js 4.x 中变成以下内容:
if (process.env.NODE_ENV === 'production') {
app.set('port', 80)
}
app .路由
Express.js 4 的一个好的变化是它不再需要编写app.router
!所以现在,基本上,中间件和路由的顺序是唯一重要的事情,而在 Express.js 3x 中,开发人员可以通过将app.router
放在中间的某个位置来增加执行的顺序。
如果您有任何应该在路由之后订购的中间件,那么将它移动到路由之后的*,按照您想要的顺序。*
例如,在 Express.js 3.x 配置中的路由之后执行的错误处理中间件:
app.use(express.cookieParser())
app.use(app.router)
app.use(express.errorHandler())
app.get('/', routes.index)
app.post('/signup', routes.signup)
在 Express.js 4.x 中迁移到以下代码:
var cookieParse = require('cookie-parser')
var errorHandler = require('errorhandler')
...
app.use(cookieParser())
app.get('/', routes.index)
app.post('/signup', routes.signup)
app.use(errorHandler())
换句话说,app.use()
和带动词的路线,如app.get()
、app.post()
、app.put()
、app.del()
成了对等物。
res.on(“标题”)
从 Connect 3 中移除了res.on('header')
事件。
res.charset
在 Express.js 4.x 中,用res.type()
或res.set('content-type')
代替 Express.js 3.x 中的res.charset
利斯特 headersent
在 Express.js 4.x 中,用res.headersSent
代替res.headerSent
。
req.accepted()
在 Express.js 4.x 中,用req.accepts()
代替req.accepted()
。
Express.js 4.x 中的req.accepts
由模块accepts
( https://github.com/expressjs/accepts
)提供支持,GitHub 文档表明该模块是从 Koa ( http://koajs.com
)中提取的,用于一般用途。
Express.js 4 的其他更改
本节介绍了 Express.js 4 的其他一些变化。
app.use()
令人惊讶的是,app.use()
现在接受 URL 参数。这是使app.use()
和动词 route 方法相等并减少混淆的又一步。参数在req.params
对象中。
例如,如果我们需要从 URL 获得一个 ID,在 Express.js 4.x 中间件中我们可以写
app.use('/posts/:slug', function(req, res, next) {
req.db.findPostBySlug(req.params.slug, function(post){
...
})
})
资源位置()
在 Express.js 4 中,res.location()
不再解析相对 URL。
app.route()
参见下一节“探索新的 Express.js 4 Route 实例以及如何链接它”,了解关于 Express.js 4 中app.route()
角色的详细信息。
json 空间
在 Express.js 4 中,json spaces
在开发中默认是关闭的。
请求参数
req.params
是对象,不是数组。
没有.本地
res.locals
现在是一个物体。
req.is
Express.js 4.x 中的req.is
已经被模块type-is
( https://github.com/expressjs/type-is
)所取代,根据 GitHub 文档,该模块也是从 Koa.js ( http://koajs.com
)中提取出来用于一般用途。
Express.js 命令行生成器
对于命令行生成器,请使用
$ sudo npm install -g express-generator
而不是普通的老式$ sudo npm install -g express
。
探索新的 Express.js 4 路由实例以及如何链接它
app.route()
方法为我们提供了新的 Express.js 4 route 实例。在探究之前,我们先来看看路由本身。
在 Express.js 4.x 中,Router
类得到了增强。在 Express.js 3.x 中,app 实例使用 router,但现在我们可以创建许多 route 实例,并通过附加特定的中间件和其他逻辑将它们用于特定的路径。这可以用来重组代码。
这里有一个开发者如何在 Express.js 4.x 中使用Router
的基本例子,假设我们有两个类别的评论:书籍和游戏。审查的逻辑类似于路由,并被打包成路由:
var express = require('express')
var app = express()
var router = express.Router()
router.use(function(req, res, next) {
//process each request
});
router.get('/', function(req, res, next) {
// get the home page for that entity
next();
});
router.get('/reviews', function(req, res, next) {
// Get the reviews for that entity
next();
});
app.use('/books', router);
app.use('/games', router);
app.listen(3000);
app.route()
或router.route()
返回新的 Express.js 4.x route 实例,我们可以这样链:
router.route('/post/:slug')
.all(function(req, res, next) {
// Runs each time
// We can fetch the post by id from the database
})
.get(function(req, res, next) {
//Render post
})
.put(function(req, res, next) {
//Update post
})
.post(function(req, res, next) {
//Create new comment
})
.del(function(req, res, next) {
//Remove post
})
在 Express.js 3.x 中,如果没有路由链,我们将不得不反复输入相同的路径(增加了输入错误的风险):
router.all('/post/:slug', function(req, res, next) {
// runs each time
// we can fetch the post by ID from the database
})
router.get('/post/:slug', function(req, res, next) {
//render post
})
router.put('/post/:slug', function(req, res, next) {
//update post
})
router.post('/post/:slug', function(req, res, next) {
//create new comment
})
router.delete('/post/:slug', function(req, res, next) {
//remove post
})
同一个路由实例也可以有自己的中间件、param 和 HTTP 动词方法(如上所示)。
更多 Express.js 4 迁移阅读链接
所以,总的来说,Express.js 4.x 的变化不是很大,而且迁移可能是一个相对轻松的过程。但是,在您点击$ git checkout -b express4
为从 3.x 到 4.x 的迁移创建一个新的 Git 分支express4
之前,请仔细考虑您是否真的需要迁移!我知道许多成功的生产应用没有更新它们的主框架版本。在 Storify,我们曾经在 3.x 可用的时候运行 Express.js 2.x,也不是什么大事。作为另一个例子,从 Ruby 世界来看,我知道许多应用和开发人员仍然在使用 Ruby on Rails 2.x,尽管 Ruby on Rails 4.x 已经推出。
如果您决定使用 Express.js 4,不要仅仅依赖这个简单的概述。看看这些额外的资源,帮助您更轻松地从 Express.js 3.x 过渡到 4.x:
- 官方迁移指南 2
- Express.js 中的新功能 4 . x3
- Express.js 4.x 文档 4
Express.js 4、Node.js 和 MongoDB REST API 教程 5
1
2
3
4
5
二十五、附录 C:Express.js 4 备忘单
Pro Express.js 是一本内容丰富的书,有很多例子教你关于中间件、模式和配置的知识。因此,当您开始从事自己的项目时,您会发现拥有最重要的函数和命令的快速参考—备忘单是非常有用的。我已经创建了自己的 Express.js 4 备忘单,如图图 C-1 所示,我将它作为礼物送给 Pro Express.js 的读者。你可以在https://gum.co/NQiQ/AC30238A-5C5C
免费下载这份备忘单的精美 PDF 格式,正常价格是 4.99 美元。此链接仅供 Pro Express.js 的读者使用,请勿分享给任何人。
图 C-1 。Express.js 4 备忘单
备忘单中的信息可在本附录中找到,也可在线访问https://github.com/azat-co/cheatsheets/blob/master/express4/index.md
。备忘单包含以下几个部分:
- 装置
- 发电机
- 基础
- HTTP 动词和路由
- 请求
- 请求标题快捷方式
- 反应
- 经手人签名
- 铁笔和玉石
- 身体
- 静态
- 连接中间件
- 其他流行的中间件
在撰写本文时,备忘单适用于 Express 4.10.4。
装置
-
本地安装最新的 Express.js】
-
本地安装 Express.js v4.2.0,保存到
package.json
$ sudo npm install express@4.2.0 --save
-
安装 Express.js 命令行生成器 v4.0.0
$ sudo npm install -g express-generator@4.0.0
发电机
用法:$ express [options] [dir]
选项:
-h
:打印使用信息-V
:打印快速生成器版本号-e
:增加 ejs 引擎支持,省略默认为 jade-H
:增加 hogan.js 引擎支持-c <library>
:添加 CSS 支持(less|stylus|compass),如果省略,默认为普通 CSS-f
:生成到非空目录
基础
-
包含模块:
var express = require('express')
-
创建实例:
var app = express()
-
启动 Express.js 服务器:
app.listen(portNumber, callback)
-
启动 Express.js 服务器:
http.createServer(app).listen(portNumber, callback)
-
通过
app.set(key, value)
键设置属性值
-
通过关键字
app.get(key)
获取属性值
HTTP 动词和路由
app.get(urlPattern, requestHandler[, requestHandler2, ...])
app.post(urlPattern, requestHandler[, requestHandler2, ...])
app.put(urlPattern, requestHandler[, requestHandler2, ...])
app.delete(urlPattern, requestHandler[, requestHandler2, ...])
app.all(urlPattern, requestHandler[, requestHandler2, ...])
app.param([name,] callback)
:app.use([urlPattern,] requestHandler[, requestHandler2, ...])
请求
request.params
:参数中间件request.param
:提取一个参数request.query
:提取查询字符串参数request.route
:返回路线字符串request.cookies
:cookie,需要cookie-parser
request.signedCookies
:已签名的 cookies,需要cookie-parser
request.body
:有效载荷,需要body-parser
请求标题快捷方式
request.get(headerKey)
:表头键值request.accepts(type)
:检查类型是否被接受request.acceptsLanguage(language)
:检查语言request.acceptsCharset(charset)
:检查字符集request.is(type)
:检查类型request.ip
: IP 地址request.ips
: IP 地址(打开信任代理)request.path
URL 路径request.host
:没有端口号的主机request.fresh
:检查新鲜度request.stale
:检查陈旧性request.xhr
:对于 AJAX-y 请求为真request.protocol
:返回 HTTP 协议request.secure
:检查协议是否为https
request.subdomains
:子域数组request.originalUrl
原始 URL
反应
response.redirect(status, url)
:重定向请求response.send(status, data)
:发送响应response.json(status, data):
发送 JSON 并强制正确的报头response.sendfile(path, options, callback)
:发送文件response.render(templateName, locals, callback)
:渲染模板response.locals
:将数据传递给模板
经手人签名
function(request, response, next) {}
:请求处理者签名function(error, request, response, next) {}
:错误处理程序签名
铁笔和玉石
app.set('views', path.join(__dirname, 'views'))
app.set('view engine', 'jade')
app.use(require('stylus').middleware(path.join(__dirname, 'public')))
身体
var bodyParser = require('body-parser')
app.use(bodyParser.json())
app.use(bodyParser.urlencoded())
静态
app.use(express.static(path.join(__dirname, 'public')))
连接中间件
$ sudo npm install <package_name> --save
body-parser
:请求有效载荷compression
: Gzipconnect-timeout
:请求超时,单位为毫秒,默认为 5000cookie-parser
:饼干cookie-session
:通过 Cookies 存储的会话csurf
: CSRFerrorhandler
:错误处理程序express-session
:通过内存或其他存储进行会话method-override
: HTTP 方法覆盖morgan
:服务器日志response-time
:响应时间中间件serve-favicon
:收藏夹图标serve-index
:提供包含目录列表的页面serve-static
:静态内容vhost
:虚拟主机
其他流行的中间件
cookies
和keygrip
:类似于cookieParser
raw-body
:生体connect-multiparty
、connect-busboy
:连接多方中间件,连接勤杂工中间件qs
:类似于query
st
、connect-static
类似于staticCache
express-validator
:验证less
:少 CSSpassport
:认证库helmet
:安全标题connect-cors
: 心形connect-redis
:连接中继
二十六、附录 D:ExpressWorks
ExpressWorks 是一个自动化的研讨会,它引导您构建 Express.js 服务器,处理 GET、POST 和 PUT 请求,以及提取查询字符串、有效负载和 URL 参数。ExpressWorks 为您提供了任务和提示。你写下这些任务的解决方案。然后,在您将解决方案编写为 Express.js 应用后,ExpressWorks 会验证您对问题的解决方案。
ExpressWorks 以 workshop1为原型,以@substack 3 和@maxogden 为灵感来源于 stream-adventure2。 4 本附录包括以下高速公路简介:
- 装置
- 使用
- 重复定位
- 任务
装置
ExpressWorks v0.0.23 的建议全局安装如下:
$ npm install -g expressworks@0.0.23
$ expressworks
如果遇到错误,请尝试
$ sudo npm install -g expressworks@0.0.23
另一种方法(对于高级开发人员)是使用本地安装。为此,请在本地运行并安装以下程序:
$ mkdir node_modules
$ npm install expressworks@0.0.23
$ cd node_modules/expressworks$ node expressworks
使用
完成安装后,ExpressWorks 理解这些命令:
$ expressworks
:显示菜单,交互选择车间。- 显示所有车间的换行符列表。
$ expressworks select NAME
:选择一个车间。$ expressworks current
:显示当前选择的车间。$ expressworks run program.js
:针对所选输入运行程序。- 根据预期的输出来验证你的程序。
重复定位
如果要重置已完成任务列表,如图 D-1 所示,清空~/.config/expressworks/completed.json
文件。
图 D-1 。已完成的任务
任务
本节描述了您将遇到的一些任务。
你好世界
创建一个运行在 l ocalhost:3000
上的 Express.js app,输出“Hello World!”有人去 root '/home'
的时候。
ExpressWorks 给你提供的process.argv[2]
,就是端口号。
翡翠
创建一个 Express.js 应用,其主页(/home
)由 Jade 模板引擎呈现,显示当前日期(toDateString
)。
古老的好形式
编写一个处理 HTML 表单输入(<form><input name="str"/></form>
)并反向打印str
值的路径('/form'
)。
静态
将静态中间件应用到没有任何路由的服务器index.html
文件。通过路径的process.argv[3]
值提供并使用index.html
文件。但是,您可以将自己的文件用于此内容:
<html>
<head>
<link rel="stylesheet" type="text/css" href="/main.css"/>
</head>
<body>
<p>I am red!</p>
</body>
</html>
时尚的 CSS
用一些 Stylus 中间件来设计你的 HTML。process.argv[3]
中提供了main.styl
文件的路径,或者您可以从这些文件/文件夹中创建自己的文件/文件夹:
p
color red
index.html
文件如下:
<html>
<head>
<title>expressworks</title>
<link rel="stylesheet" type="text/css" href="/main.css"/>
</head>
<body>
<p>I am red!</p>
</body>
</html>
帕梅!帕梅!帕梅!帕梅!帕梅!帕梅
创建一个 Express.js 服务器来处理 PUT /message/:id
请求(例如,PUT /message/526aa677a8ceb64569c9d4fb
)。
该请求的响应返回用日期散列的 id SHA1:
require('crypto')
.createHash('sha1')
.update(new Date().toDateString().toString() + id)
.digest('hex')
查询中有什么
编写一个路由,从 GET /search
URL 路由(例如?results=recent&include_tabs=true
)中的查询字符串中提取数据,然后转换并以 JSON 格式输出回给用户。
加入我吧
写一个服务器,读取一个文件(文件名传入process.argv[3]
),然后解析成 JSON,用res.json(object)
把内容输出给用户。
摘要
ExpressWorks 是一个命令行工具,它将帮助您熟悉 Express.js 的一些基础知识。如果您喜欢这种学习方法,请在http://nodeschool.io
查看免费提供给您的类似研讨会/工具。
1
2
3
4