ExpressJS как структурировать приложение?

я использую веб-фреймворк ExpressJS для NodeJS.

люди используя ExpressJS кладут их окружающие среды (развитие, продукцию, испытание...), их маршруты и т. д. app.js. Я думаю, что это не красивый способ, потому что, когда у вас есть большое приложение, приложение.js слишком большой!

Я хотел бы иметь эту структуру каталогов:

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

вот мой код:

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

конфиг/среды.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/маршруты.js

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

мой код работает хорошо, и я думаю, что структура каталогов-это красиво. Однако код пришлось адаптировать, и я не уверен, что он хорош/красив.

лучше использовать мою структуру каталогов и адаптировать код или просто использовать один файл (приложение.js)?

Спасибо за Ваши советы!

18 ответов


хорошо, прошло некоторое время, и это популярный вопрос, поэтому я пошел вперед и создал репозиторий GitHub с JavaScript-кодом и длинным README о том, как мне нравится структурировать экспресс среднего размера.приложение js.

focusaurus / express_code_structure является РЕПО с последним кодом для этого. Запросы добро пожаловать.

вот снимок README, так как stackoverflow не любит ответы только по ссылке. Я сделаю несколько обновления, поскольку это новый проект, который я буду продолжать обновлять, но в конечном итоге РЕПО github будет обновленным местом для этой информации.


Структура Экспресс-Кода

этот проект является примером того, как организовать средних экспресс.веб-приложения на JS.

ток не менее выразить В4.14 декабря 2016

Build Status

js-standard-style

насколько велика ваша заявка?

веб-приложения не все одинаковы, и, на мой взгляд, нет единой структуры кода, которая должна применяться ко всем express.приложения на JS.

если ваше приложение мало,вам не нужна такая глубокая структура каталогов, как показано здесь. Просто держите его простым и вставьте горсть .js файлы в корне вашего репозитория, и все готово. Вот.

если ваше приложение является огромная, в какой-то момент вам нужно разбить его на отдельные пакеты npm. В общем узел.подход js, похоже, благоприятствует многим небольшим пакетам, по крайней мере для библиотек, и вы должны создать свое приложение, используя несколько пакетов npm, поскольку это начинает иметь смысл и оправдывать накладные расходы. Так как ваше приложение растет, и некоторая часть кода становится явно многоразовой за пределами вашего приложение или является четкой подсистемой, переместите ее в собственный репозиторий git и превратите в автономный пакет npm.

так цель этого проекта-проиллюстрировать работоспособную структуру для приложения среднего размера.

какова ваша общая архитектура

существует множество подходов к созданию веб-приложения, таких как

  • серверная сторона MVC a la Ruby on Rails
  • Одностраничное Приложение стиль a la MongoDB / Express / угловой / узел (средний)
  • базовый веб-сайт с некоторыми формами
  • модели / операции/просмотры / события стиль a la MVC мертв, пришло время двигаться дальше
  • и многие другие как текущие, так и исторические

каждый из них вписывается в другую структуру каталогов. Для целей этого примера это просто строительные леса, а не полностью рабочее приложение, но я предполагаю следующую ключевую архитектуру очки:

  • на сайте есть несколько традиционных статических страниц / шаблонов
  • часть сайта "приложение" разрабатывается как одностраничный стиль приложения
  • приложение предоставляет REST / JSON style API для браузера
  • приложение моделирует простой бизнес-домен, в этом случае это приложение автосалона

а как насчет Ruby on Rails?

это будет тема на протяжении всего этого проект, что многие идеи, воплощенные в Ruby on Rails и решениях" Конвенция над конфигурацией", которые они приняли, хотя и широко приняты и используются, на самом деле не очень полезны, а иногда и противоположны тому, что рекомендует этот репозиторий.

мое главное замечание здесь в том, что существуют базовые принципы организации кода, и на основе этих принципов соглашения Ruby on Rails имеют смысл (в основном) для сообщества Ruby on Rails. Однако, просто бездумно подражание этим условностям не имеет смысла. Как только вы изучите основные принципы, все ваши проекты будут хорошо организованы и понятны: сценарии оболочки, игры, Мобильные приложения, корпоративные проекты, даже ваш домашний каталог.

для сообщества Rails они хотят иметь возможность переключаться с одного разработчика Rails из приложения в приложение и быть знакомыми и удобными с ним каждый раз. Это имеет большой смысл, если вы 37 сигналов или Pivotal Labs, и имеет преимущества. На стороне сервера JavaScript world, общий этос-это просто более дикий запад, и у нас действительно нет проблем с этим. Вот как мы катимся. Мы к этому привыкли. Даже в экспресс.js, это близкий родственник Синатры, а не Rails, и принятие конвенций с Rails обычно ничего не помогает. Я бы даже сказал принципы над соглашением над конфигурацией.

основные принципы и мотивы

  • быть психически легкоуправляемый
    • размер-соотвествующий
      • не создавайте "каталоги особняка", где есть только 1 файл в одиночку 3 каталога вниз. Вы можете видеть, что это происходит в Ansible Лучшие Практики это позорит небольшие проекты в создании 10 + каталогов для хранения 10 + файлов, когда 1 каталог с 3 файлами будет гораздо более подходящим. Вы не водите автобус на работу (если вы не водитель автобуса, но даже тогда вы водите автобус на работе, чтобы не работать), поэтому не создавайте структуры файловой системы, которые не оправданы фактическими файлами внутри них.
    • быть модульным, но прагматичным
      • сообщество узлов в целом предпочитает небольшие модули. Все, что можно четко отделить от вашего приложения полностью должен быть извлечен в модуль для внутреннего использования или публично опубликован на npm. Однако для средних приложений, которые являются областью здесь, накладные расходы могут добавить скуку в рабочий процесс без соответствующей ценности. Поэтому на время, когда у вас есть какой-то код, который учитывается, но недостаточно, чтобы оправдать полностью отдельный модуль npm, просто считайте его"прото-модуль " с ожиданием, что когда он пересечет некоторый порог размера, это будет извлеченные из.
      • некоторые люди, такие как @hij1nx даже включать и package.json файлы прото-модуль каталоги, чтобы облегчить этот переход и действовать как напоминание.
    • легко найти код
      • учитывая функцию для сборки или ошибку для исправления, наша цель заключается в том, что разработчик не имеет никаких проблем с поиском исходных файлов.
      • имена значимы и точный
      • crufty код полностью удален, не оставлен в сиротском файле или просто прокомментирован
    • быть дружественным к поиску
      • весь сторонний исходный код находится в вы можете cd есть запустить find / grep/xargs/ag/ack / etc и не отвлекаться на сторонние матчи
    • используйте простое и очевидное именование
      • npm теперь, похоже, требует имен пакетов в нижнем регистре. Я найти это в основном ужасно, но я должен следовать за стадом, поэтому имена файлов должны использовать kebab-case даже если имя переменной для этого в JavaScript должно быть camelCase, потому что - это минус в JavaScript.
      • имя переменной соответствует базовому имени module путь, но с kebab-case превращается в camelCase
    • группа соединением, не функцией
      • это крупный отход от конвенции Ruby on Rails app/views, app/controllers, app/models, etc
      • функции добавляются в полный стек, поэтому я хочу сосредоточиться на полном стеке файлов, относящихся к моей функции. Когда я добавляю поле номера телефона к пользовательской модели, меня не волнует ни один контроллер, кроме пользовательского контроллера, и меня не волнует ни одна модель, кроме пользовательской модели.
      • поэтому вместо редактирования 6 файлов, каждый из которых находится в своем собственном каталоге и игнорирует тонны других файлов в этих каталогах, этот репозиторий организован так, что все файлы, необходимые для создания функции, colocated
      • по характеру MVC представление пользователя связано с контроллером пользователя, который связан с моделью пользователя. Поэтому, когда я меняю модель пользователя, эти 3 файла часто меняются вместе, но контроллер сделок или контроллер клиентов отделены и, таким образом, не участвуют. То же самое относится и к дизайнам без MVC.
      • MVC или перемещение стиля развязки с точки зрения того, какой код идет, в котором модуль по-прежнему поощряется, но распространение файлов MVC в каталоги братьев просто раздражает.
      • таким образом, каждый из моих файлов маршрутов имеет часть маршрутов, которыми он владеет. A rails-style routes.rb файл удобен, если вы хотите обзор всех маршрутов в приложении, но при создании функций и исправлении ошибок вы заботитесь только о маршрутах, относящихся к части, которую вы меняете.
    • хранить тесты рядом с кодом
      • это просто пример "group by coupling", но я хотел назвать его конкретно. Я написал много проектов, где тесты живут в параллельной файловой системе под названием "тесты", и теперь, когда я начал помещать свои тесты в тот же каталог, что и их соответствующий код, я никогда не вернусь. Это более модульный и гораздо проще работать с текстовыми редакторами и облегчает много"../../.."путь глупости. Если вы сомневаетесь, попробуйте его на нескольких проектах и решите сами. Я не собираюсь сделайте что-нибудь еще, чтобы убедить себя, что так лучше.
    • уменьшите поперечное соединение с событиями
      • легко думать: "хорошо, когда создается новая сделка, я хочу отправить электронное письмо всем продавцам", а затем просто поместить код для отправки этих писем в маршрут, который создает сделки.
      • однако это соединение в конечном итоге превратит ваше приложение в гигантский шар грязи.
      • вместо этого DealModel должен просто стрелять событие "создать" и полностью не знать, что еще может сделать система в ответ на это.
      • когда вы кодируете таким образом, становится гораздо более возможным поместить весь пользовательский код в app/users потому что нет крысиного гнезда связанной бизнес-логики повсюду, загрязняющей чистоту базы пользовательского кода.
    • подача кода followable
      • не делайте магических вещей. Не загружайте файлы из каталогов magic в файловая система. Не рельсы. Приложение начинается с app/server.js:1 и вы можете увидеть все, что он загружает и выполняет, следуя коду.
      • не делайте DSLs для ваших маршрутов. Не занимайтесь глупым метапрограммированием, когда оно не требуется.
      • если ваше приложение настолько большое, что делает magicRESTRouter.route(somecontroller, {except: 'POST'}) - это большая победа для вас 3 основные app.get, app.put, app.del, звонки, вы, вероятно, строите монолитное приложение, которое слишком велико, чтобы эффективно работать. Получить фантазии для больших побед, а не для преобразования 3 простые линии до 1 линии.
    • использовать ниже-кебаб-случае имена

      • этот формат позволяет избежать проблем чувствительности файловой системы к регистру на разных платформах
      • npm запрещает верхний регистр в новых именах пакетов, и это хорошо работает с этим

        экспресс.специфика Яш

    • не используйте app.configure. Это почти совершенно бесполезно, и вам это просто не нужно. Это во многих шаблонный из-за безмозглых copypasta.

    • ПОРЯДОК MIDDLEWARE И МАРШРУТЫ В ЭКСПРЕСС-ВОПРОСАХ!!!
      • почти каждая проблема маршрутизации, которую я вижу в stackoverflow, является устаревшим промежуточным по express
      • в общем, вы хотите, чтобы ваши маршруты разделились и не полагаясь на порядок, что много
      • не используйте app.use для всего вашего приложения, Если вам действительно нужно только это промежуточное ПО для 2 маршрутов (я смотрю на вас, body-parser)
      • убедитесь, когда все сказано и сделано, у вас есть именно этот приказ:
        1. любое супер-важное промежуточное ПО для всего приложения
        2. все ваши маршруты и разных маршрута middlewares
        3. затем обработчики ошибок
    • к сожалению, будучи вдохновленным Синатрой, экспресс.js в основном предполагает, что все ваши маршруты будут в server.js и будет ясно, как они упорядочены. Для среднего размера приложения, разбивая вещи на отдельные модули маршрутов приятно, но это вводит опасность неупорядоченного промежуточного программного обеспечения

    приложение символическая ссылка трюк

    есть много подходов, изложенных и подробно обсуждаемых сообществом в Великой сути лучшие локальные пути require () для узла.js. Я могу скоро решить предпочесть либо " просто иметь дело с большим количеством ../../../..- или используйте requireFrom modlue. Однако на данный момент я использую трюк symlink подробно под.

    Итак, один из способов избежать интра-проект требует с раздражающим относительные пути, как require("../../../config") использовать следующий трюк:

    • создайте символическую ссылку под node_modules для вашего приложения
      • cd node_modules & & ln-nsf ../ app
    • добавить только символическая ссылка node_modules / app, не вся папка node_modules, чтобы git
      • git add-f node_modules / app
      • , вы должен все еще иметь "node_modules" в вашем
    • нет, вы не должны помещать "node_modules" в свой репозиторий git. Некоторые люди порекомендуют вам сделать это. Они неверны.
  • теперь вы можете требовать внутрипроектных модулей, используя этот префикс
    • var config = require("app/config");
    • var DealModel = require("app/deals/deal-model");
  • в основном, это делает интра-проект требует работы так же требует внешних НПМ модули.
  • извините, пользователи Windows, вам нужно придерживаться относительных путей родительского каталога.
  • конфигурация

    обычно модули и классы кода ожидают только базовый JavaScript options объект принят в. Только app/server.js загрузите app/config.js модуль. Оттуда он может синтезировать small options объекты для настройки подсистем по мере необходимости, но соединение каждой подсистемы с большим глобальным модулем конфигурации, полным дополнительной информации, плохо связь.

    попробуйте централизовать создание соединений БД и передать их в подсистемы, в отличие от передачи параметров соединения и наличия подсистем, которые сами делают исходящие соединения.

    переменной NODE_ENV

    это еще одна заманчивая, но ужасная идея, перенесенная с рельсов. В вашем приложении должно быть ровно 1 место,app/config.js на NODE_ENV переменные среды. Все остальное должно принимать явный параметр как класс аргумент конструктора или параметр конфигурации модуля.

    если модуль электронной почты имеет опцию о том, как доставлять электронные письма (SMTP, войти в stdout, поставить в очередь и т. д.), Он должен принять такую опцию, как {deliver: 'stdout'} но это абсолютно не должно проверять NODE_ENV.

    тесты

    теперь я храню свои тестовые файлы в том же каталоге, что и их соответствующий код, и использую соглашения об именах расширений файлов, чтобы отличать тесты от производства код.

    • foo.js имеет код модуля "foo"
    • foo.tape.js имеет тесты на основе узлов для foo и живет в том же dir
    • foo.btape.js может использоваться для тестов, которые необходимо выполнить в среде браузера

    я использую глобусы файловой системы и find . -name '*.tape.js' команда, чтобы получить доступ ко всем моим тестам по мере необходимости.

    как организовать код внутри каждого .js модуль

    объем этого проекта в основном о том, куда идут файлы и каталоги, и я не хочу добавлять много другой области, но я просто упомяну, что я организовываю свой код в 3 отдельных раздела.

    1. Открытие блока CommonJS требует вызовов зависимостей состояния
    2. основной блок кода pure-JavaScript. Отсутствие загрязнения на CommonJS здесь. Не ссылайтесь на экспорт, модуль или require.
    3. закрытие блока CommonJS для настройки экспорта

    обновление (2013-10-29): пожалуйста, смотрите мой другой ответ, а также который имеет JavaScript вместо CoffeeScript по популярному требованию, а также шаблонный GitHub repo и обширный README с подробным описанием моих последних рекомендаций по этой теме.

    Config

    то, что вы делаете хорошо. Мне нравится иметь собственное пространство имен config, настроенное на верхнем уровне config.coffee файл с вложенным пространством имен, как это.

    #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}"
    

    это удобным для редактирования системного администратора. Затем, когда мне что-то нужно, например, информация о подключении к БД, это

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

    Маршруты/Контроллеры

    мне нравится оставлять свои маршруты с моими контроллерами и организовывать их в app/controllers поддиректории. Затем я могу загрузить их и позволить им добавить любые маршруты, которые им нужны.

    в своем app/server.coffee файл coffeescript я делаю:

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

    поэтому у меня есть такие файлы, как:

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

    и например в мой контроллер доменов, у меня есть setup функции как этот.

    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
    

    вид

    ввод просмотров в app/views становится привычным местом. Я изложил это так.

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

    Статические Файлы

    поехать в public поддиректории.

    Github / Semver / NPM

    положите README.файл MD markdown в корневом каталоге git repo для github.

    поставить пакет.файл json с семантический версия номер в корне репозитория git для NPM.


    ниже приведен ответ Питера Лайонса дословно, перенесенный на vanilla JS из Coffeescript, как просили несколько других. Ответ Питера очень способный, и любой, кто голосует за мой ответ, должен голосовать и за его.


    Config

    то, что вы делаете хорошо. Мне нравится иметь собственное пространство имен config, настроенное на верхнем уровне config.js файл с вложенным пространством имен, как это.

    // 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}"
    };
    

    это дружелюбно для sysadmin редактирование. Затем, когда мне что-то нужно, например, информация о подключении к БД, это

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

    Маршруты/Контроллеры

    мне нравится оставлять свои маршруты с моими контроллерами и организовывать их в app/controllers поддиректории. Затем я могу загрузить их и позволить им добавить любые маршруты, которые им нужны.

    в своем app/server.js JavaScript-файл я делаю:

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

    поэтому у меня есть такие файлы, как:

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

    и, например, в моем контроллере доменов, I есть setup функции как этот.

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

    вид

    ввод просмотров в app/views становится привычным местом. Я изложил это так.

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

    Статические Файлы

    поехать в public поддиректории.

    Github / Semver / NPM

    положите README.файл MD markdown в корневом каталоге git repo для github.

    поставить пакет.файл json с семантический версия номер в корне репозитория git для NPM.


    мой вопрос был внесен в апреле 2011 года, это тихий старый. За это время я мог бы улучшить свой опыт работы с Express.js и как создать архитектуру приложения, написанного с помощью этой библиотеки. Итак, я делюсь здесь своим опытом.

    вот моя структура каталогов:

    ├── 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

    цель app.js файл для загрузки приложения expressjs. Он загружает модуль конфигурации, модуль регистратора, ждет базу данных соединение. ,.., и запустите экспресс-сервер.

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

    маршруты/

    каталог маршрутов имеет . Его цель-ввести своего рода магию для загрузки всех других файлов внутри . Вот реализация:

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

    С помощью этого модуля создать новое определение маршрута и его реализацию очень просто. Например, hello.js:

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

    каждый модуль маршрута автономной.


    Мне нравится использовать глобальные "приложение", а не экспортировать функцию и т. д.


    Я думаю, что это отличный способ, чтобы сделать это. Не ограничиваясь выражением, но я видел довольно много узлов.проекты js на github делают то же самое. Они вынимают параметры конфигурации + меньшие модули (в некоторых случаях каждый URI) учитываются в отдельных файлах.

    Я бы рекомендовал пройти экспресс-проекты на github, чтобы получить идею. IMO то, как вы делаете, правильно.


    сейчас конец 2015 и после развивать мою структуру на 3 лет и в небольших и больших проектах. Вывод?

    Не делайте один большой MVC, но отделите его в модулях

    Так...

    почему?

    • обычно один работает на одном модуле (например, продукты), который вы можете изменить независимо.

    • вы можете использовать модули

    • вы можете проверить его отдельно

    • вы можете заменить его отдельно

    • Они имеют четкие (стабильные) интерфейсы

      -в крайнем случае, если было несколько разработчиков, работающих, разделение модулей помогает

    на nodebootstrap проект имеет аналогичный подход к моей окончательной структуре. (github)

    Как эта структура выглядит как?

    1. малые, capsulated модули, каждый с отдельным MVC

    2. каждый модуль есть пакет.в JSON

    3. тестирование как часть структуры (в каждом модуле)

    4. глобальная конфигурация, библиотеках и услуги

    5. Интегрированный Докер, Кластер, навсегда!--3-->

    Folderoverview (см. папку lib для модулей):

    nodebootstrap structure


    прошло довольно много времени с момента последнего ответа на этот вопрос, и Express также недавно выпустила версию 4, которая добавила несколько полезных вещей для организации структуры вашего приложения.

    Ниже приведен длинный обновленный блог о лучших практиках по структурированию вашего Экспресс-приложения. http://www.terlici.com/2014/08/25/best-practices-express-structure.html

    существует также репозиторий GitHub, применяющий рекомендации в статье. Это всегда дата с последней версией Express.
    https://github.com/terlici/base-express


    Я не думаю, что это хороший подход для добавления маршрутов в config. Лучшей структурой может быть что-то вроде этого:

    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...
    

    Так продукты.js и пользователи.js будет содержать все ваши маршруты, будет вся логика внутри.


    Ну, я поставил свои маршруты как файл json, который я читал в начале, и в for-loop в приложении.js установил маршруты. Маршрут.json включает в себя представление, которое должно быть вызвано, и ключ для значений, которые будут отправлены в маршрут.
    Это работает для многих простых случаев, но мне пришлось вручную создавать некоторые маршруты для особых случаев.


    Это может быть интересно:

    https://github.com/flatiron/nconf

    иерархический узел.конфигурация js с файлами, переменными среды, аргументами командной строки и слиянием атомарных объектов.


    Я написал сообщение именно об этом вопросе. Он в основном использует routeRegistrar, который перебирает файлы в папке /controllers вызова функции init. Функция init берет экспресс app переменной в качестве параметра, так что вы можете регистрировать свои маршруты так, как вы хотите.

    var fs = require("fs");
    var express = require("express");
    var app = express();
    
    var controllersFolderPath = __dirname + "/controllers/";
    fs.readdirSync(controllersFolderPath).forEach(function(controllerName){
        if(controllerName.indexOf("Controller.js") !== -1){
            var controller = require(controllersFolderPath + controllerName);
            controller.init(app);
        }
    });
    
    app.listen(3000);
    

    1) Ваша файловая система экспресс-проекта может быть, как:

    / ...
    /lib
    /node_modules
    /public
    /views
          app.js
          config.json
          package.json
    

    app.Яш - вы можете взломать контейнер

    2) основной файл модуля (lib/mymodule / index.в JS):

    var express = require('express');    
    var app = module.exports = express();
    // and load module dependencies ...  
    
    // this place to set module settings
    app.set('view engine', 'jade');
    app.set('views', __dirname + '/views');
    
    // then do module staff    
    app.get('/mymodule/route/',function(req,res){ res.send('module works!') });
    

    3) подключить модуль в главном приложении.js

    ...
    var mymodule = require('mymodule');
    app.use(mymodule);
    

    4) пример логики

    lib/login
    lib/db
    lib/config
    lib/users
    lib/verify
    lib/
       /api/ 
       ...
    lib/
       /admin/
          /users/
          /settings/
          /groups/
    ...
    
    • лучше всего для тестирования
    • лучше всего для масштаба
    • отдельный зависит от модуля
    • группировка маршрута по функциональности (или модули)

    tj говорит / показать на Vimeo интересная идея, как модульная экспресс-приложение - модульные веб-приложения с узлом.js и Express. Мощный и простой.


    http://locomotivejs.org/ обеспечивает возможность структурировать приложение построено с узлом.js и Экспресс.

    на сайте:

    "Локомотив-это веб-фреймворк для узла.js. Локомотив поддерживает MVC шаблоны, маршруты RESTful и соглашение по конфигурации, в то время как интеграции с любой базой данных и шаблонизатор. Локомотив строит на Express, сохраняя мощность и простоту вы привыкли ожидать от Узел."


    Я даю структуру папок стиля MVC, пожалуйста, найдите ниже .

    мы использовали структуру папок ниже для наших больших и средних веб-приложений .

     myapp   
    |
    |
    |____app
    |      |____controllers
    |      |    |____home.js
    |      |
    |      |____models
    |      |     |___home.js
    |      |
    |      |____views
    |           |___404.ejs
    |           |___error.ejs
    |           |___index.ejs
    |           |___login.ejs
    |           |___signup.ejs
    |   
    |
    |_____config
    |     |___auth.js
    |     |___constants.js
    |     |___database.js
    |     |___passport.js
    |     |___routes.js
    |
    |
    |____lib
    |    |___email.js
    |
    |____node_modules
    |
    |
    |____public.js
    |    |____css
    |    |    |__style.css
    |    |    
    |    |____js
    |    |    |__script.js
    |    |
    |    |____img
    |    |    |__img.jpg
    |    |
    |    |
    |    |____uploads
    |         |__img.jpg
    |      
    |   
    |
    |_____app.js
    |
    |
    |
    |_____package.json
    

    Я создал один модуль npm для создания структуры папок express MVC.

    пожалуйста, найдите ниже https://www.npmjs.com/package/express-mvc-generator

    просто простые шаги для создания и использования этих модулей .

    i) установить модуль npm install express-mvc-generator -g

    ii) проверьте параметры express -h

    iii) создание экспресс-структуры mvc express myapp

    iv) установить зависимости:npm install:

    v) откройте конфигурацию/базу данных.js, пожалуйста, настройте свой Mongo db.

    vi) запустите приложение node app или nodemon app

    vii) Проверьте URL http://localhost:8042/signup или http://yourip:8042/signup


    недавно я принял модули в качестве независимых мини-приложений.

    |-- src
      |--module1
      |--module2
         |--www
           |--img
           |--js
           |--css
         |--#.js
         |--index.ejs
      |--module3
      |--www
         |--bower_components
         |--img
         |--js
         |--css
      |--#.js
      |--header.ejs
      |--index.ejs
      |--footer.ejs
    

    Теперь для любой маршрутизации модуля (#.js), views (*.ejs), js, css и активы находятся рядом друг с другом. маршрутизация подмодулей настраивается в Родительском #.js с двумя дополнительными строками

    router.use('/module2', opt_middleware_check, require('./module2/#'));
    router.use(express.static(path.join(__dirname, 'www')));
    

    таким образом, даже subsubmodules возможны.

    не забудьте установить вид в каталог src

    app.set('views', path.join(__dirname, 'src'));
    

    так выглядит большая часть моей структуры каталогов express project.

    я обычно делаю express dirname чтобы инициализировать проект, простите мою лень, но он очень гибкий и расширяемый. PS-вам нужно получить express-generator для этого (для тех, кто ищет его sudo npm install -g express-generator, sudo, потому что вы устанавливаете его глобально)

    |-- bin
        |-- www //what we start with "forever"
    |-- bower_components
    |-- models
        |-- database.js
        |-- model1.js //not this exact name ofcourse.
        |-- .
    |-- node_modules
    |-- public
        |-- images
        |-- javascripts
            |-- controllers
            |-- directives
            |-- services
            |-- app.js
            |-- init.js //contains config and used for initializing everything, I work with angular a lot.
        |-- stylesheets
    |-- routes
        |-- some
        |-- hierarchy
        .
        .
    |-- views
        |-- partials
        |-- content
    |-- .env
    |-- .env.template
    |-- app.js
    |-- README.md
    

    вам должно быть интересно, почему .файлы env? Потому что они работают! Я использую dotenv модуль в моих проектах (много в последнее время) и это работает! Поп в эти 2 утверждения в app.js или www

    var dotenv = require('dotenv');
    dotenv.config({path: path.join(__dirname + "/.env")});
    

    и еще одна строка, чтобы быстро установить /bower_components для обслуживания статического контента в рамках ресурса /ext

    app.use('/ext', express.static(path.join(__dirname, 'bower_components')));
    

    это, вероятно, может быть подходит для людей, которые хотят использовать Express и Angular вместе, или просто выразить без этого javascripts иерархия, конечно.


    моя структура выражает 4. https://github.com/odirleiborgert/borgert-express-boilerplate

    пакетов

    View engine: twig
    Security: helmet
    Flash: express-flash
    Session: express-session
    Encrypt: bcryptjs
    Modules: express-load
    Database: MongoDB
        ORM: Mongoose
        Mongoose Paginate
        Mongoose Validator
    Logs: winston + winston-daily-rotate-file
    Nodemon
    CSS: stylus
    Eslint + Husky
    

    структура

    |-- app
        |-- controllers
        |-- helpers
        |-- middlewares
        |-- models
        |-- routes
        |-- services
    |-- bin
    |-- logs
    |-- node_modules
    |-- public
        |-- components
        |-- images
        |-- javascripts
        |-- stylesheets
    |-- views
    |-- .env
    |-- .env-example
    |-- app.js
    |-- README.md