Gibt es eine gängige Konvention zum Aufteilen und Modularisieren der app.js
Datei in einer Express.js- Anwendung? Oder ist es üblich, alles in einer einzigen Datei zu speichern?
Gibt es eine gängige Konvention zum Aufteilen und Modularisieren der app.js
Datei in einer Express.js- Anwendung? Oder ist es üblich, alles in einer einzigen Datei zu speichern?
Antworten:
Ich habe meine wie folgt aufgeteilt:
~/app
|~controllers
| |-monkey.js
| |-zoo.js
|~models
| |-monkey.js
| |-zoo.js
|~views
| |~zoos
| |-new.jade
| |-_form.jade
|~test
| |~controllers
| |-zoo.js
| |~models
| |-zoo.js
|-index.js
Ich verwende Exporte, um zurückzugeben, was relevant ist. Zum Beispiel in den Modellen, die ich mache:
module.exports = mongoose.model('PhoneNumber', PhoneNumberSchema);
und wenn ich dann eine Telefonnummer erstellen muss, ist es so einfach wie:
var PhoneNumber = require('../models/phoneNumber');
var phoneNumber = new PhoneNumber();
Wenn ich das Schema verwenden muss, dann PhoneNumber.schema
(Dies setzt voraus, dass wir vom Routenordner aus arbeiten und 1 Ebene nach oben und dann nach unten zu den Modellen gehen müssen.)
Das Express-Wiki enthält eine Liste von Frameworks, die darauf aufbauen.
Ich denke, der Matador von Twitter ist ziemlich gut strukturiert. Wir haben tatsächlich einen sehr ähnlichen Ansatz verwendet, um Teile der App zu laden.
derby.js sieht auch sehr interessant aus. Es ist vergleichbar mit Meteor ohne den ganzen Hype und gibt tatsächlich Kredit, wo Kredit fällig ist (insbesondere Knoten und Express).
Wenn Sie ein Fan von CoffeeScript sind (ich bin es nicht) und reeeeaaaaaally das L & F von Rails wollen, gibt es auch Tower.js .
Wenn Sie mit Rails vertraut sind und sich nicht um das Ausbluten einiger Konzepte kümmern, gibt es Locomotive . Es ist ein leichtes Framework, das auf Express basiert. Es hat eine sehr ähnliche Struktur wie RoR und überträgt einige der rudimentäreren Konzepte (wie z. B. Routing).
Es lohnt sich, es sich anzusehen, auch wenn Sie nicht vorhaben, es zu verwenden.
nodejs-express-mongoose-demo ist sehr ähnlich wie ich meine strukturiert habe. Hör zu.
Warnung: Wenn ich auf Code verweise, den ich für das Knockout von Knoten zusammen gehackt habe, funktioniert das irgendwie, ist aber alles andere als elegant oder poliert.
Um genauer zu sein, habe app.js
ich die folgende Datei app.js.
var express = require('express'),
bootstrap = require('./init/bootstrap.js'),
app = module.exports = express.createServer();
bootstrap(app);
Dies bedeutet im Grunde, dass ich mein gesamtes Bootstrapping in einer separaten Datei platziere und dann den Server bootstrap.
Was macht Bootstrap ?
var configure = require("./app-configure.js"),
less = require("./watch-less.js"),
everyauth = require("./config-everyauth.js"),
routes = require("./start-routes.js"),
tools = require("buffertools"),
nko = require("nko"),
sessionStore = new (require("express").session.MemoryStore)()
module.exports = function(app) {
everyauth(app);
configure(app, sessionStore);
less();
routes(app, sessionStore);
nko('/9Ehs3Dwu0bSByCS');
app.listen(process.env.PORT);
console.log("server listening on port xxxx");
};
Nun, es teilt alle Server-Initialisierungs-Setups in schöne Teile auf. Speziell
app.configure
)Schauen wir uns zum Beispiel die Routing- Datei an
var fs = require("fs"),
parseCookie = require('connect').utils.parseCookie;
module.exports = function(app, sessionStore) {
var modelUrl = __dirname + "/../model/",
models = fs.readdirSync(modelUrl),
routeUrl = __dirname + "/../route/"
routes = fs.readdirSync(routeUrl);
Hier lade ich alle meine Modelle und Routen als Arrays von Dateien.
Haftungsausschluss: readdirSync
ist nur in Ordnung, wenn er aufgerufen wird, bevor Sie den http-Server starten (vorher .listen
). Das Aufrufen synchroner Blockierungsaufrufe zur Serverstartzeit macht den Code nur lesbarer (es ist im Grunde ein Hack).
var io = require("socket.io").listen(app);
io.set("authorization", function(data, accept) {
if (data.headers.cookie) {
data.cookie = parseCookie(data.headers.cookie);
data.sessionId = data.cookie['express.sid'];
sessionStore.get(data.sessionId, function(err, session) {
if (err) {
return accept(err.message, false);
} else if (!(session && session.auth)) {
return accept("not authorized", false)
}
data.session = session;
accept(null, true);
});
} else {
return accept('No cookie', false);
}
});
Hier drücke ich socket.io, um die Autorisierung tatsächlich zu verwenden, anstatt Tom und Jack mit meinem socket.io-Server sprechen zu lassen
routes.forEach(function(file) {
var route = require(routeUrl + file),
model = require(modelUrl + file);
route(app, model, io);
});
};
Hier beginne ich meine Routen, indem ich das entsprechende Modell an jedes aus der Routendatei zurückgegebene Routenobjekt übergebe.
Grundsätzlich geht es darum, dass Sie alles in nette kleine Module organisieren und dann einen Bootstrapping-Mechanismus haben.
Mein anderes Projekt (mein Blog) hat eine Init-Datei mit einer ähnlichen Struktur .
Haftungsausschluss: Der Blog ist kaputt und wird nicht erstellt. Ich arbeite daran.
Informationen zur wartbaren Routing-Organisation finden Sie in diesem Artikel zum Express-Routen-Scan- Knotenmodul . Dies ist die beste Lösung für mich.
Ich habe meine Apps auf dem Express-Generator-Tool aufgebaut. Sie können es installieren, indem Sie es npm install express-generator -g
ausführen und mit ausführen express <APP_NAME>
.
Um Ihnen eine Perspektive zu geben, sah eine der Strukturen meiner kleineren Anwendung folgendermaßen aus:
~/
|~bin
| |-www
|
|~config
| |-config.json
|
|~database
| |-database.js
|
|~middlewares
| |-authentication.js
| |-logger.js
|
|~models
| |-Bank.js
| |-User.js
|
|~routes
| |-index.js
| |-banks.js
| |-users.js
|
|~utilities
| |-fiat-converersion.js
|
|-app.js
|-package.json
|-package-lock.json
Eine coole Sache, die ich an dieser Struktur mag, die ich letztendlich für jede von mir entwickelte Expressanwendung übernehme, ist die Art und Weise, wie die Routen organisiert sind. Ich mochte es nicht, jede Routendatei in die app.js und app.use()
jede Route benötigen zu müssen , besonders wenn die Datei größer wird. Daher fand ich es hilfreich, alle meine app.use()
Dateien in einer ./routes/index.js-Datei zu gruppieren und zu zentralisieren .
Am Ende wird meine app.js ungefähr so aussehen:
...
const express = require('express');
const app = express();
...
require('./routes/index')(app);
und meine ./routes/index.js sehen ungefähr so aus:
module.exports = (app) => {
app.use('/users', require('./users'));
app.use('/banks', require('./banks'));
};
Ich kann dies einfach, require(./users)
weil ich die Benutzerroute mit express.Router () geschrieben habe, wodurch ich mehrere Routen "gruppieren" und dann gleichzeitig exportieren kann, um die Anwendung modularer zu gestalten.
Dies ist ein Beispiel dafür, was Sie auf meiner Route ./routers/users.js in Ordnung bringen würden:
const router = require('express').Router();
router.post('/signup', async (req, res) => {
// Signup code here
});
module.exports = router;
Hoffentlich hat dies geholfen, Ihre Frage zu beantworten! Viel Glück!