Üretime hazır bir Node ve Express uygulaması nasıl yazılır

Proje Yapılandırma

Node & Express uygulamaları oluşturmaya başladığımda, uygulamanızı yapılandırmanın ne kadar önemli olduğunu bilmiyordum. Ekspres, proje yapısını korumak için katı kurallar veya yönergeler içermez.

İstediğiniz herhangi bir yapıyı kullanmakta özgürsünüz. Kod tabanınız büyüdüğünde, uzun routeişleyicilere sahip olursunuz . Bu, kodunuzun anlaşılmasını zorlaştırır ve potansiyel hatalar içerir.

Bir başlangıç ​​için çalışıyorsanız, çoğu zaman projenizi yeniden düzenlemek veya modülerleştirmek için zamanınız olmayacak. Sonsuz bir hata düzeltme ve yama döngüsüne sahip olabilirsiniz.

Zamanla, hem küçük ekiplerle hem de büyük ekiplerle çalışırken, projenizle ne tür bir yapının büyüyebileceğini ve yine de bakımının kolay olduğunu fark ettim.

Model Görünümü Denetleyicisi

MVC modeli hızlı ve paralel gelişime yardımcı olur. Örneğin, bir geliştirici görünüm üzerinde çalışırken bir diğeri denetleyicide iş mantığı oluşturmaya çalışabilir.

Basit bir kullanıcı CRUD uygulaması örneğine bakalım.

project/ controllers/ users.js util/ plugin.js middlewares/ auth.js models/ user.js routes/ user.js router.js public/ js/ css/ img/ views/ users/ index.jade tests/ users/ create-user-test.js update-user-test.js get-user-test.js .gitignore app.js package.json
  • denetleyiciler: Uygulama yol işleyicilerinizi ve iş mantığınızı tanımlayın
  • util: Herhangi bir denetleyici tarafından kullanılabilen yardımcı program / yardımcı işlevleri buraya yazar. Örneğin bir fonksiyon yazabilirsiniz mergeTwoArrays(arr1, arr2).
  • ara yazılımlar: Yol işleyiciye geçmeden önce gelen tüm istekleri yorumlamak için ara yazılımlar yazabilirsiniz. Örneğin,

    router.post('/login', auth, controller.login)burada authbir ara katman işlevi tanımlanmıştır middlewares/auth.js.

  • modeller: ayrıca denetleyiciniz ve veritabanı arasında bir tür ara yazılım. Veritabanına yazmadan önce bir şema tanımlayabilir ve bazı doğrulamalar yapabilirsiniz. Örneğin, şemanın kendisinde kullanmak için harika özellik ve yöntemlerle gelen Mongoose gibi bir ORM kullanabilirsiniz.
  • rotalar: HTTP yöntemleriyle uygulama rotalarınızı tanımlayın. Örneğin, kullanıcıyla ilgili her şeyi tanımlayabilirsiniz.
router.post('/users/create', controller.create) router.put('/users/:userId', controller.update) router.get('/users', controller.getAll)
  • public: Statik resimleri /img, özel JavaScript dosyalarında ve CSS'de saklayın/css
  • görünümler: Sunucu tarafından işlenecek şablonları içerir.
  • testler: Burada, API sunucusu için tüm birim testlerini veya kabul testlerini yazabilirsiniz.
  • app.js: Uygulamayı ve projenin diğer öğelerini başlattığınız projenin ana dosyası görevi görür.
  • package.json: Bağımlılıklarla, npmkomutla çalıştırılacak betiklerle ve projenizin sürümüyle ilgilenir .

İstisnalar ve Hata Giderme

Bu, herhangi bir dilde herhangi bir proje oluştururken düşünülmesi gereken en önemli hususlardan biridir. Bir Express uygulamasında hataları ve istisnaları incelikle nasıl ele alacağımızı görelim.

Sözleri kullanmak

Geri aramaları üzerinde vaat kullanmanın avantajlarından biri de aynı zamanda tanımlanan senkron kodu için uyumsuz kod bloklar halinde örtülü veya açık istisnalar / hataları işleyebilir olduğunu .then(), bir söz callback'inde

Sadece .catch(next)söz zincirinin sonuna ekleyin . Örneğin:

router.post('/create', (req, res, next) => { User.create(req.body) // function to store user data in db .then(result => { // do something with result return result }) .then(user => res.json(user)) .catch(next) })

Try-catch kullanma

Try-catch, zaman uyumsuz koddaki istisnaları yakalamanın geleneksel bir yoludur.

İstisna alma olasılığı olan bir örneğe bakalım:

router.get('/search', (req, res) => { setImmediate(() => { const jsonStr = req.query.params try { const jsonObj = JSON.parse(jsonStr) res.send('Success') } catch (e) { res.status(400).send('Invalid JSON string') } }) })

Eşzamanlı kod kullanmaktan kaçının

Eşzamanlı kod, aynı zamanda engelleme kodu olarak da bilinir, çünkü yürütülene kadar yürütmeyi engeller.

Bu nedenle, milisaniyeler veya mikrosaniyeler sürebilen senkronize işlevler veya yöntemler kullanmaktan kaçının. Yüksek trafikli bir web sitesi için bileşikleşir ve API isteklerinin yüksek gecikmesine veya yanıt süresine yol açabilir.

Bunları özellikle üretimde kullanmayın :)

Birçok node.js modülleri hem gelmek .syncve .asyncyöntemler üretimde kullanılması zaman uyumsuz yüzden.

Ancak yine de eşzamanlı bir API kullanmak istiyorsanız --trace-sync-iokomut satırı işaretini kullanın . Uygulamanız senkronize bir API kullandığında bir uyarı ve yığın izi yazdıracaktır.

Hata işlemenin temelleri hakkında daha fazla bilgi için bkz .:

  • Node.js'de Hata İşleme
  • Sağlam Düğüm Uygulamaları Oluşturma: Hata İşleme (StrongLoop blogu)
Yapmamanız gereken şeyuncaughtException , olay döngüsüne kadar bir istisna baloncuğunda ortaya çıktığında gönderilen olayı dinlemektir . Genellikle kullanılması tercih edilmez.

Doğru günlüğe kaydetme

Günlük kaydı, hata ayıklama ve uygulama etkinliği için önemlidir. Esas olarak geliştirme amaçlı kullanılır. Biz kullanmak console.logve console.errorancak bu senkron fonksiyonlardır.

Hata Ayıklama amaçları için

Hata ayıklama gibi bir modül kullanabilirsiniz. Bu modül, varsa, hangi hata ayıklama mesajlarının gönderileceğini kontrol etmek için DEBUG ortam değişkenini kullanmanızı sağlar console.err().

Uygulama etkinliği için

Bunun bir yolu onları veritabanına yazmaktır.

Uygulamamı denetlemek için mongoose eklentilerini nasıl kullandığıma bakın.

Another way is to write to a file OR use a logging library like Winston or Bunyan. For a detailed comparison of these two libraries, see the StrongLoop blog post Comparing Winston and Bunyan Node.js Logging.

require(“./../../../../../../”) mess

There are different workarounds for this problem.

If you find any module getting popular and if it has logical independence from the application, you can convert it to private npm module and use it like any other module in package.json.

OR

const path = require('path'); const HOMEDIR = path.join(__dirname,'..','..');

where __dirname is the built-in variable that names the directory that contains the current file, and .. ,..is the requisite number of steps up the directory tree to reach the root of the project.

From there it is simply:

const foo = require(path.join(HOMEDIR,'lib','foo')); const bar = require(path.join(HOMEDIR,'lib','foo','bar'));

to load an arbitrary file within the project.

Let me know in the comment below if you have better ideas :)

Set NODE_ENV to “production”

The NODE_ENV environment variable specifies the environment in which an application is running (usually, development or production). One of the simplest things you can do to improve performance is to set NODE_ENVto “production.”

Setting NODE_ENV to “production” makes Express:

  • Cache view templates.
  • Cache CSS files generated from CSS extensions.
  • Generate less verbose error messages.

Tests indicate that just doing this can improve app performance by a factor of three!

Using Process Manager

For production, you should not simply use node app.j — if your app crashes, it will be offline until you restart it.

The most popular process managers for Node are:

  • StrongLoop Process Manager
  • PM2
  • Forever

I personally use PM2.

For a feature-by-feature comparison of the three process managers, see //strong-pm.io/compare/. For a more detailed introduction to all three, see Process managers for Express apps.

Run your app in a cluster

In a multi-core system, you can increase the performance of a Node app by many times by launching a cluster of processes.

A cluster runs multiple instances of the app, ideally one instance on each CPU core. This distributes the load and tasks among the instances.

Using Node’s cluster module

Clustering is made possible with Node’s cluster module. This enables a master process to spawn worker processes. It distributes incoming connections among the workers.

However, rather than using this module directly, it’s far better to use one of the many tools out there that do it for you automatically. For example node-pm or cluster-service.

Using PM2

For pm2 you can use cluster directly through a command. For example,

# Start 4 worker processes pm2 start app.js -i 4 # Auto-detect number of available CPUs and start that many worker processes pm2 start app.js -i max 

If you encounter any problems, feel free to get in touch or comment below.

I would be happy to help :)

Don’t hesitate to clap if you considered this a worthwhile read!

References: //expressjs.com/en/advanced/best-practice-performance.html

Originally published at 101node.io on September 30, 2018.