
您想使用Node.js構(gòu)建Web應(yīng)用程序并需要選擇一個(gè)服務(wù)器框架嗎?您可能只是因?yàn)?a target="_blank">Express的流行而默認(rèn)使用Express,但是其他選項(xiàng)可能更適合您應(yīng)用程序的需求,例如Koa和Hapi。
本文為您介紹了每個(gè)框架的服務(wù)器設(shè)置和路由,然后比較了它們的優(yōu)缺點(diǎn)。最后,您選擇的選擇很大程度上取決于應(yīng)用程序的特定需求。
Express
EXPRES是不容爭辯的Node.js的最流行的框架 Express的第一位貢獻(xiàn)者TJ Holowaychuk于2010年1月3日發(fā)布了0.0.1版,使其成為最古老,最成熟的框架。許多初學(xué)者更喜歡使用Express,因?yàn)樗皇懿僮髡叩闹浠驈腘ode提取的次數(shù)較少,這意味著它更類似于開發(fā)本機(jī)節(jié)點(diǎn)應(yīng)用程序。
Hello World!
要設(shè)置服務(wù)器,首先必須要求Express軟件包,然后通過將其分配給變量(在本例中為app)來實(shí)例化它。然后,實(shí)例化服務(wù)器以偵聽特定端口。連接后,您將在控制臺(tái)日志中看到成功消息。
const express = require(‘express’);
const app = express();
app.get(‘/’, function (req, res) {
res.send(‘Hello World!’)
})
app.listen(3000, () => console.log(`App is listening on port 3000!`))
而已。您現(xiàn)在已經(jīng)可以使用服務(wù)器了!簡單,不是嗎?
上面的示例演示了對(duì)根或主頁的GET請(qǐng)求,該請(qǐng)求在'/'處建立了端點(diǎn)。響應(yīng)對(duì)象具有將HTML文本發(fā)送到頁面的send方法。如果您訪問localhost:3000/(或您指定的任何端口),則應(yīng)看到“ Hello World!”。在頁面上。這是應(yīng)用程序的最簡單示例。挺整潔的!
您還可以使用應(yīng)用程序?qū)ο蟮钠渌椒?,這些方法與HTTP方法相對(duì)應(yīng):PUT,POST和DELETE。您也不僅限于發(fā)送純文本。有多種響應(yīng)方法,包括res.render(),可以與諸如EJS的模板引擎一起使用以呈現(xiàn)不同的視圖。
基本路由
使用Express,路由也相對(duì)簡單。使用app.route,您可以將路徑的路由處理程序鏈接在一起,同時(shí)保持代碼DRY。
app.route(‘/book’)
.get(function (req, res) {
res.send(‘Get a random book’)
})
.post(function (req, res) {
res.send(‘Add a book’)
})
.put(function (req, res) {
res.send(‘Update the book’)
})
優(yōu)點(diǎn)
因此,現(xiàn)在您可以看到使用Express設(shè)置服務(wù)器只需要很少的樣板代碼。由于Express的成熟和流行,它得到大量文檔的支持,并具有出色的社區(qū)支持,因此,如果遇到困難,可以使用大量資源來進(jìn)行調(diào)試。它也非常穩(wěn)定并由Node.js Foundation Incubator維護(hù),因此也難怪許多其他框架都基于Express構(gòu)建。
缺點(diǎn)
盡管Express有其廣泛的優(yōu)點(diǎn),但并非沒有缺點(diǎn)。從根本上講,這是非常勞動(dòng)密集型的。它要求開發(fā)人員手動(dòng)創(chuàng)建所有端點(diǎn),這意味著代碼庫越大,重構(gòu)就越困難。隨后,您需要有條理地維護(hù)代碼,因?yàn)楹苋菀自谒兄虚g件中迷失方向。它還沒有像Koa和Hapi這樣的內(nèi)置錯(cuò)誤處理。
Koa
每周下載量:300k+ | Github Star:28k+
在框架中,Koa是更酷,更熱門和更先進(jìn)的產(chǎn)品。由與Express相同的團(tuán)隊(duì)開發(fā)的TJ Holowaychuk(聽起來很熟悉嗎?)于2013年8月17日進(jìn)行了首次提交。Koa和Express之間的主要區(qū)別在于它們處理中間件的方式。Express在應(yīng)用程序框架中包括路由和模板。另一方面,Koa需要具有這些功能的模塊,因此使其更具模塊化或可定制性。您還會(huì)在下面的代碼示例中注意到Koa使用ES2015異步函數(shù),因此它需要Node v7.6.0及更高版本才能運(yùn)行。
設(shè)置
這是相同的Hello World!Koa的應(yīng)用程序:
const Koa = require(‘koa’);
const app = new Koa();
app.use(async ctx => {
ctx.body = ‘Hello World’;
});
app.listen(3000, () => console.log(‘Koa is listening to http://localhost:3000'));
看起來很相似,對(duì)吧?注意,Node的req和res對(duì)象丟失了,因?yàn)樗鼈円驯籏oa的Context對(duì)象替換。該對(duì)象包括ctx.request和ctx.response屬性。
路由
如前所述,Koa不提供任何內(nèi)置的路由中間件,因此您必須安裝類似koa-router的模塊。
上面的示例但包含一個(gè)路由器:
const Koa = require(‘koa’);
const Router = require(‘koa-router’);
const app = new Koa();
const router = new Router();
router
.get(‘/’, (ctx, next) => {
ctx.body = ‘Hello World!’;
})
.post(‘/users’, (ctx, next) => {
// …
.put(‘/users’, (ctx, next) => {
// …
.del(‘/users’, (ctx, next) => {
// …
});
app
.use(router.routes())
.use(router.allowedMethods());
有了Koa,這是一個(gè)簡單的路由器。如果請(qǐng)求/響應(yīng)周期中存在錯(cuò)誤,則內(nèi)置錯(cuò)誤處理功能,這意味著它將所有錯(cuò)誤輸出到stderr。
優(yōu)點(diǎn)
使用Koa,由于該框架具有靈活性,因此更容易編寫中間件。它被設(shè)計(jì)為既使寫作又使閱讀愉快。它還使用ES6異步/等待功能來消除對(duì)回調(diào)的使用。另一個(gè)重要的考慮因素是Koa的下載量很小。它非常輕巧,大約有500行代碼。
缺點(diǎn)
雖然Koa可能是新的,但它也比其較舊的兄弟版Express不穩(wěn)定。相比之下,開源社區(qū)也要小得多,這意味著可用的支持較少。盡管async / await消除了對(duì)回調(diào)的需求,但一次多個(gè)異步調(diào)用仍可能導(dǎo)致async / await hell。Koa特定的中間件也與其他框架不兼容。
哈皮 Hapi
每周下載:170k+ | GitHub Star:12k +
Hapi是(Http)API的縮寫,由WalmartLabs開發(fā)。Eran Hammer于2011年8月5日進(jìn)行了首次提交。代碼庫經(jīng)過了良好的測試和維護(hù),因?yàn)樗菫槲譅柆敽谏瞧谖宓匿N售而擴(kuò)張。在Express使用中間件擴(kuò)展Node的請(qǐng)求/響應(yīng)對(duì)象的地方,Hapi使用了功能強(qiáng)大的插件的廣泛集合。
服務(wù)器時(shí)間
讓我們看一下與Hapi相同的服務(wù)器示例服務(wù)器。
‘use strict’;
const Hapi = require(‘@hapi/hapi’);
const init = async () => {
const server = Hapi.server({
port: 3000,
host: ‘localhost’
});
await server.start();
console.log(‘Server running on %s’, server.info.uri);
};
server.route({
method: ‘GET’,
path: ‘/’,
handler: function (request, h) {
return ‘Hello World!’;
}
});
process.on(‘unhandledRejection’, (err) => {
console.log(err);
process.exit(1);
});
init();
馬上,您會(huì)發(fā)現(xiàn)設(shè)置Hapi服務(wù)器涉及很多樣板。公平地說,與Express或Koa相比,這些路線本身可讀性強(qiáng)。Hapi還使用異步/等待和類似Koa的錯(cuò)誤處理。
路由
server.route([
{
method: ‘GET’,
path: ‘/api/items’,
handler: function(request, reply) {
reply(‘Get item id’);
}
},
{
method: ‘GET’,
path: ‘/api/items/{id}’,
handler: function(request, reply) {
reply(‘Get item id: ‘ + request.params.id);
}
},
{
method: ‘POST’,
path: ‘/api/items’,
handler: function(request, reply) {
reply(‘Post item’);
}
},
{
method: ‘PUT’,
path: ‘/api/items/{id}’,
handler: function(request, reply) {
reply(‘Put item id: ‘ + request.params.id);
}
},
{
method: ‘DELETE’,
path: ‘/api/items/{id}’,
handler: function(request, reply) {
reply(‘Delete item id: ‘ + request.params.id);
}
}
)];
路由涉及很多代碼,但是Hapi在設(shè)計(jì)時(shí)考慮了代碼的配置。由于這種一致性,在大型團(tuán)隊(duì)中更容易使用。另外,Hapi還內(nèi)部執(zhí)行Express需要中間件執(zhí)行的某些操作,例如處理表單數(shù)據(jù)或設(shè)置cookie(分別為body-parser和cookie-parser)。
優(yōu)點(diǎn)
Hapi是一個(gè)健壯的框架,具有許多“開箱即用”的功能,使其非常適合大型項(xiàng)目。它還利用了功能強(qiáng)大的插件。另外,您可以將其與任何前端框架(React,Angular,Vue等)一起使用。
缺點(diǎn)
雖然Hapi是大型項(xiàng)目的絕佳選擇,但它不適用于較小的應(yīng)用程序。與Express一樣,它也需要大量的人工和維護(hù),但是與Express不同的是,沒有龐大的社區(qū)可以依靠。Hapi已被CondéNast,PayPal和Mozilla等主要公司使用,但不適用于不需要相同規(guī)模組件的輕量級(jí)應(yīng)用程序。
概括
這三個(gè)框架都具有不同的優(yōu)缺點(diǎn),這使它們成為您的Web應(yīng)用程序的正確選擇。但是,選擇框架都取決于項(xiàng)目的特定要求和開發(fā)它們的團(tuán)隊(duì)。
如果您正在尋求穩(wěn)定的支持,那么Express絕對(duì)是一個(gè)不錯(cuò)的選擇。但是,如果您想為單頁應(yīng)用程序提供更輕巧的功能和更新的功能,那么Koa可能是您的最佳選擇。而且,如果您要構(gòu)建一些需要擴(kuò)展并需要大型團(tuán)隊(duì)理解的內(nèi)容,那么Hapi就是贏家。性能也是要考慮的因素,但它不在本文討論范圍之內(nèi)。無論您選擇哪種,均可使用Express / Koa / Hapi編碼!