Question ExpressJS Comment structurer une application?


J'utilise le framework web ExpressJS pour NodeJS.

Les personnes utilisant ExpressJS mettent leurs environnements (développement, production, test ...), leurs routes, etc. app.js. Je pense que ce n'est pas une belle façon car lorsque vous avez une grosse application, app.js est trop grosse!

J'aimerais avoir cette structure de répertoire:

| my-application
| -- app.js
| -- config/
     | -- environment.js
     | -- routes.js

Voici mon code:

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 / routes.js

module.exports = function(app) {
    app.get('/', function(req, res) {
    res.send('Hello world !');
    });
};

Mon code fonctionne bien et je pense que la structure des répertoires est belle. Cependant, le code devait être adapté et je ne suis pas sûr que ce soit bien / beau.

Est-il préférable d'utiliser ma structure de répertoires et d'adapter le code ou d'utiliser simplement un fichier (app.js)?

Merci pour vos conseils!


467
2018-04-25 12:18


origine


Réponses:


OK, ça fait un moment et c'est une question populaire, donc je suis allé de l'avant et j'ai créé un référentiel github d'échafaudage avec du code JavaScript et un long fichier README sur comment j'aime structurer une application express.js de taille moyenne.

focusaurus / express_code_structure est le repo avec le dernier code pour cela. Tirez les demandes bienvenues.

Voici un instantané du fichier README, car stackoverflow n’aime pas les réponses à un simple lien. Je vais faire quelques mises à jour car c'est un nouveau projet que je vais continuer à mettre à jour, mais finalement le dépôt github sera la mise à jour de cette information.


Structure de code express

Ce projet est un exemple de la façon d'organiser une application Web express.js de taille moyenne.

Actuel au moins express v4.14 Décembre 2016

Build Status

js-standard-style

Quelle est la taille de votre application?

Les applications Web ne sont pas toutes les mêmes et, à mon avis, aucune structure de code ne doit être appliquée à toutes les applications express.js.

Si votre application est petite, vous n'avez pas besoin d'une structure de répertoires aussi détaillée que celle illustrée ici. Gardez simplement les choses simples et collez une poignée de .js fichiers à la racine de votre dépôt et vous avez terminé. Voilà.

Si votre application est énorme, à un moment donné, vous devez la décomposer en paquets npm distincts. En général, l'approche node.js semble favoriser de nombreux petits paquets, au moins pour les bibliothèques, et vous devriez construire votre application en utilisant plusieurs paquets npm car cela commence à avoir un sens et à justifier le temps système. Alors que votre application se développe et qu'une partie du code devient clairement réutilisable en dehors de votre application ou est un sous-système clair, placez-la dans son propre dépôt git et faites-en un paquet npm autonome.

Alors L'objectif de ce projet est d'illustrer une structure réalisable pour une application de taille moyenne.

Quelle est votre architecture globale

Il existe de nombreuses approches pour créer une application Web, telle que

  • Côté serveur MVC à la Ruby on Rails
  • Style d'application de page unique à la MongoDB / Express / Angular / Node (MEAN)
  • Site web de base avec quelques formulaires
  • Modèles / Opérations / Vues / Événements style a la MVC est mort, il est temps de bouger
  • et beaucoup d'autres à la fois actuels et historiques

Chacun d'entre eux s'intègre bien dans une structure de répertoires différente. Pour les besoins de cet exemple, il s'agit juste d'un échafaudage et non d'une application entièrement fonctionnelle, mais je suppose les points d'architecture clés suivants:

  • Le site a des pages / modèles statiques traditionnels
  • La partie "application" du site est développée en tant que style d'une seule page.
  • L'application expose une API de style REST / JSON au navigateur
  • L'application modélise un domaine d'activité simple, dans ce cas, c'est une application de concessionnaire automobile

Et qu'en est-il de Ruby on Rails?

Tout au long de ce projet, un des thèmes abordés dans les décisions Ruby on Rails et «Convention over Configuration» qu'ils ont adoptées, bien que largement acceptées et utilisées, n'est pas vraiment utile et est parfois à l'opposé de ce référentiel. recommande.

Mon point principal ici est qu'il y a des principes sous-jacents à l'organisation du code, et sur la base de ces principes, les conventions de Ruby on Rails ont du sens (surtout) pour la communauté Ruby on Rails. Cependant, il suffit d'étouffer ces conventions sans réfléchir. Une fois que vous aurez compris les principes de base, TOUS vos projets seront bien organisés et clairs: scripts shell, jeux, applications mobiles, projets d'entreprise, même votre répertoire personnel.

Pour la communauté Rails, ils souhaitent pouvoir faire passer un seul développeur Rails d’une application à l’autre d’une application à l’autre et s’y familiariser et s’y familiariser à chaque fois. Cela a du sens si vous êtes 37 signaux ou Pivotal Labs et que vous en avez des avantages. Dans le monde JavaScript côté serveur, l'éthique générale est tout simplement plus sauvage et nous n'avons pas vraiment de problème avec cela. Voilà comment nous roulons. Nous y sommes habitués. Même dans express.js, c'est un proche parent de Sinatra, pas de Rails, et prendre des conventions avec Rails n'aide généralement rien. Je dirais même Principes sur la convention sur la configuration.

Principes sous-jacents et motivations

  • Être gérable mentalement
    • Le cerveau ne peut traiter et penser à un petit nombre de choses liées à la fois. C'est pourquoi nous utilisons des répertoires. Cela nous aide à gérer la complexité en mettant l'accent sur les petites portions.
  • Être approprié à la taille
    • Ne créez pas de "répertoires Mansion" où il n'y a qu'un seul fichier contenant 3 répertoires. Vous pouvez voir cela se passe dans le Ansible Best Practices qui regrette que les petits projets créent plus de 10 répertoires contenant plus de 10 fichiers lorsque 1 répertoire avec 3 fichiers serait beaucoup plus approprié. Vous ne conduisez pas un bus pour aller au travail (sauf si vous êtes chauffeur de bus, mais même si vous conduisez un bus AT, ne travaillez PAS), ne créez donc pas de structures de système de fichiers non justifiées par les fichiers qu'il contient. .
  • Être modulaire mais pragmatique
    • La communauté des nœuds favorise globalement les petits modules. Tout ce qui peut être complètement séparé de votre application doit être extrait dans un module pour un usage interne ou publiquement publié sur npm. Cependant, pour les applications de taille moyenne dont la portée est ici, la surcharge peut ajouter un peu de temps à votre flux de travail sans valeur proportionnelle. Donc, pour le moment où vous avez du code qui est factorisé mais pas assez pour justifier un module NPM complètement séparé, il suffit de le considérer comme un "proto-module"avec l'espoir que quand il franchit un certain seuil de taille, il serait extrait.
    • Certaines personnes comme @ hij1nx même inclure un app/node_modules répertoire et avoir package.json fichiers dans le proto-module répertoires pour faciliter cette transition et servir de rappel.
  • Soyez facile à localiser le code
    • Compte tenu d'une fonctionnalité à construire ou d'un bug à corriger, notre objectif est qu'un développeur n'a aucun mal à localiser les fichiers source impliqués.
    • Les noms sont significatifs et précis
    • Le code de crufty est entièrement supprimé, pas laissé dans un fichier orphelin ou juste commenté
  • Soyez à la recherche
    • tout le code source de première partie est dans le app répertoire pour que vous puissiez cd il y a courir trouver / grep / xargs / ag / ack / etc et ne pas être distrait par des matches de tierces parties
  • Utiliser des noms simples et évidents
    • npm semble maintenant exiger des noms de paquets tout en minuscules. Je trouve cela surtout terrible mais je dois suivre le troupeau, donc les noms de fichiers doivent utiliser kebab-case même si le nom de la variable pour cela dans JavaScript doit être camelCase car - est un signe moins dans JavaScript.
    • nom de la variable correspond au nom de base du chemin du module, mais avec kebab-case transformé en camelCase
  • Grouper par couplage, pas par fonction
    • C'est un changement majeur par rapport à la convention Ruby on Rails app/views, app/controllers, app/models, etc
    • Les fonctionnalités sont ajoutées à une pile complète, donc je veux me concentrer sur une pile complète de fichiers qui sont pertinents pour ma fonctionnalité. Lorsque j'ajoute un champ de numéro de téléphone au modèle utilisateur, je ne m'intéresse pas aux contrôleurs autres que le contrôleur utilisateur et je ne m'intéresse à aucun modèle autre que le modèle utilisateur.
    • Ainsi, au lieu d'éditer 6 fichiers qui se trouvent chacun dans leur propre répertoire et d'ignorer des tonnes d'autres fichiers de ces répertoires, ce référentiel est organisé de telle sorte que tous les fichiers nécessaires à la création d'une fonctionnalité soient regroupés.
    • Par la nature de MVC, la vue d'utilisateur est couplée au contrôleur d'utilisateur qui est couplé au modèle d'utilisateur. Donc, lorsque je change de modèle d'utilisateur, ces 3 fichiers changent souvent ensemble, mais le contrôleur de transactions ou le contrôleur client sont découplés et ne sont donc pas impliqués. Il en va généralement de même pour les conceptions non-MVC.
    • Le découplage de style MVC ou MOVE en termes de code dans quel module est toujours encouragé, mais la diffusion des fichiers MVC dans des répertoires frères est tout simplement agaçante.
    • Ainsi, chacun de mes fichiers de routes a la partie des routes qu'il possède. Un style de rails routes.rb Le fichier est pratique si vous voulez avoir un aperçu de tous les itinéraires dans l'application, mais lorsque vous créez des fonctionnalités et corrigez des bogues, vous ne vous souciez que des itinéraires pertinents pour la pièce que vous modifiez.
  • Stocker des tests à côté du code
    • Ceci est juste une instance de "groupe par couplage", mais je voulais l'appeler spécifiquement. J'ai écrit beaucoup de projets où les tests vivent sous un système de fichiers parallèle appelé "tests" et maintenant que j'ai commencé à placer mes tests dans le même répertoire que le code correspondant, je ne reviens jamais en arrière. Ceci est plus modulaire et beaucoup plus facile à utiliser dans les éditeurs de texte et permet de réduire une grande partie du non-sens du chemin "../../ ..". Si vous avez un doute, essayez-le sur quelques projets et décidez par vous-même. Je ne vais rien faire de plus pour vous convaincre que c'est mieux.
  • Réduire le couplage transversal avec les événements
    • Il est facile de penser "OK, chaque fois qu'un nouveau Deal est créé, je veux envoyer un email à tous les commerciaux", puis simplement mettre le code pour envoyer ces emails dans la route qui crée les offres.
    • Cependant, ce couplage finira par transformer votre application en une boule de boue géante.
    • Au lieu de cela, le DealModel devrait simplement déclencher un événement "create" et ignorer complètement ce que le système pourrait faire d'autre en réponse à cela.
    • Lorsque vous codez de cette façon, il devient beaucoup plus possible de mettre tout le code associé à l'utilisateur dans app/users parce qu'il n'y a pas un nid de rat de la logique métier couplée partout polluer la pureté de la base de code utilisateur.
  • Le flux de code peut être suivi
    • Ne fais pas de choses magiques. Ne pas charger automatiquement les fichiers des répertoires magiques du système de fichiers. Ne soyez pas Rails. L'application commence à app/server.js:1 et vous pouvez voir tout ce qu’il charge et s’exécute en suivant le code.
    • Ne créez pas de DSL pour vos itinéraires. Ne faites pas de métaprogrammation stupide quand ce n'est pas demandé.
    • Si votre application est si grande que faire magicRESTRouter.route(somecontroller, {except: 'POST'}) est une grande victoire pour vous sur 3 basiques app.get, app.put, app.del, appels, vous construisez probablement une application monolithique qui est trop grande pour travailler efficacement. Obtenez fantaisie pour BIG victoires, pas pour convertir 3 lignes simples à 1 ligne complexe.
  • Utiliser des noms de fichiers avec un kebab inférieur

    • Ce format évite les problèmes de sensibilité à la casse du système de fichiers sur les plates-formes
    • npm interdit les majuscules dans les nouveaux noms de paquets, et cela fonctionne bien avec

      express.js détails

  • Ne pas utiliser app.configure. C'est presque entièrement inutile et vous n'en avez tout simplement pas besoin. Il est dans beaucoup de passe-partout en raison de copypasta stupide.

  • L'ORDRE DU MIDDLEWARE ET DES ROUTES EN MATIÈRE EXPRESS !!!
    • Presque tous les problèmes de routage que je vois sur stackoverflow sont des middleware express désordonnés
    • En général, vous voulez que vos routes soient découplées et ne vous fiez pas trop à l'ordre
    • Ne pas utiliser app.use pour l'ensemble de votre application si vous avez vraiment besoin de ce middleware pour 2 routes (je vous regarde, body-parser)
    • Assurez-vous que tout est dit et fait, vous avez exactement cette commande:
      1. Tout middleware à l'échelle de l'application super important
      2. Tous vos itinéraires et parcours intermédiaires
      3. ALORS gestionnaires d'erreur
  • Malheureusement, express.js étant inspiré de la sinatra, cela suppose que toutes vos routes seront server.js et il sera clair comment ils sont commandés. Pour une application de taille moyenne, il est utile de décomposer les éléments en modules de routes distincts, mais cela présente des risques pour le middleware en panne.

L'application symlink trick

Il y a beaucoup d'approches décrites et discutées longuement par la communauté dans le grand esprit Meilleurs chemins require () locaux pour Node.js. Je pourrai bientôt décider de préférer soit "traiter avec beaucoup de ../../../ .." ou utiliser le requireFrom modlue. Cependant, pour le moment, j'utilise le truc du lien symbolique détaillé ci-dessous.

Donc, une façon d'éviter les projets intra-projet avec des chemins relatifs ennuyeux comme require("../../../config")est d'utiliser l'astuce suivante:

  • créer un lien symbolique sous node_modules pour votre application
    • cd node_modules && ln -nsf ../app
  • ajouter juste le node_modules / app symlink lui-même, pas tout le dossier node_modules, à git
    • git ajouter -f node_modules / app
    • Oui, vous devriez toujours avoir "node_modules" dans votre .gitignore fichier
    • Non, vous ne devriez pas mettre "node_modules" dans votre dépôt git. Certaines personnes vous recommanderont de le faire. Ils sont incorrects
  • Vous pouvez maintenant exiger des modules intra-projet en utilisant ce préfixe
    • var config = require("app/config");
    • var DealModel = require("app/deals/deal-model");
  • Fondamentalement, cela fait que le travail intra-projet nécessite un travail très similaire à celui requis pour les modules npm externes.
  • Désolé, les utilisateurs de Windows, vous devez vous en tenir aux chemins relatifs du répertoire parent.

Configuration

Généralement, les modules de code et les classes n'attendent qu'un JavaScript de base options objet passé. Seulement app/server.js devrait charger le app/config.js module. De là, il peut synthétiser de petites options objets pour configurer les sous-systèmes en fonction des besoins, mais coupler chaque sous-système à un grand module de configuration global rempli d'informations supplémentaires est un mauvais couplage.

Essayez de centraliser la création de connexions de base de données et de les transférer dans des sous-systèmes, au lieu de passer des paramètres de connexion et de faire eux-mêmes des sous-systèmes.

NODE_ENV

C'est une autre idée séduisante mais terrible reprise de Rails. Il devrait y avoir exactement 1 place dans votre application, app/config.js qui regarde le NODE_ENV variable d'environnement. Tout le reste devrait prendre une option explicite en tant qu'argument de constructeur de classe ou paramètre de configuration de module.

Si le module de messagerie a une option quant à la manière de livrer les emails (SMTP, se connecter à stdout, mettre en file d'attente, etc.), cela devrait prendre une option comme {deliver: 'stdout'} mais il ne devrait absolument pas vérifier NODE_ENV.

Des tests

Je conserve maintenant mes fichiers de test dans le même répertoire que le code correspondant et utilise les conventions de dénomination des extensions de nom de fichier pour distinguer les tests du code de production.

  • foo.js a le code du module "foo"
  • foo.tape.js a les tests basés sur les nœuds pour foo et vit dans le même répertoire
  • foo.btape.js peut être utilisé pour les tests qui doivent être exécutés dans un environnement de navigateur

J'utilise des globes de système de fichiers et le find . -name '*.tape.js' commande pour accéder à tous mes tests si nécessaire.

Comment organiser le code dans chaque .js fichier de module

La portée de ce projet concerne principalement la destination des fichiers et des répertoires, et je ne souhaite pas en ajouter beaucoup, mais je mentionnerai simplement que j'organise mon code en trois sections distinctes.

  1. Le bloc d'ouverture de CommonJS nécessite des appels aux dépendances d'état
  2. Bloc de code principal de pure-JavaScript. Pas de pollution CommonJS ici. Ne référencez pas les exportations, module ou require.
  3. Bloc de clôture de CommonJS pour mettre en place des exportations

254
2017-10-27 21:01



MISE À JOUR (2013-10-29): S'il vous plaît voir mon autre réponse, qui a JavaScript à la place de CoffeeScript à la demande populaire, ainsi qu'un republi github passe-partout et un README détaillé détaillant mes dernières recommandations sur ce sujet.

Config

Ce que vous faites est bien. J'aime avoir mon propre espace de noms de configuration mis en place dans un niveau supérieur config.coffee fichier avec un espace de noms imbriqué comme celui-ci.

#Set the current environment to true in the env object
currentEnv = process.env.NODE_ENV or 'development'
exports.appName = "MyApp"
exports.env =
  production: false
  staging: false
  test: false
  development: false
exports.env[currentEnv] = true
exports.log =
  path: __dirname + "/var/log/app_#{currentEnv}.log"
exports.server =
  port: 9600
  #In staging and production, listen loopback. nginx listens on the network.
  ip: '127.0.0.1'
if currentEnv not in ['production', 'staging']
  exports.enableTests = true
  #Listen on all IPs in dev/test (for testing from other machines)
  exports.server.ip = '0.0.0.0'
exports.db =
  URL: "mongodb://localhost:27017/#{exports.appName.toLowerCase()}_#{currentEnv}"

Ceci est convivial pour l'édition de sysadmin. Ensuite, quand j'ai besoin de quelque chose, comme les informations de connexion DB, c'est

require('./config').db.URL

Routes / Contrôleurs

J'aime laisser mes itinéraires avec mes contrôleurs et les organiser dans un app/controllers sous-répertoire. Ensuite, je peux les charger et les laisser ajouter les routes dont ils ont besoin.

Dans mon app/server.coffee fichier coffeescript que je fais:

[
  'api'
  'authorization'
  'authentication'
  'domains'
  'users'
  'stylesheets'
  'javascripts'
  'tests'
  'sales'
].map (controllerName) ->
  controller = require './controllers/' + controllerName
  controller.setup app

J'ai donc des fichiers comme:

app/controllers/api.coffee
app/controllers/authorization.coffee
app/controllers/authentication.coffee
app/controllers/domains.coffee

Et par exemple dans mon contrôleur de domaine, j'ai un setup fonctionne comme ça.

exports.setup = (app) ->
  controller = new exports.DomainController
  route = '/domains'
  app.post route, controller.create
  app.put route, api.needId
  app.delete route, api.needId
  route = '/domains/:id'
  app.put route, controller.loadDomain, controller.update
  app.del route, controller.loadDomain, exports.delete
  app.get route, controller.loadDomain, (req, res) ->
    res.sendJSON req.domain, status.OK

Vues

Mettre des vues dans app/views est en train de devenir l'endroit habituel. Je l'expose comme ça.

app/views/layout.jade
app/views/about.jade
app/views/user/EditUser.jade
app/views/domain/EditDomain.jade

Fichiers statiques

Aller dans un public sous-répertoire.

Github / Semver / NPM

Mettez un fichier démarrable README.md à votre racine repo git pour github.

Placez un fichier package.json avec un version sémantique nombre dans votre racine repo git pour NPM.


153
2017-09-08 15:47



Ce qui suit est la réponse de Peter Lyons mot à mot, transférée à la vanille JS de Coffeescript, comme demandé par plusieurs autres. La réponse de Peter est très bonne, et quiconque vote sur ma réponse devrait voter sur la sienne également.


Config

Ce que vous faites est bien. J'aime avoir mon propre espace de noms de configuration mis en place dans un niveau supérieur config.js fichier avec un espace de noms imbriqué comme celui-ci.

// Set the current environment to true in the env object
var currentEnv = process.env.NODE_ENV || 'development';
exports.appName = "MyApp";
exports.env = {
  production: false,
  staging: false,
  test: false,
  development: false
};  
exports.env[currentEnv] = true;
exports.log = {
  path: __dirname + "/var/log/app_#{currentEnv}.log"
};  
exports.server = {
  port: 9600,
  // In staging and production, listen loopback. nginx listens on the network.
  ip: '127.0.0.1'
};  
if (currentEnv != 'production' && currentEnv != 'staging') {
  exports.enableTests = true;
  // Listen on all IPs in dev/test (for testing from other machines)
  exports.server.ip = '0.0.0.0';
};
exports.db {
  URL: "mongodb://localhost:27017/#{exports.appName.toLowerCase()}_#{currentEnv}"
};

Ceci est convivial pour l'édition de sysadmin. Ensuite, quand j'ai besoin de quelque chose, comme les informations de connexion DB, c'est

require('./config').db.URL

Routes / Contrôleurs

J'aime laisser mes itinéraires avec mes contrôleurs et les organiser dans un app/controllers sous-répertoire. Ensuite, je peux les charger et les laisser ajouter les routes dont ils ont besoin.

Dans mon app/server.js fichier javascript que je fais:

[
  'api',
  'authorization',
  'authentication',
  'domains',
  'users',
  'stylesheets',
  'javascripts',
  'tests',
  'sales'
].map(function(controllerName){
  var controller = require('./controllers/' + controllerName);
  controller.setup(app);
});

J'ai donc des fichiers comme:

app/controllers/api.js
app/controllers/authorization.js
app/controllers/authentication.js
app/controllers/domains.js

Et par exemple dans mon contrôleur de domaine, j'ai un setup fonctionne comme ça.

exports.setup = function(app) {
  var controller = new exports.DomainController();
  var route = '/domains';
  app.post(route, controller.create);
  app.put(route, api.needId);
  app.delete(route, api.needId);
  route = '/domains/:id';
  app.put(route, controller.loadDomain, controller.update);
  app.del(route, controller.loadDomain, function(req, res){
    res.sendJSON(req.domain, status.OK);
  });
}

Vues

Mettre des vues dans app/views est en train de devenir l'endroit habituel. Je l'expose comme ça.

app/views/layout.jade
app/views/about.jade
app/views/user/EditUser.jade
app/views/domain/EditDomain.jade

Fichiers statiques

Aller dans un public sous-répertoire.

Github / Semver / NPM

Mettez un fichier démarrable README.md à votre racine repo git pour github.

Placez un fichier package.json avec un version sémantique nombre dans votre racine repo git pour NPM.


49
2017-10-03 21:19



Ma question a été introduite en avril 2011, c'est vieux. Pendant ce temps, je pourrais améliorer mon expérience avec Express.js et comment archiver une application écrite en utilisant cette bibliothèque. Donc, je partage ici mon expérience.

Voici ma structure de répertoire:

├── app.js   // main entry
├── config   // The configuration of my applications (logger, global config, ...)
├── models   // The model data (e.g. Mongoose model)
├── public   // The public directory (client-side code)
├── routes   // The route definitions and implementations
├── services // The standalone services (Database service, Email service, ...)
└── views    // The view rendered by the server to the client (e.g. Jade, EJS, ...)

App.js

L'objectif de app.js Le fichier est pour amorcer l'application expressjs. Il charge le module de configuration, le module enregistreur, attend la connexion à la base de données, ... et exécute le serveur express.

'use strict';
require('./config');
var database = require('./services/database');
var express = require('express');
var app = express();
module.exports = app;

function main() {
  var http = require('http');

  // Configure the application.
  app.configure(function () {
    // ... ... ...
  });
  app.configure('production', function () {
    // ... ... ...
  });
  app.configure('development', function () {
    // ... ... ...
  });

  var server = http.createServer(app);

  // Load all routes.
  require('./routes')(app);

  // Listen on http port.
  server.listen(3000);
}

database.connect(function (err) {
  if (err) { 
    // ...
  }
  main();
});

routes /

Le répertoire des routes a un index.js fichier. Son but est d'introduire une sorte de magie pour charger tous les autres fichiers dans le routes/ annuaire. Voici la mise en œuvre:

/**
 * This module loads dynamically all routes modules located in the routes/
 * directory.
 */
'use strict';
var fs = require('fs');
var path = require('path');

module.exports = function (app) {
  fs.readdirSync('./routes').forEach(function (file) {
    // Avoid to read this current file.
    if (file === path.basename(__filename)) { return; }

    // Load the route file.
    require('./' + file)(app);
  });
};

Avec ce module, créer une nouvelle définition d'itinéraire et la mise en œuvre est vraiment facile. Pour des exemples, hello.js:

function hello(req, res) {
  res.send('Hello world');
}

module.exports = function (app) {
  app.get('/api/hello_world', hello);
};

Chaque module de route est autonome.


40
2017-11-01 09:56



J'aime utiliser une "application" globale, plutôt que d'exporter une fonction, etc.


18
2017-09-08 14:36



Je pense que c'est un excellent moyen de le faire. Pas limité à exprimer mais j'ai vu un certain nombre de projets node.js sur github faire la même chose. Ils retirent les paramètres de configuration + les modules plus petits (dans certains cas, chaque URI) sont factorisés dans des fichiers séparés.

Je recommanderais de passer par des projets spécifiques à Express sur github pour avoir une idée. OMI comme vous le faites est correct.


17
2018-04-25 12:56



c'est maintenant Fin 2015 et après avoir développé ma structure pendant 3 ans et dans de petits et grands projets. Conclusion?

Ne pas faire un grand MVC, mais le séparer en modules

Alors...

Pourquoi?

  • Généralement, on travaille sur un module (par exemple, Produits), que vous pouvez modifier indépendamment.

  • Vous êtes capable de réutiliser des modules

  • Vous êtes capable de le tester séparément

  • Vous êtes en mesure de le remplacer séparément

  • Ils ont des interfaces claires (stables)

    -Au plus tard, si plusieurs développeurs fonctionnaient, la séparation des modules aide

le nodebootstrap projet a une approche similaire à ma structure finale. (github)

Comment cette structure ressemble-t-elle?

  1. Petits modules encapsulés, chacun avec MVC séparé

  2. Chaque module a un package.json

  3. Essai dans le cadre de la structure (dans chaque module)

  4. Configuration globale, bibliothèques et services

  5. Docker intégré, cluster, pour toujours

Folderoverview (voir le dossier lib pour les modules):

nodebootstrap structure


13
2017-09-18 19:45



Cela fait un bon moment depuis la dernière réponse à cette question et Express a également récemment publié la version 4, qui a ajouté quelques éléments utiles pour l'organisation de la structure de votre application.

Vous trouverez ci-dessous un article sur les meilleures pratiques concernant la structure de votre application Express. http://www.terlici.com/2014/08/25/best-practices-express-structure.html

Il existe également un dépôt GitHub qui applique les conseils de l'article. Il est toujours à jour avec la dernière version Express.
https://github.com/terlici/base-express


7
2017-10-10 11:23



Je ne pense pas que ce soit une bonne approche pour ajouter des routes à la configuration. Une meilleure structure pourrait être quelque chose comme ceci:

application/
| - app.js
| - config.js
| - public/ (assets - js, css, images)
| - views/ (all your views files)
| - libraries/ (you can also call it modules/ or routes/)
    | - users.js
    | - products.js
    | - etc...

Ainsi, products.js et users.js contiendront toutes vos routes et toute la logique à l'intérieur.


7
2018-04-22 20:09