Używam frameworka sieci ExpressJS dla NodeJS.
Ludzie korzystający z ExpressJS umieszczają swoje środowiska (programowanie, produkcja, testy ...), trasy itp app.js
. W Internecie . Myślę, że nie jest to piękny sposób, ponieważ gdy masz dużą aplikację, plik app.js jest za duży!
Chciałbym mieć tę strukturę katalogów:
| my-application
| -- app.js
| -- config/
| -- environment.js
| -- routes.js
Oto mój kod:
app.js
var express = require('express');
var app = module.exports = express.createServer();
require('./config/environment.js')(app, express);
require('./config/routes.js')(app);
app.listen(3000);
config / environment.js
module.exports = function(app, express){
app.configure(function() {
app.use(express.logger());
});
app.configure('development', function() {
app.use(express.errorHandler({
dumpExceptions: true,
showStack: true
}));
});
app.configure('production', function() {
app.use(express.errorHandler());
});
};
config / trasy.js
module.exports = function(app) {
app.get('/', function(req, res) {
res.send('Hello world !');
});
};
Mój kod działa dobrze i myślę, że struktura katalogów jest piękna. Jednak kod musiał zostać dostosowany i nie jestem pewien, czy jest dobry / piękny.
Czy lepiej jest użyć mojej struktury katalogów i dostosować kod, czy po prostu użyć jednego pliku (app.js)?
Dziękuję za twoje porady!
Odpowiedzi:
OK, minęło trochę czasu i jest to popularne pytanie, więc stworzyłem repozytorium github rusztowania z kodem JavaScript i długim README o tym, jak lubię tworzyć struktury średniej aplikacji express.js.
focusaurus / express_code_structure to repozytorium z najnowszym kodem do tego. Witamy w zaproszeniach do ściągania.
Oto migawka README, ponieważ przepełnienie stosu nie lubi odpowiedzi typu „tylko łącze”. Zrobię kilka aktualizacji, ponieważ jest to nowy projekt, który będę nadal aktualizować, ale ostatecznie repozytorium github będzie aktualnym miejscem dla tych informacji.
Struktura ekspresowego kodu
Ten projekt jest przykładem organizacji średniej aplikacji sieci web express.js.
Aktualne co najmniej ekspresowe v4.14 grudnia 2016 r
Jak duża jest twoja aplikacja?
Aplikacje internetowe nie są takie same i moim zdaniem nie ma jednej struktury kodu, którą należy zastosować do wszystkich aplikacji express.js.
Jeśli twoja aplikacja jest niewielka, nie potrzebujesz tak głębokiej struktury katalogów, jak pokazano tutaj. Po prostu zachowaj prostotę i wrzuć garść
.js
plików do katalogu głównego repozytorium i gotowe. Voilà.Jeśli twoja aplikacja jest ogromna, w pewnym momencie musisz podzielić ją na odrębne pakiety npm. Zasadniczo podejście node.js wydaje się faworyzować wiele małych pakietów, przynajmniej dla bibliotek, i powinieneś zbudować swoją aplikację, używając kilku pakietów npm, ponieważ zaczyna to mieć sens i uzasadniać narzut. Tak więc, gdy Twoja aplikacja rośnie, a część kodu staje się jednoznacznie wielokrotnego użytku poza aplikacją lub stanowi przejrzysty podsystem, przenieś ją do własnego repozytorium git i przekształć w samodzielny pakiet npm.
Dlatego celem tego projektu jest zilustrowanie praktycznej struktury dla średnich aplikacji.
Jaka jest twoja ogólna architektura
Istnieje wiele podejść do tworzenia aplikacji internetowych, takich jak
Każdy z nich ładnie pasuje do innej struktury katalogów. Na potrzeby tego przykładu jest to tylko rusztowanie, a nie w pełni działająca aplikacja, ale zakładam następujące kluczowe punkty architektury:
A co z Ruby on Rails?
Tematem całego projektu będzie to, że wiele pomysłów zawartych w Ruby on Rails i przyjęte przez nich decyzje „Konwencja w sprawie konfiguracji”, choć powszechnie akceptowane i stosowane, nie są w rzeczywistości bardzo pomocne i czasami są przeciwieństwem tego, co to repozytorium poleca.
Chodzi mi przede wszystkim o to, że istnieją podstawowe zasady organizowania kodu i na podstawie tych zasad konwencje Ruby on Rails mają sens (głównie) dla społeczności Ruby on Rails. Jednak bezmyślne aportowanie tych konwencji mija się z celem. Po zapoznaniu się z podstawowymi zasadami WSZYSTKIE projekty będą dobrze zorganizowane i przejrzyste: skrypty powłoki, gry, aplikacje mobilne, projekty korporacyjne, a nawet katalog domowy.
Społeczność Railsów chce mieć możliwość przełączenia jednego dewelopera Railsów z aplikacji na aplikację i za każdym razem dobrze się z tym czuje. Ma to sens, jeśli masz 37 sygnałów lub Pivotal Labs i ma swoje zalety. W świecie JavaScript po stronie serwera ogólny etos jest o wiele bardziej dziki i zachodni, a tak naprawdę nie mamy z tym problemu. Tak się toczymy. Jesteśmy do tego przyzwyczajeni. Nawet w Express.js, jest to bliski krew Sinatry, a nie Railsów, a przyjmowanie konwencji z Railsów zwykle nic nie pomaga. Powiedziałbym nawet, że zasady są ważniejsze niż konwencja .
Podstawowe zasady i motywacje
app/node_modules
katalog i mająpackage.json
pliki w katalogach modułów, aby ułatwić to przejście i działają jako przypomnienie.app
katalogu, dzięki czemu możnacd
uruchomić find / grep / xargs / ag / ack / etc i nie rozpraszać się dopasowaniami innych firmkebab-case
mimo że nazwa zmiennej w JavaScript musi być taka,camelCase
ponieważ-
jest znakiem minus w JavaScript.kebab-case
transformacją nacamelCase
app/views
,app/controllers
,app/models
, etcroutes.rb
jest przydatny, jeśli chcesz przeglądać wszystkie trasy w aplikacji, ale podczas faktycznego budowania funkcji i naprawiania błędów dbasz tylko o trasy odpowiednie dla zmienianego elementu.app/users
ponieważ nie ma gniazda szczurów połączonej logiki biznesowej w całym miejscu, która zanieczyszczałaby czystość bazy kodu użytkownika.app/server.js:1
i możesz zobaczyć wszystko, co ładuje i wykonuje, postępując zgodnie z kodem.magicRESTRouter.route(somecontroller, {except: 'POST'})
to dla ciebie wielka wygrana na 3 podstawoweapp.get
,app.put
,app.del
, rozmowy, jesteś prawdopodobnie budowę monolityczną aplikację, która jest zbyt duża, aby efektywnie pracować. Przygotuj się na DUŻE zwycięstwa, a nie na zamianę 3 prostych linii na 1 linię złożoną.Używaj nazw plików zawierających małe litery kebab
specyfikacja express.js
Nie używać
app.configure
. Jest prawie całkowicie bezużyteczny i po prostu go nie potrzebujesz. Jest w wielu płytkach kuchennych z powodu bezmyślnego copypasta.app.use
do całej aplikacji, jeśli naprawdę potrzebujesz tego oprogramowania pośredniego tylko na 2 trasy (patrzę na ciebie,body-parser
)server.js
i będzie jasne, w jaki sposób są one uporządkowane. W przypadku aplikacji średniej wielkości rozdzielanie modułów na osobne trasy jest przyjemne, ale wprowadza niebezpieczeństwo niedziałającego oprogramowania pośredniegoAplikacja dowiązanie symboliczne
Istnieje wiele podejść przedstawione i omówione obszernie przez społeczność w wielkiej GIST Lepszy lokalny require () ścieżki dla node.js . Mogę wkrótce zdecydować, że wolę „po prostu poradzić sobie z dużą ilością ../../../ ..” lub skorzystać z modlue requFrom. Jednak w tej chwili stosuję sztuczkę z dowiązaniem symbolicznym opisaną poniżej.
Tak więc jednym ze sposobów uniknięcia irytujących ścieżek względnych
require("../../../config")
jest użycie następującej sztuczki:.gitignore
plikuvar config = require("app/config");
var DealModel = require("app/deals/deal-model")
;Konfiguracja
Generalnie koduj moduły i klasy, aby oczekiwać, że tylko podstawowy
options
obiekt JavaScript zostanie przekazany. Tylko modułapp/server.js
powinien zostać załadowanyapp/config.js
. Stamtąd może syntezować małeoptions
obiekty w celu konfigurowania podsystemów w razie potrzeby, ale łączenie każdego podsystemu z dużym globalnym modułem konfiguracji pełnym dodatkowych informacji jest złym sprzężeniem.Spróbuj scentralizować tworzenie połączeń DB i przekazywać je do podsystemów, w przeciwieństwie do przekazywania parametrów połączeń i samodzielnego wykonywania połączeń wychodzących przez podsystemy.
NODE_ENV
To kolejny kuszący, ale okropny pomysł przeniesiony z Rails. W aplikacji powinno znajdować się dokładnie 1 miejsce,
app/config.js
które wygląda naNODE_ENV
zmienną środowiskową. Cała reszta powinna przyjąć jawną opcję jako argument konstruktora klasy lub parametr konfiguracyjny modułu.Jeśli moduł e-mail ma opcję dostarczania wiadomości e-mail (SMTP, logowanie do standardowego wejścia, umieszczanie w kolejce itp.), Powinien wybrać taką opcję,
{deliver: 'stdout'}
ale absolutnie nie powinien tego sprawdzaćNODE_ENV
.Testy
Teraz trzymam moje pliki testowe w tym samym katalogu co odpowiadający im kod i używam konwencji nazewnictwa rozszerzeń nazw plików, aby odróżnić testy od kodu produkcyjnego.
foo.js
ma kod modułu „foo”foo.tape.js
ma testy węzłów dla foo i mieszka w tym samym katalogufoo.btape.js
może być używany do testów, które należy wykonać w środowisku przeglądarkiUżywam globów systemu plików i
find . -name '*.tape.js'
polecenia, aby uzyskać dostęp do wszystkich moich testów w razie potrzeby.Jak zorganizować kod w każdym
.js
pliku modułuZakres tego projektu dotyczy głównie tego, gdzie idą pliki i katalogi, i nie chcę dodawać wiele innych zakresów, ale wspomnę tylko, że mój kod dzielę na 3 odrębne sekcje.
źródło
AKTUALIZACJA (2013-10-29) : Proszę zobaczyć moją inną odpowiedź, która zawiera JavaScript zamiast CoffeeScript przez popularne żądanie, a także repozytorium github repo i obszerny plik README opisujący moje najnowsze rekomendacje na ten temat.
Config
To co robisz jest w porządku. Lubię mieć własną przestrzeń nazw konfiguracji skonfigurowaną w pliku najwyższego poziomu
config.coffee
z taką zagnieżdżoną przestrzenią nazw.Jest to przyjazne dla edycji sysadmin. Potem, gdy potrzebuję czegoś, na przykład informacji o połączeniu DB, jest to
Trasy / Kontrolery
Lubię zostawiać trasy z kontrolerami i organizować je w
app/controllers
podkatalogu. Następnie mogę je załadować i pozwolić im dodać dowolne trasy, których potrzebują.W moim
app/server.coffee
pliku coffeescript wykonuję:Mam więc pliki takie jak:
I na przykład w moim kontrolerze domen mam taką
setup
funkcję.Wyświetlenia
Widoki
app/views
stają się zwyczajowym miejscem. Tak to układam.Pliki statyczne
Idź w
public
podkatalogu.Github / Semver / NPM
Umieść plik README.md w swoim katalogu głównym git repo dla github.
Umieść plik package.json z semantycznym numerem wersji w katalogu głównym git repo dla NPM.
źródło
app.put route, api.needId
Go
i dołączambin
plik do struktury. Jak uruchomić tengo
plikbin
?Poniżej znajduje się pełna odpowiedź Petera Lyonsa, przeniesiona do waniliowej JS z Coffeescript, zgodnie z żądaniem kilku innych. Odpowiedź Piotra jest bardzo zdolna i każdy, kto głosuje na moją odpowiedź, również powinien głosować na jego odpowiedź.
Config
To co robisz jest w porządku. Lubię mieć własną przestrzeń nazw konfiguracji skonfigurowaną w pliku najwyższego poziomu
config.js
z taką zagnieżdżoną przestrzenią nazw.Jest to przyjazne dla edycji sysadmin. Potem, gdy potrzebuję czegoś, na przykład informacji o połączeniu DB, jest to
Trasy / Kontrolery
Lubię zostawiać trasy z kontrolerami i organizować je w
app/controllers
podkatalogu. Następnie mogę je załadować i pozwolić im dodać dowolne trasy, których potrzebują.W moim
app/server.js
pliku javascript robię:Mam więc pliki takie jak:
I na przykład w moim kontrolerze domen mam taką
setup
funkcję.Wyświetlenia
Widoki
app/views
stają się zwyczajowym miejscem. Tak to układam.Pliki statyczne
Przejdź do
public
podkatalogu.Github / Semver / NPM
Umieść plik README.md w swoim katalogu głównym git repo dla github.
Umieść plik package.json z semantycznym numerem wersji w katalogu głównym git repo dla NPM.
źródło
Moje pytanie zostało wprowadzone w kwietniu 2011 roku, jest cicho stare. W tym czasie mogłem poprawić swoje wrażenia z Express.js i jak zaprojektować aplikację napisaną przy użyciu tej biblioteki. Podzielę się tutaj moim doświadczeniem.
Oto moja struktura katalogów:
App.js
Celem
app.js
pliku jest bootstrap aplikacji expressjs. Ładuje moduł konfiguracji, moduł rejestratora, czeka na połączenie z bazą danych, ... i uruchamia serwer ekspresowy.trasy /
Katalog tras ma
index.js
plik. Jego celem jest wprowadzenie pewnego rodzaju magii do ładowania wszystkich innych plików wroutes/
katalogu. Oto implementacja:Dzięki temu modułowi tworzenie nowej definicji trasy i jej implementacji jest naprawdę łatwe. Na przykład
hello.js
:Każdy moduł trasy jest samodzielny .
źródło
Lubię używać globalnej „aplikacji”, zamiast eksportować funkcję itp
źródło
Myślę, że to świetny sposób, aby to zrobić. Nie tylko ekspresowe, ale widziałem całkiem sporo projektów node.js na github robiących to samo. Wyciągają parametry konfiguracyjne + mniejsze moduły (w niektórych przypadkach każdy identyfikator URI) są podzielone na osobne pliki.
Poleciłbym przejrzenie konkretnych projektów na github, aby uzyskać pomysł. IMO sposób w jaki robisz jest poprawny.
źródło
jest teraz koniec 2015 roku i po 3 latach rozwijania mojej struktury oraz w małych i dużych projektach. Wniosek?
Nie rób jednego dużego MVC, ale rozdziel go na moduły
Więc...
Dlaczego?
Zwykle jeden działa na jednym module (np. Produkty), który można zmieniać niezależnie.
Możesz ponownie wykorzystać moduły
Możesz to przetestować osobno
Możesz go wymienić osobno
Mają jasne (stabilne) interfejsy
- Jeśli działało wielu programistów, separacja modułów pomaga
Projekt nodebootstrap ma podobne podejście do mojej ostatecznej struktury. ( github )
Jak wygląda ta struktura?
Małe, zamknięte moduły , każdy z osobnym MVC
Każdy moduł ma pakiet.json
Testowanie jako część struktury (w każdym module)
Globalna konfiguracja , biblioteki i usługi
Zintegrowany Docker, Cluster, na zawsze
Przegląd folderów (zobacz folder lib dla modułów):
źródło
Daję strukturę folderów w stylu MVC, proszę znaleźć poniżej.
W naszych dużych i średnich aplikacjach internetowych zastosowaliśmy poniższą strukturę folderów.
Stworzyłem jeden moduł npm do generowania struktury folderów express mvc.
Poniżej znajduje się https://www.npmjs.com/package/express-mvc-generator
Wystarczy proste kroki, aby wygenerować i korzystać z tych modułów.
i) zainstaluj moduł
npm install express-mvc-generator -g
ii) sprawdź opcje
express -h
iii) Wygeneruj ekspresową strukturę mvc
express myapp
iv) Zainstaluj zależności
npm install
:v) Otwórz plik config / database.js. Skonfiguruj bazę danych mongo.
vi) Uruchom aplikację
node app
lubnodemon app
vii) Sprawdź adres URL http: // localhost: 8042 / signup LUB http: // yourip: 8042 / signup
źródło
Minęło sporo czasu od ostatniej odpowiedzi na to pytanie, a Express wydał również niedawno wersję 4, która dodała kilka przydatnych rzeczy do uporządkowania struktury aplikacji.
Poniżej znajduje się długi post na blogu na temat najlepszych praktyk dotyczących strukturyzacji aplikacji Express. http://www.terlici.com/2014/08/25/best-practices-express-structure.html
Istnieje również repozytorium GitHub, które stosuje porady zawarte w artykule. Jest zawsze na bieżąco z najnowszą wersją Express.
https://github.com/terlici/base-express
źródło
Nie sądzę, aby dobrym rozwiązaniem było dodawanie tras do konfiguracji. Lepsza struktura może być taka:
Tak więc products.js i users.js będą zawierać wszystkie twoje trasy, wszystkie będą logiczne.
źródło
Cóż, umieściłem swoje trasy jako plik json, który czytałem na początku, aw pętli for w app.js ustawiłem trasy. Route.json zawiera widok, który powinien zostać wywołany, oraz klucz wartości, które zostaną wysłane na trasę.
Działa to w wielu prostych przypadkach, ale musiałem ręcznie utworzyć kilka tras dla specjalnych przypadków.
źródło
Napisałem post dokładnie na ten temat. Zasadniczo korzysta z pliku,
routeRegistrar
który iteruje pliki w folderze/controllers
wywołującym jego funkcjęinit
. Funkcjainit
przyjmujeapp
zmienną ekspresową jako parametr, dzięki czemu możesz zarejestrować swoje trasy tak, jak chcesz.źródło
Może to być interesujące:
https://github.com/flatiron/nconf
źródło
1) Twój system plików projektu Express może:
app.js - globalny kontener aplikacji
2) Główny plik modułu (lib / mymodule / index.js):
3) Podłącz moduł w głównej aplikacji.js
4) Przykładowa logika
tj mówi / pokaż na Vimeo ciekawy pomysł, jak modularyzować aplikację ekspresową - modułowe aplikacje internetowe z Node.js i Express . Mocny i prosty.
źródło
http://locomotivejs.org/ zapewnia sposób na uporządkowanie aplikacji zbudowanej z Node.js i Express.
Ze strony:
źródło
Niedawno przyjęłam moduły jako niezależne mini-aplikacje.
Teraz dla dowolnego routingu modułów (# .js) widoki (* .ejs), js, css i zasoby są obok siebie. routing submodułu jest ustawiony w nadrzędnym # .js z dwoma dodatkowymi liniami
W ten sposób możliwe są nawet podmoduły.
Nie zapomnij ustawić widoku na katalog src
źródło
Tak wygląda większość struktury mojego katalogu projektów ekspresowych.
Zwykle
express dirname
inicjuję projekt, wybaczam moje lenistwo, ale jest on bardzo elastyczny i można go rozbudowywać. PS - musisz się na to zdobyćexpress-generator
(dla tych, którzy go szukająsudo npm install -g express-generator
, sudo, ponieważ instalujesz go globalnie)Musisz się zastanawiać, dlaczego pliki .env? Ponieważ działają! Używam
dotenv
modułu w moich projektach (ostatnio) i działa! Wpisz te 2 stwierdzenia wapp.js
lubwww
I kolejny wiersz, aby szybko ustawić
/bower_components
wyświetlanie treści statycznych w zasobie/ext
Prawdopodobnie może być odpowiedni dla osób, które chcą używać Express i Angular razem lub po prostu ekspres bez tej
javascripts
hierarchii, oczywiście.źródło
Moja struktura ekspresowa 4. https://github.com/odirleiborgert/borgert-express-boilerplate
Pakiety
Struktura
źródło
Prosty sposób na uporządkowanie aplikacji ekspresowej:
W main index.js należy zachować następującą kolejność.
źródło
Najlepszy sposób na strukturę MVC dla projektu ExpressJs z kierownicą i Passportjs
źródło