Estou usando a estrutura da web ExpressJS para NodeJS.
As pessoas que usam ExpressJS colocar seus ambientes (desenvolvimento, produção, teste ...), suas rotas etc no app.js
. Eu acho que não é uma maneira bonita, porque quando você tem um grande aplicativo, o app.js é muito grande!
Eu gostaria de ter esta estrutura de diretórios:
| my-application
| -- app.js
| -- config/
| -- environment.js
| -- routes.js
Aqui está o meu 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 !');
});
};
Meu código funciona bem e acho que a estrutura dos diretórios é bonita. No entanto, o código teve que ser adaptado e não tenho certeza de que seja bom / bonito.
É melhor usar minha estrutura de diretórios e adaptar o código ou simplesmente usar um arquivo (app.js)?
Obrigado por seus conselhos!
Respostas:
OK, já faz um tempo e essa é uma pergunta popular, então criei um repositório de github para andaimes com código JavaScript e um README longo sobre como eu gosto de estruturar um aplicativo express.js de tamanho médio.
focusaurus / express_code_structure é o repositório com o código mais recente para isso. Solicitações pull bem-vindas.
Aqui está um instantâneo do README, já que o stackoverflow não gosta de respostas apenas por um link. Farei algumas atualizações, pois este é um novo projeto que continuarei atualizando, mas no final o repositório do github será o local atualizado para essas informações.
Estrutura do código expresso
Este projeto é um exemplo de como organizar um aplicativo Web express.js de tamanho médio.
Atual para pelo menos expressar v4.14 de dezembro de 2016
Qual é o tamanho da sua aplicação?
Os aplicativos da Web não são todos iguais e, na minha opinião, não existe uma única estrutura de código que deva ser aplicada a todos os aplicativos express.js.
Se seu aplicativo for pequeno, você não precisará de uma estrutura de diretórios tão profunda como exemplificada aqui. Apenas mantenha a simplicidade e cole alguns
.js
arquivos na raiz do seu repositório e pronto. Voilà.Se seu aplicativo for enorme, em algum momento você precisará dividi-lo em pacotes npm distintos. Em geral, a abordagem node.js parece favorecer muitos pacotes pequenos, pelo menos para bibliotecas, e você deve criar seu aplicativo usando vários pacotes npm, pois isso começa a fazer sentido e justificar a sobrecarga. Assim, à medida que seu aplicativo cresce e parte do código se torna claramente reutilizável fora do aplicativo ou é um subsistema claro, mova-o para seu próprio repositório git e faça-o em um pacote npm independente.
Portanto, o foco deste projeto é ilustrar uma estrutura viável para um aplicativo de tamanho médio.
Qual é a sua arquitetura geral
Existem muitas abordagens para criar um aplicativo Web, como
Cada um deles se encaixa perfeitamente em uma estrutura de diretórios diferente. Para os fins deste exemplo, é apenas um andaime e não um aplicativo totalmente funcional, mas estou assumindo os seguintes pontos principais da arquitetura:
E o Ruby on Rails?
Será um tema ao longo deste projeto que muitas das idéias incorporadas no Ruby on Rails e as decisões da "Convenção sobre configuração" que eles adotaram, embora amplamente aceitas e usadas, não são realmente muito úteis e às vezes são o oposto do que esse repositório recomenda.
Meu ponto principal aqui é que existem princípios subjacentes à organização do código e, com base nesses princípios, as convenções Ruby on Rails fazem sentido (principalmente) para a comunidade Ruby on Rails. No entanto, apenas imitar essas convenções sem pensar perde o objetivo. Depois de conhecer os princípios básicos, TODOS os seus projetos serão bem organizados e claros: shell scripts, jogos, aplicativos móveis, projetos corporativos e até o diretório inicial.
Para a comunidade Rails, eles desejam ter um único desenvolvedor de Rails alternando de aplicativo para aplicativo e se familiarizar e se familiarizar com ele a cada vez. Isso faz muito sentido se você tiver 37 sinais ou o Pivotal Labs e tiver benefícios. No mundo JavaScript do lado do servidor, o ethos geral é apenas muito mais a oeste, e não temos realmente nenhum problema com isso. É assim que nós fazemos. Estamos acostumados a isso. Mesmo no express.js, é um parente próximo do Sinatra, não do Rails, e aceitar convenções do Rails geralmente não ajuda em nada. Eu diria até Princípios sobre Convenção sobre Configuração .
Princípios e motivações subjacentes
app/node_modules
diretório e têmpackage.json
arquivos nos diretórios proto-module para facilitar essa transição e agir como um lembrete.app
diretório para que você possacd
executar find / grep / xargs / ag / ack / etc e não se distrair com correspondências de terceiroskebab-case
mesmo que o nome da variável no JavaScript deva sercamelCase
porque-
é um sinal de menos no JavaScript.kebab-case
transformado emcamelCase
app/views
,app/controllers
,app/models
, etcroutes.rb
arquivo no estilo trilhos é útil se você deseja ter uma visão geral de todas as rotas no aplicativo, mas ao criar recursos e corrigir bugs, você se preocupa apenas com as rotas relevantes para a peça que está sendo alterada.app/users
porque não existe um ninho de ratos de lógica de negócios acoplada em todo o lugar, poluindo a pureza da base de códigos do usuário.app/server.js:1
e você pode ver tudo o que carrega e executa seguindo o código.magicRESTRouter.route(somecontroller, {except: 'POST'})
é uma grande vitória para você mais de 3 básicoapp.get
,app.put
,app.del
, chamadas, provavelmente você está criando um aplicativo monolítico que é muito grande para trabalhar eficazmente diante. Seja extravagante por grandes vitórias, não pela conversão de 3 linhas simples em 1 linha complexa.Use nomes de arquivos com letras minúsculas no kebab
express.js específicos
Não use
app.configure
. É quase totalmente inútil e você simplesmente não precisa. É um monte de boilerplate devido a copypasta irracional.app.use
para todo o aplicativo se você realmente só precisa desse middleware para 2 rotas (estou olhando para vocêbody-parser
)server.js
e ficará claro como elas serão ordenadas. Para um aplicativo de tamanho médio, é bom dividir as coisas em módulos de rotas separadas, mas introduz o perigo do middleware fora de ordemO truque de link simbólico do aplicativo
Existem muitas abordagens descritas e discutidas em profundidade pela comunidade na grande essência Melhor locais exigem caminhos () para Node.js . Em breve, posso decidir preferir "apenas lidar com lotes de ../../../ .." ou usar o modulo requireFrom. No entanto, no momento, eu tenho usado o truque de link simbólico detalhado abaixo.
Portanto, uma maneira de evitar o intraprojeto exige caminhos relativos irritantes, como
require("../../../config")
é usar o seguinte truque:.gitignore
arquivovar config = require("app/config");
var DealModel = require("app/deals/deal-model")
;Configuração
Geralmente codifique módulos e classes para esperar apenas a
options
passagem de um objeto JavaScript básico . Somente oapp/server.js
carregamento deve ser carregadoapp/config.js
. A partir daí, ele pode sintetizaroptions
objetos pequenos para configurar subsistemas, conforme necessário, mas o acoplamento de cada subsistema a um grande módulo de configuração global cheio de informações extras é um acoplamento ruim.Tente centralizar a criação de conexões com o banco de dados e passe-as para os subsistemas, em vez de passar os parâmetros de conexão e fazer com que os subsistemas façam as próprias conexões de saída.
NODE_ENV
Essa é outra idéia atraente, mas terrível, herdada do Rails. Deve haver exatamente um lugar no seu aplicativo,
app/config.js
que analisa aNODE_ENV
variável de ambiente. Tudo o resto deve ter uma opção explícita como argumento do construtor de classe ou parâmetro de configuração do módulo.Se o módulo de e-mail tiver uma opção de como enviar e-mails (SMTP, log para stdout, colocar na fila etc.), deve ser uma opção como
{deliver: 'stdout'}
essa, mas absolutamente não deve ser verificadaNODE_ENV
.Testes
Agora, mantenho meus arquivos de teste no mesmo diretório que o código correspondente e uso as convenções de nomenclatura de extensão de nome de arquivo para distinguir testes de código de produção.
foo.js
tem o código do módulo "foo"foo.tape.js
possui os testes baseados em nós para foo e vive no mesmo diretóriofoo.btape.js
pode ser usado para testes que precisam ser executados em um ambiente de navegadorUso globs do sistema de arquivos e o
find . -name '*.tape.js'
comando para obter acesso a todos os meus testes, conforme necessário.Como organizar o código dentro de cada
.js
arquivo de móduloO escopo deste projeto é principalmente para onde os arquivos e diretórios vão, e não quero adicionar muito outro escopo, mas mencionarei apenas que organizo meu código em três seções distintas.
fonte
UPDATE (29/10/2013) : consulte também minha outra resposta, que possui JavaScript em vez de CoffeeScript pela demanda popular, além de um repositório do github padrão e um README extenso detalhando minhas recomendações mais recentes sobre este tópico.
Config
O que você está fazendo está bem. Eu gosto de ter meu próprio namespace de configuração configurado em um
config.coffee
arquivo de nível superior com um namespace aninhado como este.Isso é amigável para a edição do sysadmin. Então, quando eu preciso de algo, como as informações de conexão com o banco de dados, é
Rotas / Controladores
Eu gosto de deixar minhas rotas com meus controladores e organizá-las em um
app/controllers
subdiretório. Então eu posso carregá-los e deixá-los adicionar as rotas necessárias.No meu
app/server.coffee
arquivo coffeescript eu faço:Então, eu tenho arquivos como:
E, por exemplo, no meu controlador de domínios, tenho uma
setup
função como esta.Visualizações
Colocar pontos de vista
app/views
está se tornando o local habitual. Eu coloco isso assim.Arquivos estáticos
Vá em um
public
subdiretório.Github / Semver / NPM
Coloque um arquivo de marcação README.md na raiz do seu repositório git para github.
Coloque um arquivo package.json com um número de versão semântica no seu git repo root para o NPM.
fonte
app.put route, api.needId
Go
e incluí obin
arquivo na estrutura. Como você executa essego
arquivobin
?A seguir, é apresentada a resposta de Peter Lyons, literalmente, portada para baunilha JS do Coffeescript, conforme solicitado por vários outros. A resposta de Peter é muito capaz, e qualquer pessoa que vote na minha resposta deve votar nela também.
Config
O que você está fazendo está bem. Eu gosto de ter meu próprio namespace de configuração configurado em um
config.js
arquivo de nível superior com um namespace aninhado como este.Isso é amigável para a edição do sysadmin. Então, quando eu preciso de algo, como as informações de conexão com o banco de dados, é
Rotas / Controladores
Eu gosto de deixar minhas rotas com meus controladores e organizá-las em um
app/controllers
subdiretório. Então eu posso carregá-los e deixá-los adicionar as rotas necessárias.No meu
app/server.js
arquivo javascript eu faço:Então, eu tenho arquivos como:
E, por exemplo, no meu controlador de domínios, eu tenho um
setup
função como esta.Visualizações
Colocar visualizações em
app/views
está se tornando o local habitual. Eu coloco isso assim.Arquivos estáticos
Vá em um
public
subdiretório.Github / Semver / NPM
Coloque um arquivo de marcação README.md na raiz do seu repositório git para github.
Coloque um arquivo package.json com um número de versão semântica no seu git repo root para o NPM.
fonte
Minha pergunta foi introduzida em abril de 2011, é muito antiga. Durante esse período, pude melhorar minha experiência com o Express.js e como arquitetar um aplicativo escrito usando esta biblioteca. Então, compartilho aqui minha experiência.
Aqui está a minha estrutura de diretórios:
App.js
O objetivo do
app.js
arquivo é inicializar o aplicativo expressjs. Carrega o módulo de configuração, o módulo de logger, aguarda a conexão com o banco de dados, ... e executa o servidor expresso.rotas /
O diretório de rotas possui um
index.js
arquivo. Seu objetivo é introduzir um tipo de mágica para carregar todos os outros arquivos dentro doroutes/
diretório. Aqui está a implementação:Com esse módulo, é realmente fácil criar uma nova definição e implementação de rota. Por exemplo
hello.js
:Cada módulo de rota é autônomo .
fonte
Eu gosto de usar um "aplicativo" global, em vez de exportar uma função etc.
fonte
Eu acho que é uma ótima maneira de fazer isso. Não estou limitado a expressar, mas já vi vários projetos node.js no github fazendo a mesma coisa. Eles retiram os parâmetros de configuração + módulos menores (em alguns casos, todos os URI) são fatorados em arquivos separados.
Eu recomendaria passar por projetos expressos específicos no github para ter uma idéia. IMO do jeito que você está fazendo está correto.
fonte
agora é final de 2015 e depois de desenvolver minha estrutura por 3 anos e em projetos pequenos e grandes. Conclusão?
Não faça um MVC grande, mas separe-o em módulos
Assim...
Por quê?
Normalmente, trabalha-se em um módulo (por exemplo, produtos), que você pode alterar independentemente.
Você pode reutilizar módulos
Você é capaz de testá-lo separadamente
Você pode substituí-lo separadamente
Eles têm interfaces claras (estáveis)
-No máximo, se houver vários desenvolvedores trabalhando, a separação de módulos ajuda
O projeto nodebootstrap tem uma abordagem semelhante à minha estrutura final. ( github )
Como é essa estrutura?
Módulos pequenos e capsulados , cada um com MVC separado
Cada módulo possui um package.json
Testando como parte da estrutura (em cada módulo)
Configuração global , bibliotecas e serviços
Docker integrado, cluster, para sempre
Folderoverview (consulte a pasta lib para obter os módulos):
fonte
Estou dando a estrutura de pastas no estilo MVC, por favor, veja abaixo.
Usamos a estrutura de pastas abaixo para nossos aplicativos Web grandes e médios.
Eu criei um módulo npm para geração de estruturador de pastas mvc express.
Encontre o seguinte https://www.npmjs.com/package/express-mvc-generator
Apenas etapas simples para gerar e usar esses módulos.
i) instale o módulo
npm install express-mvc-generator -g
ii) verificar opções
express -h
iii) Gere estrutura expressa de mvc
express myapp
iv) Instalar dependências
npm install
::v) Abra o seu config / database.js. Por favor, configure o seu mongo db.
vi) Execute o aplicativo
node app
ounodemon app
vii) Verifique o URL http: // localhost: 8042 / signup OU http: // yourip: 8042 / signup
fonte
Já faz um bom tempo desde a última resposta a esta pergunta e o Express também lançou recentemente a versão 4, que adicionou algumas coisas úteis para organizar a estrutura do seu aplicativo.
Abaixo, há uma postagem de blog longa e atualizada sobre as práticas recomendadas sobre como estruturar seu aplicativo Express. http://www.terlici.com/2014/08/25/best-practices-express-structure.html
Há também um repositório do GitHub que aplica os conselhos deste artigo. Está sempre atualizado com a versão mais recente do Express.
https://github.com/terlici/base-express
fonte
Eu não acho que seja uma boa abordagem adicionar rotas à configuração. Uma estrutura melhor poderia ser algo como isto:
Portanto, products.js e users.js conterão todas as suas rotas, todas dentro da lógica.
fonte
Bem, eu coloquei minhas rotas como um arquivo json, que li no início, e em um loop for no app.js, configurei as rotas. O route.json inclui qual visualização deve ser chamada e a chave para os valores que serão enviados para a rota.
Isso funciona para muitos casos simples, mas tive que criar manualmente algumas rotas para casos especiais.
fonte
Eu escrevi um post exatamente sobre esse assunto. Basicamente, utiliza um
routeRegistrar
que itera através de arquivos na pasta/controllers
chamando sua funçãoinit
. A funçãoinit
usa aapp
variável express como parâmetro, para que você possa registrar suas rotas da maneira que desejar.fonte
Isso pode ser de interesse:
https://github.com/flatiron/nconf
fonte
1) O sistema de arquivos do seu projeto Express pode ser como:
app.js - seu contêiner global de aplicativos
2) Arquivo principal do módulo (lib / mymodule / index.js):
3) Conecte o módulo no app.js principal
4) Exemplo de lógica
tj diz / mostra no Vimeo uma idéia interessante de como modularizar o aplicativo expresso - aplicativos Web modulares com Node.js. e Express . Poderoso e simples.
fonte
http://locomotivejs.org/ fornece uma maneira de estruturar um aplicativo criado com Node.js e Express.
A partir do site:
fonte
Recentemente, abracei os módulos como mini-aplicativos independentes.
Agora, para qualquer roteamento de módulo (# .js), visualizações (* .ejs), js, css e ativos estão próximos um do outro. o roteamento do submódulo é configurado no pai # .js com duas linhas adicionais
Dessa forma, até os subsub-módulos são possíveis.
Não se esqueça de definir a exibição no diretório src
fonte
É assim que parece a maior parte da minha estrutura de diretórios de projeto expresso.
Eu costumo fazer uma
express dirname
inicialização do projeto, perdoar minha preguiça, mas é muito flexível e extensível. PS - você precisaexpress-generator
disso (para quem está procurandosudo npm install -g express-generator
, sudo porque você está instalando globalmente)Você deve estar se perguntando por que arquivos .env? Porque eles trabalham! Eu uso o
dotenv
módulo em meus projetos (muito recentemente) e funciona! Entre nessas duas declarações emapp.js
ouwww
E outra linha para configurar rapidamente
/bower_components
para veicular conteúdo estático sob o recurso/ext
Provavelmente pode ser adequado para pessoas que desejam usar o Express e o Angular juntos, ou apenas se expressam sem essa
javascripts
hierarquia, é claro.fonte
Minha estrutura expressa 4. https://github.com/odirleiborgert/borgert-express-boilerplate
Pacotes
Estrutura
fonte
Uma maneira simples de estruturar seu aplicativo expresso:
No principal index.js, a seguinte ordem deve ser mantida.
fonte
Melhor maneira de estrutura MVC para o projeto ExpressJs com guidão e Passportjs
fonte