Estoy usando el framework web ExpressJS para NodeJS.
Las personas que usan ExpressJS ponen sus entornos (desarrollo, producción, pruebas ...), sus rutas, etc en el app.js
. Creo que no es una manera hermosa porque cuando tienes una aplicación grande, ¡app.js es demasiado grande!
Me gustaría tener esta estructura de directorios:
| my-application
| -- app.js
| -- config/
| -- environment.js
| -- routes.js
Aquí está mi código:
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 !');
});
};
Mi código funciona bien y creo que la estructura de los directorios es hermosa. Sin embargo, el código tuvo que adaptarse y no estoy seguro de que sea bueno / hermoso.
¿Es mejor usar mi estructura de directorios y adaptar el código o simplemente usar un archivo (app.js)?
¡Gracias por tus consejos!
Respuestas:
OK, ha pasado un tiempo y esta es una pregunta popular, así que seguí adelante y creé un repositorio de andamios github con código JavaScript y un largo archivo README sobre cómo me gusta estructurar una aplicación express.js de tamaño mediano.
focusaurus / express_code_structure es el repositorio con el último código para esto. Solicitudes de extracción bienvenidas.
Aquí hay una instantánea de README ya que stackoverflow no le gusta las respuestas de solo un enlace. Haré algunas actualizaciones ya que este es un nuevo proyecto que continuaré actualizando, pero finalmente el repositorio de github será el lugar actualizado para esta información.
Estructura de código expreso
Este proyecto es un ejemplo de cómo organizar una aplicación web express.js de tamaño mediano.
Actual al menos expreso v4.14 de diciembre de 2016
¿Qué tan grande es su aplicación?
Las aplicaciones web no son todas iguales y, en mi opinión, no hay una única estructura de código que deba aplicarse a todas las aplicaciones express.js.
Si su aplicación es pequeña, no necesita una estructura de directorio tan profunda como se ejemplifica aquí. Simplemente manténgalo simple y pegue un puñado de
.js
archivos en la raíz de su repositorio y listo. Voilà.Si su aplicación es enorme, en algún momento deberá dividirla en paquetes npm distintos. En general, el enfoque de node.js parece favorecer muchos paquetes pequeños, al menos para las bibliotecas, y debe construir su aplicación utilizando varios paquetes npm, ya que eso comienza a tener sentido y justifica la sobrecarga. Entonces, a medida que su aplicación crece y una parte del código se vuelve claramente reutilizable fuera de su aplicación o es un subsistema claro, muévalo a su propio repositorio git y conviértalo en un paquete npm independiente.
Por lo tanto, el objetivo de este proyecto es ilustrar una estructura viable para una aplicación de tamaño mediano.
¿Cuál es su arquitectura general?
Existen muchos enfoques para crear una aplicación web, como
Cada uno de estos encaja perfectamente en una estructura de directorio diferente. Para los propósitos de este ejemplo, solo se trata de andamios y no es una aplicación que funciona completamente, pero supongo que los siguientes puntos clave de la arquitectura:
¿Y qué hay de Ruby on Rails?
Será un tema a lo largo de este proyecto que muchas de las ideas incorporadas en Ruby on Rails y las decisiones de "Convención sobre la configuración" que han adoptado, aunque ampliamente aceptadas y utilizadas, en realidad no son muy útiles y a veces son lo contrario de lo que este repositorio recomienda
Mi punto principal aquí es que existen principios subyacentes para organizar el código, y basados en esos principios, las convenciones de Ruby on Rails tienen sentido (principalmente) para la comunidad de Ruby on Rails. Sin embargo, simplemente imitar esas convenciones sin pensarlo pasa por alto el punto. Una vez que comprenda los principios básicos, TODOS sus proyectos estarán bien organizados y claros: scripts de shell, juegos, aplicaciones móviles, proyectos empresariales, incluso su directorio de inicio.
Para la comunidad de Rails, quieren poder tener un solo desarrollador de Rails para cambiar de una aplicación a otra y estar familiarizados y cómodos con él cada vez. Esto tiene mucho sentido si tiene 37 señales o Pivotal Labs, y tiene beneficios. En el mundo de JavaScript del lado del servidor, el ethos general es mucho más salvaje que cualquier cosa, y realmente no tenemos ningún problema con eso. Así es como nosotros lo hacemos. Estamos acostumbrados Incluso dentro de express.js, es un pariente cercano de Sinatra, no de Rails, y tomar convenciones de Rails generalmente no ayuda en nada. Incluso diría Principios sobre Convención sobre Configuración .
Principios y motivaciones subyacentes
app/node_modules
directorio y tienenpackage.json
archivos en los directorios del proto-módulo para facilitar esa transición y actuar como un recordatorio.app
directorio para que puedacd
ejecutar find / grep / xargs / ag / ack / etc y no distraerse con coincidencias de terceroskebab-case
aunque el nombre de la variable para eso en JavaScript debe sercamelCase
porque-
es un signo menos en JavaScript.kebab-case
transformado acamelCase
app/views
,app/controllers
,app/models
, etc.routes.rb
archivo de estilo de rieles es útil si desea una visión general de todas las rutas en la aplicación, pero cuando realmente crea características y corrige errores, solo le importan las rutas relevantes para la pieza que está cambiando.app/users
porque no hay un nido de ratas de lógica comercial acoplada en todo el lugar contaminando la pureza de la base de código de usuario.app/server.js:1
y puede ver todo lo que carga y ejecuta siguiendo el código.magicRESTRouter.route(somecontroller, {except: 'POST'})
es una gran victoria para usted durante 3 básicaapp.get
,app.put
,app.del
, llamadas, es probable que la construcción de una aplicación monolítica que es demasiado grande para trabajar eficazmente en. Obtenga fantasía para GRANDES victorias, no para convertir 3 líneas simples en 1 línea compleja.Utilice nombres de archivo en minúsculas kebab
Detalles de express.js
No utilice
app.configure
. Es casi completamente inútil y simplemente no lo necesitas. Está en un montón de repeticiones debido a la copia sin sentido.app.use
para toda su aplicación si realmente solo necesita ese middleware para 2 rutas (lo estoy mirandobody-parser
)server.js
y estará claro cómo se ordenan. Para una aplicación de tamaño mediano, dividir las cosas en módulos de rutas separadas es bueno, pero presenta un peligro de middleware fuera de servicioEl truco del enlace simbólico de la aplicación
Hay muchos enfoques descritos y discutidos ampliamente por la comunidad en la gran GIST Mejor locales requieren caminos () para Node.js . Pronto puedo decidir preferir "tratar con muchos ../../../ .." o usar el módulo requireFrom. Sin embargo, por el momento, he estado usando el truco de enlace simbólico que se detalla a continuación.
Entonces, una forma de evitar el intraproyecto requiere con rutas relativas molestas como
require("../../../config")
es usar el siguiente truco:.gitignore
archivovar config = require("app/config");
var DealModel = require("app/deals/deal-model")
;Configuración
Generalmente, los módulos y clases de código esperan que solo se
options
pase un objeto JavaScript básico . Solo seapp/server.js
debe cargar elapp/config.js
módulo. A partir de ahí, puede sintetizar pequeñosoptions
objetos para configurar subsistemas según sea necesario, pero acoplar cada subsistema a un gran módulo de configuración global lleno de información adicional es un mal acoplamiento.Intente centralizar la creación de conexiones de base de datos y pasarlas a subsistemas en lugar de pasar parámetros de conexión y hacer que los subsistemas establezcan conexiones salientes.
NODE_ENV
Esta es otra idea tentadora pero terrible de Rails. Debe haber exactamente 1 lugar en su aplicación,
app/config.js
que observe laNODE_ENV
variable de entorno. Todo lo demás debería tomar una opción explícita como argumento de constructor de clase o parámetro de configuración del módulo.Si el módulo de correo electrónico tiene una opción sobre cómo entregar correos electrónicos (SMTP, iniciar sesión en stdout, poner en cola, etc.), debería tomar una opción como,
{deliver: 'stdout'}
pero no debería comprobarloNODE_ENV
.Pruebas
Ahora mantengo mis archivos de prueba en el mismo directorio que su código correspondiente y uso convenciones de nomenclatura de extensión de nombre de archivo para distinguir las pruebas del código de producción.
foo.js
tiene el código del módulo "foo"foo.tape.js
tiene las pruebas basadas en nodos para foo y vive en el mismo directoriofoo.btape.js
se puede usar para pruebas que deben ejecutarse en un entorno de navegadorUso globs del sistema de archivos y el
find . -name '*.tape.js'
comando para obtener acceso a todas mis pruebas según sea necesario.Cómo organizar el código dentro de cada
.js
archivo de móduloEl alcance de este proyecto se trata principalmente de dónde van los archivos y directorios, y no quiero agregar mucho otro alcance, pero solo mencionaré que organizo mi código en 3 secciones distintas.
fuente
ACTUALIZACIÓN (2013-10-29) : consulte también mi otra respuesta que tiene JavaScript en lugar de CoffeeScript por demanda popular, así como un repositorio de github repetitivo y un extenso README que detalla mis últimas recomendaciones sobre este tema.
Config
Lo que estás haciendo está bien. Me gusta tener mi propio espacio de nombres de configuración configurado en un
config.coffee
archivo de nivel superior con un espacio de nombres anidado como este.Esto es amigable para la edición de administrador de sistemas. Luego, cuando necesito algo, como la información de conexión de DB, es
Rutas / Controladores
Me gusta dejar mis rutas con mis controladores y organizarlas en un
app/controllers
subdirectorio. Luego puedo cargarlos y dejar que agreguen las rutas que necesiten.En mi
app/server.coffee
archivo coffeescript hago:Entonces tengo archivos como:
Y, por ejemplo, en mi controlador de dominios, tengo una
setup
función como esta.Puntos de vista
Poner vistas se
app/views
está convirtiendo en el lugar habitual. Lo expongo así.Archivos estáticos
Ir en un
public
subdirectorio.Github / Semver / NPM
Ponga un archivo README.md markdown en su raíz de repositorio de git para github.
Coloque un archivo package.json con un número de versión semántica en su raíz de repositorio git para NPM.
fuente
app.put route, api.needId
Go
e incluí elbin
archivo en la estructura. ¿Cómo ejecuta esego
archivobin
?La siguiente es la respuesta literal de Peter Lyons, portada a vanilla JS de Coffeescript, según lo solicitado por varios otros. La respuesta de Peter es muy capaz, y cualquiera que vote por mi respuesta también debería votar por la suya.
Config
Lo que estás haciendo está bien. Me gusta tener mi propio espacio de nombres de configuración configurado en un
config.js
archivo de nivel superior con un espacio de nombres anidado como este.Esto es amigable para la edición de administrador de sistemas. Luego, cuando necesito algo, como la información de conexión de DB, es
Rutas / Controladores
Me gusta dejar mis rutas con mis controladores y organizarlas en un
app/controllers
subdirectorio. Luego puedo cargarlos y dejar que agreguen las rutas que necesiten.En mi
app/server.js
archivo javascript hago:Entonces tengo archivos como:
Y, por ejemplo, en mi controlador de dominios, tengo una
setup
función como esta.Puntos de vista
Poner vistas se
app/views
está convirtiendo en el lugar habitual. Lo expongo así.Archivos estáticos
Ir en un
public
subdirectorio.Github / Semver / NPM
Ponga un archivo README.md markdown en su raíz de repositorio de git para github.
Coloque un archivo package.json con un número de versión semántica en su raíz de repositorio git para NPM.
fuente
Mi pregunta fue presentada en abril de 2011, es bastante antigua. Durante este tiempo, pude mejorar mi experiencia con Express.js y cómo diseñar una aplicación escrita usando esta biblioteca. Entonces, comparto aquí mi experiencia.
Aquí está mi estructura de directorios:
App.js
El objetivo del
app.js
archivo es arrancar la aplicación expressjs. Carga el módulo de configuración, el módulo de registro, espera la conexión de la base de datos, ... y ejecuta el servidor express.rutas /
El directorio de rutas tiene un
index.js
archivo. Su objetivo es introducir un tipo de magia para cargar todos los demás archivos dentro delroutes/
directorio. Aquí está la implementación:Con ese módulo, crear una nueva definición de ruta e implementación es realmente fácil. Por ejemplo
hello.js
:Cada módulo de ruta es independiente .
fuente
Me gusta usar una "aplicación" global, en lugar de exportar una función, etc.
fuente
Creo que es una excelente forma de hacerlo. No se limita a express, pero he visto bastantes proyectos de node.js en github que hacen lo mismo. Sacan los parámetros de configuración + módulos más pequeños (en algunos casos, cada URI) se factorizan en archivos separados.
Recomendaría pasar por proyectos expresos específicos en github para tener una idea. OMI, la forma en que lo estás haciendo es correcta.
fuente
ahora es finales de 2015 y después de desarrollar mi estructura durante 3 años y en proyectos pequeños y grandes. ¿Conclusión?
No haga un MVC grande, sino sepárelo en módulos.
Entonces...
¿Por qué?
Por lo general, uno funciona en un módulo (por ejemplo, Productos), que puede cambiar de forma independiente.
Puede reutilizar módulos
Puedes probarlo por separado
Puede reemplazarlo por separado
Tienen interfaces claras (estables)
A más tardar, si había varios desarrolladores trabajando, la separación de módulos ayuda
El proyecto nodebootstrap tiene un enfoque similar a mi estructura final. ( github )
¿Cómo se ve esta estructura?
Pequeños módulos encapsulados , cada uno con MVC separado
Cada módulo tiene un paquete.json
Pruebas como parte de la estructura (en cada módulo)
Configuración global , bibliotecas y servicios
Integrado Docker, Cluster, para siempre
Folderverview (ver la carpeta lib para los módulos):
fuente
Estoy dando la estructura de carpetas de estilo MVC, por favor encuentre a continuación.
Utilizamos la siguiente estructura de carpetas para nuestras aplicaciones web grandes y medianas.
He creado un módulo npm para la generación de estructurador de carpetas express mvc.
Encuentre el siguiente https://www.npmjs.com/package/express-mvc-generator
Solo pasos simples para generar y usar estos módulos.
i) instalar el módulo
npm install express-mvc-generator -g
ii) verifique las opciones
express -h
iii) Generar estructura express de mvc
express myapp
iv) Instalar dependencias
npm install
::v) Abra su config / database.js, configure su mongo db.
vi) Ejecute la aplicación
node app
onodemon app
vii) Compruebe la URL http: // localhost: 8042 / signup O http: // yourip: 8042 / signup
fuente
Ha pasado bastante tiempo desde la última respuesta a esta pregunta y Express también lanzó recientemente la versión 4, que agregó algunas cosas útiles para organizar la estructura de su aplicación.
A continuación se muestra una publicación de blog larga y actualizada sobre las mejores prácticas sobre cómo estructurar su aplicación Express. http://www.terlici.com/2014/08/25/best-practices-express-structure.html
También hay un repositorio de GitHub que aplica los consejos del artículo. Siempre está actualizado con la última versión Express.
https://github.com/terlici/base-express
fuente
No creo que sea un buen enfoque agregar rutas a la configuración. Una mejor estructura podría ser algo como esto:
Por lo tanto, products.js y users.js contendrán todas sus rutas con toda la lógica dentro.
fuente
Bueno, puse mis rutas como un archivo json, que leí al principio, y en un bucle for en app.js configuré las rutas. Route.json incluye la vista que debe llamarse y la clave de los valores que se enviarán a la ruta.
Esto funciona para muchos casos simples, pero tuve que crear manualmente algunas rutas para casos especiales.
fuente
He escrito una publicación exactamente sobre este asunto. Básicamente hace uso de un
routeRegistrar
que itera a través de archivos en la carpeta que/controllers
llama a su funcióninit
. La funcióninit
toma laapp
variable express como parámetro para que pueda registrar sus rutas de la manera que desee.fuente
Esto puede ser de interés:
https://github.com/flatiron/nconf
fuente
1) Su sistema de archivos de proyecto Express puede ser como:
app.js: tu contenedor global de aplicaciones
2) Archivo principal del módulo (lib / mymodule / index.js):
3) Conecte el módulo en app.js principal
4) lógica de muestra
tj dice / muestra en Vimeo una idea interesante de cómo modularizar la aplicación express - Aplicaciones web modulares con Node.js y Express . Potente y simple.
fuente
http://locomotivejs.org/ proporciona una forma de estructurar una aplicación creada con Node.js y Express.
Desde el sitio web:
fuente
Recientemente adopté los módulos como miniaplicaciones independientes.
Ahora, para cualquier enrutamiento de módulos (# .js), las vistas (* .ejs), js, css y los activos están uno al lado del otro. el enrutamiento de submódulos se configura en el padre # .js con dos líneas adicionales
De esta manera, incluso los submódulos son posibles.
No olvide configurar la vista en el directorio src
fuente
Así es como se ve la mayoría de la estructura de directorios de mi proyecto express.
Normalmente hago un
express dirname
para inicializar el proyecto, perdono mi pereza, pero es muy flexible y ampliable. PD: necesita obtenerexpress-generator
eso (para aquellos que lo buscansudo npm install -g express-generator
, sudo porque lo está instalando a nivel mundial)Debe preguntarse por qué los archivos .env? ¡Porque funcionan! ¡Uso el
dotenv
módulo en mis proyectos (mucho recientemente) y funciona! Pop en estas 2 declaraciones enapp.js
owww
Y otra línea para configurar rápidamente
/bower_components
para servir contenido estático bajo el recurso/ext
Probablemente sea adecuado para las personas que buscan usar Express y Angular juntas, o simplemente expresarse sin esa
javascripts
jerarquía, por supuesto.fuente
Mi estructura expresa 4. https://github.com/odirleiborgert/borgert-express-boilerplate
Paquetes
Estructura
fuente
Una forma sencilla de estructurar su aplicación express:
En index.js principal, se debe mantener el siguiente orden.
fuente
La mejor forma de estructura MVC para el proyecto ExpressJs con manillar y Passportjs
fuente