Existe-t-il une convention commune pour la division et la modularisation du app.js
fichier dans une application Express.js ? Ou est-il courant de tout conserver dans un seul fichier?
Existe-t-il une convention commune pour la division et la modularisation du app.js
fichier dans une application Express.js ? Ou est-il courant de tout conserver dans un seul fichier?
Réponses:
J'ai le mien brisé comme suit:
~/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
J'utilise Exportations pour renvoyer ce qui est pertinent. Par exemple, dans les modèles que je fais:
module.exports = mongoose.model('PhoneNumber', PhoneNumberSchema);
et puis si j'ai besoin de créer un numéro de téléphone, c'est aussi simple que:
var PhoneNumber = require('../models/phoneNumber');
var phoneNumber = new PhoneNumber();
si j'ai besoin d'utiliser le schéma, alors PhoneNumber.schema
(ce qui suppose que nous travaillons à partir du dossier routes et que nous devons monter d'un niveau, puis descendre aux modèles)
Le wiki express a une liste de frameworks construits dessus.
Parmi ceux-ci, je pense que le matador de Twitter est plutôt bien structuré. Nous avons en fait utilisé une approche très similaire pour charger certaines parties de l'application.
derby.js semble également extrêmement intéressant. Cela s'apparente à un météore sans tout le battage médiatique et donne en fait du crédit là où le crédit est dû (notamment, nœud et express).
Si vous êtes fan de CoffeeScript (je ne le suis pas) et que vous voulez vraiment le L&F de Rails, il y a aussi Tower.js .
Si vous êtes familier avec les rails et que cela ne vous dérange pas de perdre certains concepts, il y a Locomotive . C'est un cadre léger construit sur Express. Il a une structure très similaire à RoR et reprend certains des concepts les plus rudimentaires (tels que le routage).
Cela vaut la peine de vérifier même si vous ne prévoyez pas de l'utiliser.
nodejs-express-mongoose-demo est très similaire à la façon dont j'ai le mien structuré. Vérifiez-le.
Attention: le code de référencement que j'ai piraté ensemble pour le knock-out des nœuds, cela fonctionne en quelque sorte mais est loin d'être élégant ou poli.
Pour être plus précis sur le fractionnement, app.js
j'ai le fichier app.js suivant
var express = require('express'),
bootstrap = require('./init/bootstrap.js'),
app = module.exports = express.createServer();
bootstrap(app);
Cela signifie essentiellement que je place tout mon bootstrapping dans un fichier séparé, puis je bootstrap le serveur.
Alors, que fait le 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");
};
Eh bien, il divise toute la configuration d'initialisation du serveur en jolis morceaux. Plus précisément
app.configure
)Par exemple, regardons le fichier de routage
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);
Ici, je charge tous mes modèles et routes sous forme de tableaux de fichiers.
Clause de non-responsabilité: readdirSync
n'est correct que lorsqu'il est appelé avant de démarrer le serveur http (avant .listen
). L'appel d'appels de blocage synchrones au moment du démarrage du serveur rend simplement le code plus lisible (c'est essentiellement un 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);
}
});
Ici, je frappe socket.io pour utiliser l'autorisation plutôt que de laisser n'importe quel tom et jack parler à mon serveur socket.io
routes.forEach(function(file) {
var route = require(routeUrl + file),
model = require(modelUrl + file);
route(app, model, io);
});
};
Ici, je commence mes itinéraires en passant le modèle pertinent dans chaque objet d'itinéraire renvoyé par le fichier d'itinéraire.
Fondamentalement, le fait est que vous organisez tout dans de jolis petits modules et que vous disposez ensuite d'un mécanisme de démarrage.
Mon autre projet (mon blog) a un fichier init avec une structure similaire .
Avertissement: le blog est cassé et ne se construit pas, je travaille dessus.
Pour une organisation de routage maintenable, vous pouvez consulter cet article sur le module de nœud express-routescan et l'essayer. C'est la meilleure solution pour moi.
J'ai mes applications construites au-dessus de l'outil de générateur express. Vous pouvez l'installer en l'exécutant npm install express-generator -g
et l'exécuter en utilisant express <APP_NAME>
.
Pour vous donner une perspective, l'une des structures de ma plus petite application ressemblait à ceci:
~/
|~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
Une chose que j'aime bien dans cette structure que je finis par adopter pour toute application express que je développe est la façon dont les itinéraires sont organisés. Je n'aimais pas avoir à exiger chaque fichier de route dans l'app.js et app.use()
chaque route, d'autant plus que le fichier grossit . En tant que tel, j'ai trouvé utile de regrouper et de centraliser tous mes app.use()
fichiers sur un fichier ./routes/index.js.
En fin de compte, mon app.js ressemblera à ceci:
...
const express = require('express');
const app = express();
...
require('./routes/index')(app);
et mon ./routes/index.js ressemblera à ceci:
module.exports = (app) => {
app.use('/users', require('./users'));
app.use('/banks', require('./banks'));
};
Je suis capable de le faire simplement require(./users)
parce que j'ai écrit la route des utilisateurs en utilisant express.Router () qui me permet de "grouper" plusieurs routes et de les exporter en même temps, dans le but de rendre l'application plus modulaire.
Voici un exemple de ce que vous feriez bien sur mon itinéraire ./routers/users.js:
const router = require('express').Router();
router.post('/signup', async (req, res) => {
// Signup code here
});
module.exports = router;
J'espère que cela a aidé à répondre à votre question! Bonne chance!