ExpressJS Как структурировать приложение? - PullRequest
505 голосов
/ 25 апреля 2011

Я использую веб-инфраструктуру ExpressJS для NodeJS.

Люди, использующие ExpressJS, размещают свои среды (разработку, производство, тестирование ...), свои маршруты и т. Д. На app.js.Я думаю, что это не очень хороший способ, потому что когда у вас большое приложение, app.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);

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

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

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

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

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

Ответы [ 19 ]

289 голосов
/ 28 октября 2013

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

focusaurus / express_code_structure - это репозиторий с последним кодом для этого. Запросы на извлечение приветствуются.

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


Экспресс структура кода

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

Текущий, по крайней мере, экспресс v4.14 декабря 2016 года

Build Status

js-standard-style

Насколько велико ваше приложение?

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

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

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

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

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

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

  • MVC на стороне сервера в стиле Ruby on Rails
  • Стиль одностраничного приложения в стиле MongoDB / Express / Angular / Node (MEAN)
  • Базовый веб-сайт с некоторыми формами
  • Модели / Операции / Представления / Стиль событий а-ля MVC мертв, пора ПЕРЕМЕЩАТЬ на
  • и многие другие как текущие, так и исторические

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

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

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

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

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

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

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

  • Быть умственно управляемым
    • Мозг может иметь дело только с небольшим количеством связанных вещей и думать о них одновременно. Вот почему мы используем каталоги. Это помогает нам справляться со сложностью, сосредотачиваясь на небольших порциях.
  • Будьте подходящего размера
    • Не создавайте «Каталоги Mansion», где есть только один файл, один на три каталога вниз. Вы можете увидеть это в Ansible Best Practices , который вынуждает небольшие проекты создавать более 10 каталогов для хранения более 10 файлов, когда 1 каталог с 3 файлами будет гораздо более подходящим. Вы не едете на работу на автобусе (если вы не водитель автобуса, но даже если вы ездите на автобусе, AT не работает), поэтому не создавайте структуры файловой системы, которые не оправданы фактическими файлами внутри них. .
  • Будьте модульными, но прагматичными
    • В целом сообщество узлов предпочитает небольшие модули. Все, что может быть чисто отделено от вашего приложения целиком, должно быть извлечено в модуль для внутреннего использования или публично опубликовано на npm. Тем не менее, для приложений среднего размера, которые являются здесь областью, накладные расходы могут добавить утомление вашему рабочему процессу без соответствующей стоимости. Так что для того времени, когда у вас есть некоторый код, который выровнен, но не достаточен для оправдания совершенно отдельного модуля npm, просто считайте его « proto-module », ожидая, что когда он пересекает некоторый порог размера, это будет извлечено.
    • Некоторые люди, такие как @ hij1nx , даже включают каталог app/node_modules и имеют файлы package.json в каталогах proto-module , чтобы упростить этот переход и выступить в качестве напоминания.
  • Легко найти код
    • Учитывая возможность сборки или исправления ошибки, наша цель состоит в том, чтобы у разработчика не было проблем с поиском соответствующих исходных файлов.
    • Имена значимы и точны
    • код ошибки полностью удален, не оставлен в файле-сироте или просто закомментирован
  • Будьте удобны для поиска
    • весь исходный код первого лица находится в каталоге app, поэтому вы можете cd выполнить команду find / grep / xargs / ag / ack / etc и не отвлекаться на сторонние совпадения
  • Используйте простые и понятные названия
    • npm теперь требует имен пакетов в нижнем регистре. Я нахожу это в основном ужасным, но я должен следовать за стадом, поэтому имена файлов должны использовать kebab-case, хотя имя переменной для этого в JavaScript должно быть camelCase, потому что - является знаком минус в JavaScript.
    • имя переменной совпадает с базовым именем пути модуля, но с kebab-case преобразованным в camelCase
  • Группировка по соединению, а не по функции
    • Это серьезное отклонение от соглашения по Ruby on Rails app/views, app/controllers, app/models и т. Д.
    • Функции добавляются в полный стек, поэтому я хочу сосредоточиться на полном стеке файлов, которые имеют отношение к моей функции. Когда я добавляю поле телефонного номера в модель пользователя, мне не важен какой-либо контроллер, кроме пользовательского контроллера, и меня не волнует какая-либо модель, кроме пользовательской модели.
    • Таким образом, вместо того, чтобы редактировать 6 файлов, каждый из которых находится в своем собственном каталоге, и игнорировать тонны других файлов в этих каталогах, этот репозиторий организован таким образом, что все файлы, которые мне нужны для создания функции, располагаются в одном месте
    • По своей природе MVC, пользовательский вид связан с пользовательским контроллером, который связан с пользовательской моделью. Поэтому, когда я изменяю модель пользователя, эти 3 файла часто меняются вместе, но контроллер сделок или контроллер клиента разъединяются и, следовательно, не участвуют. То же самое относится и к проектам, отличным от MVC.
    • Разъединение в стиле MVC или MOVE с точки зрения того, какой код входит, какой модуль все еще поощряется, но распространение файлов MVC в одноуровневые каталоги просто раздражает.
    • Таким образом, каждый из моих файлов маршрутов имеет часть маршрутов, которыми он владеет. Файл в стиле rails routes.rb удобен, если вы хотите получить обзор всех маршрутов в приложении, но при создании объектов и исправлении ошибок вам важны только маршруты, относящиеся к изменяемой части.
  • Хранить тесты рядом с кодом
    • Это всего лишь пример «группирования по связям», но я хотел конкретно это назвать. Я написал много проектов, в которых тесты живут в параллельной файловой системе, называемой «тестами», и теперь, когда я начал размещать свои тесты в том же каталоге, что и соответствующий им код, я больше никогда не вернусь. Это более модульное решение, с которым гораздо проще работать в текстовых редакторах, и оно избавляет от большого количества бессмысленного пути "../../ ..". Если вы сомневаетесь, попробуйте несколько проектов и решите сами. Я не собираюсь делать ничего, кроме этого, чтобы убедить вас, что это лучше.
  • Уменьшить сквозное сцепление с событиями
    • Легко подумать: «Хорошо, всякий раз, когда создается новая сделка, я хочу отправить электронное письмо всем продавцам», а затем просто введите код для отправки этих электронных писем по маршруту, который создает сделки.
    • Однако это соединение в конечном итоге превратит ваше приложение в гигантский шарик грязи.
    • Вместо этого DealModel должен просто вызывать событие "create" и совершенно не знать, что еще система может сделать в ответ на это.
    • Когда вы кодируете таким образом, становится намного более возможным поместить весь код, связанный с пользователем, в app/users, потому что повсюду нет гнезда связанной бизнес-логики, нарушающего чистоту базы кода пользователя.
  • Поток кода отслеживается
    • Не делай волшебных вещей. Не загружайте файлы из магических каталогов в файловой системе. Не будь Rails. Приложение начинается с app/server.js:1, и вы можете увидеть все, что оно загружает и выполняет, следуя коду.
    • Не создавайте DSL для ваших маршрутов. Не делайте глупого метапрограммирования, когда оно не требуется.
    • Если ваше приложение настолько велико, что выполнение magicRESTRouter.route(somecontroller, {except: 'POST'}) - это большой выигрыш для вас за 3 основных app.get, app.put, app.del звонка, вы, вероятно, создаете монолитное приложение, которое слишком велико для эффективно работать на. Получите удовольствие от БОЛЬШИХ выигрышей, а не от преобразования 3 простых линий в 1 сложную.
  • Использовать имена файлов в нижнем регистре

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

      Экспресс.js Особенности

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

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

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

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

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

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

Конфигурация

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

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

NODE_ENV

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

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

Тесты

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

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

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

Как организовать код в каждом .js файле модуля

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

  1. Для открытия блока CommonJS требуются вызовы зависимостей состояний
  2. Основной блок кода из чистого JavaScript. Никакого загрязнения CommonJS здесь. Не ссылаться на экспорт, модуль или запрос.
  3. Закрытие блока CommonJS для настройки экспорта
155 голосов
/ 08 сентября 2011

ОБНОВЛЕНИЕ (2013-10-29) : Пожалуйста, ознакомьтесь с моим другим ответом, в котором есть популярный спрос на JavaScript вместо CoffeeScript, а также репозиторий Github и обширный README с подробным изложением моих последних рекомендаций по эта тема.

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 / НМП

Поместите файл уценки README.md в корень вашего git-репо для github.

Поместите файл package.json с семантической версией номер в корень вашего git-репо для NPM.

50 голосов
/ 04 октября 2013

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


Конфиг

То, что вы делаете, прекрасно.Мне нравится иметь свое собственное пространство имен конфигурации, настроенное в файле 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}"
};

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

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

И, например, в моем контроллере доменов у меня есть функция 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 в корень вашего git-репо для github.

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

42 голосов
/ 01 ноября 2013

Мой вопрос был задан в апреле 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();
});

маршруты /

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

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

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

18 голосов
/ 08 сентября 2011

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

17 голосов
/ 25 апреля 2011

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

Я бы порекомендовал пройти через специальные проекты на github. ИМО, как вы делаете это правильно.

14 голосов
/ 18 сентября 2015

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

Не делать один большой MVC, а разделить его на модули

Итак ...

Почему?

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

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

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

  • Выв состоянии заменить его отдельно

  • Они имеют понятные (стабильные) интерфейсы

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

Проект nodebootstrap аналогичен моей финальной структуре.( github )

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

  1. Маленькие капсулированные модули каждый с отдельным MVC

  2. Каждый модуль имеет пакет. json

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

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

  5. Встроенный докер, кластер, навсегда

Просмотр папки (см. папку lib для модулей):

nodebootstrap structure

7 голосов
/ 05 июля 2016

Я даю структуру папок в стиле 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 для генерации экспресс-структуры папок 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) Откройте ваш config / database.js, пожалуйста, настройте свою базу данных mongo.

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

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

7 голосов
/ 23 апреля 2012

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

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

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

7 голосов
/ 10 октября 2014

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...