Node.js的Express,Koa和Hapi Web框架的比較

您想使用Node.js構(gòu)建Web應(yīng)用程序并需要選擇一個(gè)服務(wù)器框架嗎?您可能只是因?yàn)?a target="_blank">Express的流行而默認(rèn)使用Express,但是其他選項(xiàng)可能更適合您應(yīng)用程序的需求,例如KoaHapi。

本文為您介紹了每個(gè)框架的服務(wù)器設(shè)置和路由,然后比較了它們的優(yōu)缺點(diǎn)。最后,您選擇的選擇很大程度上取決于應(yīng)用程序的特定需求。

Express

每周下載量:9百萬+| GitHub Star:47k+

EXPRES是不容爭辯的Node.js的最流行的框架 Express的第一位貢獻(xiàn)者TJ Holowaychuk20101月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(聽起來很熟悉嗎?)于20138月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編碼!

參考

Is Express the Best Option?

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容