它们的不同之处
每个人,包括文档,都倾向于回顾它们有多相似,但实际上没有提到任何差异。事实上,它们是不同的。
var bigApp = express();
var miniApp = express.Router();
listen()
最明显的区别在于bigApp
将提供listen
,这只是一种相当令人困惑的方式来完成本应该简单明了的http
或https
模块中的操作:
var server = require('http').createServer(bigApp);
server.listen(8080, function () {
console.info(server.address());
});
我认为这是一种反模式,因为它抽象化和混淆掉了原本并不复杂或困难的东西,并且使得使用 Websockets 和其他需要原始 HTTP 服务器的中间件变得困难。
内部状态
最重要的区别在于,所有的bigApp
都有独立的内部状态。
bigApp.enable('trust proxy');
bigApp.enabled('trust proxy');
var bigApp2 = express();
bigApp2.enabled('trust proxy');
bigApp.use('/bunnies', bigApp2);
将miniApp
传递给bigApp
,它将以保留其内部状态和this
性质的方式由bigApp
操作,并相应地处理这些路由。
bigApp.enable('trust proxy');
bigApp.enabled('trust proxy');
var miniApp = express.Router();
bigApp.use('/bunnies', miniApp);
这很重要,因为express
对http.ServerRequest
和httpServerResponse
对象做了许多(有时是棘手的)修改或劫持操作 - 例如修改(或劫持)req.url
和req.originalUrl
以及其他一些你一直在使用但没有意识到的属性 - 而你可能不希望这些被复制和分离。
更小的API
Router
可以使用更少、更明确定义的函数:
.use(mount, fn)
.all(mount, fn)
.options(mount, fn)
.head(mount, fn)
.get(mount, fn)
.post(mount, fn)
.patch(mount, fn)
.put(mount, fn)
.delete(mount, fn)
.route(mount).XXXX
.param(name, cb).XXXX
还有其他一些方便的方法,比如basic()
,但你不会发现set()
或enable()
或其他改变大型应用状态的方法。
Router
本身不会.listen()
来处理请求。它有助于将你的应用程序分成多个模块--在每个模块中创建一个Router
,然后通过app
进行require()
和.use()
作为中间件。 - Jonathan Lonowskiapp.get(..)
语法只是一个快捷方式,使得使用express.router
更加方便。如果你刚开始学习,不要担心路由器的细节。 - soulprovidrapp
自己的路由方法(例如app.get()
)足以满足您的需求,请使用它们。Router
只是为了方便您在多个模块上组织应用程序而存在的。根据指南所述:“*express.Router
类可用于创建模块化可挂载的路由处理程序。Router
实例是完整的中间件和路由系统,因此通常被称为“mini-app”。*” - Jonathan Lonowski