javascript node.js modularity express

javascript - ¿Cómo estructurar una aplicación express.js?



node.js modularity (3)

Para la organización de enrutamiento mantenible puede consultar este artículo sobre el módulo de nodo de ruta expresa y probarlo. Esta es la mejor solución para mí.

¿Existe una convención común para dividir y modularizar el archivo app.js en una aplicación Express.js ? ¿O es común mantener todo en un solo archivo?


Tengo el mío dividido de la siguiente manera:

~/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

Yo uso Exportaciones para devolver lo relevante. Por ejemplo, en los modelos que hago:

module.exports = mongoose.model(''PhoneNumber'', PhoneNumberSchema);

y luego, si necesito crear un número de teléfono, es tan simple como:

var PhoneNumber = require(''../models/phoneNumber''); var phoneNumber = new PhoneNumber();

si necesito usar el esquema, entonces PhoneNumber.schema

(lo cual supone que estamos trabajando desde la carpeta de rutas y necesitamos subir de nivel 1 y luego a modelos)

EDIT 4

La wiki expresa tiene una lista de marcos construidos sobre ella.

De esos, creo que el matador de Twitter está estructurado bastante bien. De hecho, utilizamos un enfoque muy similar a la forma en que cargan partes de la aplicación.

derby.js también se ve extremadamente interesante. Es similar a un meteor sin todo el bombo y en realidad da crédito donde se debe crédito (notablemente, nodo y expreso).

EDIT 3

Si eres un fanático de CoffeeScript (no lo soy) y quieres que reeeeaaaaaaalmente quieras el L & F de Rails, también está Tower.js .

EDIT 2

Si está familiarizado con Rails y no le importa el desbordamiento de algunos conceptos, existe Locomotive . Es un marco ligero construido en Express. Tiene una estructura muy similar a RoR y transmite algunos de los conceptos más rudimentarios (como el enrutamiento).

Vale la pena echarle un vistazo, incluso si no planea usarlo.

EDIT 1

nodejs-express-mongoose-demo es muy similar a como tengo estructurado el mío. Echale un vistazo.


Advertencia: al hacer referencia al código que pirateé para nodos knockout, funciona, pero está lejos de ser elegante o pulido.

Para ser más específico sobre la división de app.js tengo el siguiente archivo app.js

var express = require(''express''), bootstrap = require(''./init/bootstrap.js''), app = module.exports = express.createServer(); bootstrap(app);

Esto básicamente significa que pongo todo mi bootstrapping en un archivo separado, luego reinicio el servidor.

Entonces, ¿qué hace 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"); };

Bueno, divide toda la configuración de inicialización del servidor en buenos trozos. Específicamente

  • Tengo un fragmento que configura toda mi autenticación OAuth remota con everyauth.
  • Tengo un fragmento que configura mi aplicación (básicamente llamando a app.configure )
  • Tengo un poco de código que perfora menos, así que vuelve a compilar cualquiera de mis archivos menos en CSS en tiempo de ejecución.
  • Tengo un código que configura todas mis rutas
  • Yo llamo a este pequeño módulo nko
  • Finalmente, comienzo el servidor escuchando un puerto.

Solo por ejemplo, veamos el archivo de routing

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);

Aquí cargo todos mis modelos y rutas como matrices de archivos.

Descargo de responsabilidad: readdirSync solo está bien cuando se llama antes de iniciar el servidor http (antes .listen ). Llamar a llamadas de bloqueo sincrónicas al inicio del servidor hace que el código sea más legible (básicamente es un truco)

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); } });

Aquí perforo socket.io para usar la autorización en lugar de permitir que tom y jack hablen con mi servidor socket.io

routes.forEach(function(file) { var route = require(routeUrl + file), model = require(modelUrl + file); route(app, model, io); }); };

Aquí empiezo mis rutas pasando el modelo relevante a cada objeto de ruta devuelto desde el archivo de ruta.

Básicamente, el problema es que organizas todo en pequeños módulos y luego tienes algún mecanismo de arranque.

Mi otro proyecto (mi blog) tiene un archivo init con una estructura similar .

Descargo de responsabilidad: el blog está roto y no se construye, estoy trabajando en ello.