Tamam, bir süre oldu ve bu popüler bir soru, bu yüzden devam ettim ve JavaScript kodlu bir iskele github deposu ve orta boyutlu bir express.js uygulamasını nasıl yapılandırmak istediğim hakkında uzun bir README oluşturdum.
focusaurus / express_code_sttruc , bunun için en son koda sahip olan repo'dur . Çekme istekleri kabul edilir.
Stackoverflow sadece bir bağlantı yanıtlarını sevmediği için README'nin bir anlık görüntüsü. Bu, güncellemeye devam edeceğim yeni bir proje olduğu için bazı güncellemeler yapacağım, ancak sonuçta github repo bu bilgiler için güncel bir yer olacak.
Ekspres Kod Yapısı
Bu proje, orta ölçekli bir express.js web uygulamasının nasıl düzenleneceğine bir örnektir.
En azından ekspres v4.14 Aralık 2016'da geçerli
Başvurunuz ne kadar büyük?
Web uygulamaları aynı değildir ve bence tüm express.js uygulamalarına uygulanması gereken tek bir kod yapısı yoktur.
Uygulamanız küçükse, burada örneklendiği gibi derin bir dizin yapısına ihtiyacınız yoktur. Basit tutun ve deponuzun .js
köküne bir avuç dosya yapıştırın ve işiniz bitti. Voilà.
Uygulamanız çok büyükse, bir noktada onu farklı npm paketlerine ayırmanız gerekir. Genel olarak node.js yaklaşımı, en azından kütüphaneler için birçok küçük paketi destekliyor gibi görünüyor ve mantıklı olmaya ve ek yükü haklı çıkarmaya başlarken uygulamanızı birkaç npm paketi kullanarak oluşturmalısınız. Uygulamanız büyüdükçe ve kodun bir kısmı uygulamanızın dışında tekrar kullanılabilir hale geldikçe veya açık bir alt sistem olduğunda, onu kendi git deposuna taşıyın ve bağımsız bir npm paketine dönüştürün.
Dolayısıyla bu projenin odak noktası orta ölçekli bir uygulama için uygulanabilir bir yapı göstermektir.
Genel mimariniz nedir
Bir web uygulaması oluşturmak için birçok yaklaşım vardır, örneğin:
- Sunucu Tarafı MVC ve Ruby on Rails
- Tek Sayfa Uygulama stili a MongoDB / Express / Açısal / Düğüm (MEAN)
- Bazı formlara sahip temel web sitesi
- Modeller / İşlemler / Görüntüler / Olaylar tarzı bir MVC öldü, hareket zamanı
- ve daha pek çoğu hem güncel hem de tarihsel
Bunların her biri farklı bir dizin yapısına iyi uyum sağlar. Bu örneğin amaçları için, sadece iskele ve tamamen çalışan bir uygulama değil, ancak aşağıdaki temel mimari noktaları varsayıyorum:
- Sitede bazı geleneksel statik sayfalar / şablonlar var
- Sitenin "uygulama" kısmı, Tek Sayfalı Uygulama stili olarak geliştirilmiştir
- Uygulama, tarayıcıya bir REST / JSON stili API'si gösterir
- Uygulama basit bir iş etki alanı modelleri, bu durumda, bir araba bayilik uygulaması
Peki Ruby on Rails?
Bu proje boyunca Ruby on Rails'de yer alan fikirlerin çoğunun ve yaygın olarak kabul edilip kullanılmasına rağmen kabul ettikleri "Konfigürasyon Konvansiyonu" kararlarının aslında çok yararlı olmadığı ve bazen bu deponun tersi olduğu bir tema olacaktır. önerir.
Buradaki ana nokta, kod düzenlemenin altında yatan ilkeler olduğu ve bu ilkelere dayanarak Ruby on Rails sözleşmelerinin Ruby on Rails topluluğu için (çoğunlukla) mantıklı olduğu. Ancak, düşüncesizce bu sözleşmelerin üstesinden gelmek bu noktayı kaçırıyor. Temel ilkeleri inceledikten sonra, TÜM projeleriniz iyi organize edilmiş ve net olacaktır: kabuk komut dosyaları, oyunlar, mobil uygulamalar, kurumsal projeler, hatta ana dizininiz.
Rails topluluğu için, tek bir Rails geliştiricisinin uygulamadan uygulamaya uygulaması olmasını ve her seferinde tanıdık ve rahat olmasını isterler. 37 sinyal veya Pivotal Labs iseniz ve bunun faydaları varsa, bu çok mantıklıdır. Sunucu tarafındaki JavaScript dünyasında, genel ethos, vahşi batıdaki her şeyin gittiği yoldan çok daha fazla ve bununla ilgili bir sorunumuz yok. İşte biz buyuz. Biz buna alışkınız. Express.js içinde bile, Rails değil Sinatra'nın yakın bir akrabasıdır ve Rails'ten konvansiyon almak genellikle hiçbir şeye yardımcı olmaz. Hatta Konfigürasyon Konvansiyonu Hakkında İlkeler bile diyebilirim .
Temel İlkeler ve Motivasyonlar
Uygulama symlink hilesi
Topluluk tarafından büyük özde Node.js için daha iyi yerel gereksinim () yollarında özetlenen ve tartışılan birçok yaklaşım vardır . Yakında ya "sadece ../../../ .." bir sürü anlaşma tercih ya da requirFrom modlue kullanmaya karar verebilir. Ancak, şu anda aşağıda ayrıntıları verilen symlink numarasını kullanıyorum.
Proje içi rahatsızlıktan kaçınmanın bir yolu require("../../../config")
, aşağıdaki gibi hileli rahatsız edici yollar gerektirir :
- uygulamanız için node_modules altında bir sembolik bağlantı oluşturun
- cd node_modules && ln -nsf ../app
- git'e node_modules klasörünün tamamını değil,
yalnızca node_modules / app symlink'in kendisini ekleyin
- git add -f node_modules / app
- Evet, yine de
.gitignore
dosyanızda "node_modules" olmalıdır
- Hayır, git deponuza "node_modules" koymamalısınız. Bazı insanlar bunu yapmanızı tavsiye eder. Yanlış.
- Artık bu öneki kullanarak proje içi modüllere ihtiyaç duyabilirsiniz
var config = require("app/config");
var DealModel = require("app/deals/deal-model")
;
- Temel olarak, bu proje içi gerektirir harici npm modülleri için çok benzer çalışma gerektirir.
- Maalesef, Windows kullanıcıları, üst dizine ilişkin yollara bağlı kalmalısınız.
Yapılandırma
Genellikle modülleri ve sınıfları yalnızca temel bir JavaScript options
nesnesinin geçmesini beklemek üzere kodlayın . Yalnızca modülü app/server.js
yüklemelidir app/config.js
. Oradan options
, alt sistemleri gerektiği gibi yapılandırmak için küçük nesneleri sentezleyebilir , ancak her alt sistemi fazladan bilgi içeren büyük bir global yapılandırma modülüne bağlamak kötü bağlantıdır.
DB bağlantılarının oluşturulmasını merkezileştirmeye çalışın ve bunları bağlantı parametrelerini geçmekten ve alt sistemlerin giden bağlantıları kendileri yapmasının aksine alt sistemlere geçirmeye çalışın.
NODE_ENV
Bu, Rails'ten taşınan bir başka cazip ama korkunç fikir. Uygulamanızda ortam değişkenine app/config.js
bakan tam olarak 1 yer olmalıdır NODE_ENV
. Diğer her şey bir sınıf yapıcı argümanı veya modül yapılandırma parametresi olarak açık bir seçenek almalıdır.
E-posta modülünde e-postaların nasıl gönderileceği seçeneği varsa (SMTP, stdout'a giriş, sıraya koyma vb.), Bunun gibi bir seçenek almalıdır, {deliver: 'stdout'}
ancak kesinlikle kontrol etmemelidir NODE_ENV
.
Testler
Şimdi test dosyalarımı karşılık gelen kodlarıyla aynı dizinde tutuyorum ve testleri üretim kodundan ayırmak için dosya adı uzantısı adlandırma kurallarını kullanıyorum.
foo.js
modül "foo" koduna sahip
foo.tape.js
foo için düğüm tabanlı testlere sahip ve aynı direkte yaşıyor
foo.btape.js
tarayıcı ortamında yürütülmesi gereken testler için kullanılabilir
find . -name '*.tape.js'
Gerektiğinde tüm testlerime erişmek için dosya sistemi glob'larını ve komutunu kullanıyorum.
Her .js
modül dosyası içindeki kod nasıl düzenlenir
Bu projenin kapsamı çoğunlukla dosyaların ve dizinlerin nereye gittiği ile ilgilidir ve başka bir kapsam eklemek istemiyorum, ancak kodumu 3 ayrı bölüm halinde organize ettiğimi söyleyeceğim.
- CommonJS'nin açılış bloğu, eyalet bağımlılıklarına çağrı yapılmasını gerektirir
- Saf JavaScript'in ana kod bloğu. Burada CommonJS kirliliği yok. Dışa aktarma, modül veya gereksinimlere referans vermeyin.
- İhracat kurmak için CommonJS'nin kapanış bloğu