Как организовать сборку, сервер, клиент и общий код JavaScript с помощью NodeJS

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

Код времени сборки

Временной код сборки для проектов, использующих Gulp, Grunt или vanilla NPM, в соответствии с базовой документацией, как правило, довольно прост. Большинство небольших проектов, как правило, хранят весь код в одном файле, и этот файл, как правило, называется обычным именем, например, gulpfile.js, однако в более крупных проектах я видел, как эти сценарии начинают разделяться. Я видел несколько случаев, когда файл gulp разбивается на несколько файлов и помещается в отдельный каталог. Хуже того, я обнаружил случаи, когда файл gulpfile.js даже не назывался как таковой, что заставляло новых разработчиков искать, где находится файл gulpfile, и как только он был обнаружен, команду gulp всегда нужно запускать с определенным < em> --gulpfile.

Выполняемый серверный код

Точка входа для основных приложений узла, по-видимому, просто требует указания определенного файла JavaScript при запуске команды узла (например, node script.js). Для приложений веб-сервера, таких как те, которые используют Express, я заметил, что по соглашению файл точки входа часто называется server.js и обычно находится в корневом каталоге приложения. Однако в некоторых других случаях, например при запуске веб-сервера в среде разработки, я видел, как задачи gulp берут на себя ответственность за запуск Node. В этих случаях кажется, что есть несколько способов включить точку входа, но один пример, который я нашел, — это просто запуск компилятора веб-пакета, за которым следует оператор require для сценария точки входа. Выяснение того, как включить обычное руководство по выполнению типичной команды отладки узла, нетривиально. в этом типе установки. Помимо точки входа в приложение, похоже, не существует каких-либо общих рекомендаций по структуре каталогов для приложений NodeJS/Express, которые хранили бы специфичный для сервера код на своем месте, чтобы помочь найти его и отделить от времени сборки и клиентский код.

История на стороне сервера становится еще более сложной в тех случаях, когда код на стороне сервера используется как для обслуживания статического контента, сгенерированных на стороне сервера представлений (например, с MVC), так и для предоставления API клиенту. боковая сторона. Я предпочитаю отделять API от проекта приложения, но другие считают, что при этом возникает ощущение чрезмерной сложности, когда я вижу в этом разумное разделение задач.

Выполняемый клиентский код

Поскольку код на стороне клиента часто может иметь различные точки входа в зависимости от первой запрошенной страницы, это может быть непросто. Однако из-за общей прозрачности URL-адресов в отношении того, как они сопоставляются с ресурсами в типичных случаях, а также из-за того, насколько мощными стали инструменты отладки в современных браузерах, следовать сценариям не составляет особых проблем. Вместо этого трудность для кода на стороне клиента возникает больше для типичных процессов сборки, которые обычно заканчиваются копированием файлов и помещением их в производственную структуру под другим именем. Примером может служить проект, в котором есть папка с именем src или js, содержащая перемешанный клиентский и серверный код, за исключением того, что только часть файлов быть включенным в задачу сборки, которая преобразует и часто объединяет файлы и помещает их в папку распространения. Известные мне распространенные имена этих папок распространения: dist, public, www и wwwroot. Часто, если не всегда, эти каталоги находятся в корне проекта, что, по крайней мере, упрощает их поиск без необходимости опрашивать сценарии сборки.

Я надеюсь, что есть какое-то общее руководство о том, как разумно собрать все это воедино, возможно, от авторитетного источника, главным образом, чтобы дать руководство тем, кто, как я, хочет начать с правильной ноги. В качестве побочного эффекта, возможно, возможность ссылаться на какой-то стандарт, даже если он нечеткий, также может уменьшить количество шаблонов, которые команда должна изобретать и обсуждать в начале работы. В каждом из перечисленных выше контекстов, очевидно, будут некоторые технологические соглашения, такие как те, которые применяются для AngularJS, Meteor или ReactJS на стороне клиента. Соглашения, которые я ищу, более специфичны для разделения основных контекстов высокого уровня в сквозных приложениях JavaScript, где язык и платформа больше не становятся очевидным способом различения между ними.


person jpierson    schedule 26.10.2015    source источник
comment
Возможно, далеко не авторитетный, я наткнулся на этот проект github, в котором обсуждаются возможные макеты для больших приложений NodeJS. gist.github.com/lancejpollard/1398757   -  person jpierson    schedule 26.10.2015


Ответы (1)


Код времени сборки

ИМХО, если у вас так много кода времени сборки, что он превышает, скажем, 1000 строк и требует более нескольких файлов, что-то пошло не так. Либо вы не знаете, как эффективно использовать существующие пакеты из npm, либо вы не понимаете, как рефакторить универсальный код и публиковать его как независимые пакеты npm. Если вы чувствуете, что вам нужно руководство по коду времени сборки проекта, потому что он такой большой и сложный, я предлагаю разделить его на модули и разделить на отдельные проекты, каждый из которых публикуется независимо в npm. Также просто проверьте свой общий подход. Что вы делаете, что так нестандартно и требует столько машин?

Боковой код сервера времени выполнения

См. мой другой ответ на ExpressJS Как структурировать приложение?

Как правило, я бы предпочел видеть код на стороне клиента и код на стороне сервера либо полностью отдельными пакетами npm (отдельные репозитории git, отдельные файлы package.json, публикуемые независимо) (если они достаточно велики), либо иным образом объединены в один и тот же модуль и сгруппированы путем связывания (весь код, относящийся к функции, хранится вместе, включая внешний и внутренний код), особенно если в вашей кодовой базе имеется значительный объем кода, который работает в обеих средах.

У меня есть полнофункциональное приложение node/JS с открытым исходным кодом под названием mjournal, в котором хранится код браузера и код узла. рядом друг с другом. Вы можете взглянуть и посмотреть, кажется ли вам это логичным и легко понять, где живет код. Это ни в коем случае не популярный подход, поэтому многим людям он не понравится, но лично мне он нравится, поскольку я принял «группировку по соединению» в качестве общего принципа.

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

Да, это ерунда. Ваше приложение должно начинаться с npm start или что-то вроде node server.js. Сложные настройки gulp/grunt, которые сбивают с толку новых разработчиков, — это ненужная сложность, от которой нужно просто избавиться.

История на стороне сервера становится еще более сложной в тех случаях, когда код на стороне сервера используется как для обслуживания статического контента,

По моему опыту, код для обслуживания статического контента сводится к 5 строкам или меньше, так что ничего страшного. Если у вас есть немикроскопический объем кода, связанный с обслуживанием статического контента, опять же, что-то пошло не по плану.

Код на стороне клиента во время выполнения

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

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

Но в целом поиск «стандарта» — это не то, как катится сообщество node.js/javascript/web. Небольшие пакеты npm. Макеты файлов, которые вынуждены быть очевидными из-за небольшого размера. Я чувствую ваше разочарование в связи с тем, что интерфейсные цепочки инструментов настолько сложны, но в конечном счете это происходит потому, что JavaScript в браузере потребовалось слишком много десятилетий, чтобы создать разумную модульную систему. В ближайшие несколько лет все может начать стандартизироваться, поскольку модули ES6 являются официальной спецификацией, но с таким большим количеством кода, уже написанного на CommonJS, и его ужасными предшественниками, такими как RequireJS/AMD, мы, вероятно, будем иметь дело с ними в обозримом будущем.

person Peter Lyons    schedule 26.10.2015
comment
По моему опыту, код для обслуживания статического контента сводится к 5 строкам или меньше. Удивительно, однако знать это важно. Для нового разработчика в Node может быть не очевидно, какой код за что отвечает. Я изменю свой вопрос, чтобы указать веб-контент, такие представления возвращаются с кодом стиля MVC, а не только со статическим контентом. Я лично стараюсь избегать представлений, созданных на стороне сервера, за исключением изоморфных подходов, но это не относится к делу. - person jpierson; 26.10.2015
comment
Вы используете слово модуль с точки зрения организации кода проекта. Я знаком с концепцией модулей как единицы повторного использования общедоступных пакетов из NPM и кратко рассмотрел концепцию частных общих модулей, но пока не нашел никакой информации об использовании модулей для улучшения организации NodeJS. веб приложение. Не могли бы вы уточнить? Это может быть недостающий совет, который я ищу. - person jpierson; 26.10.2015
comment
Когда я говорю разделить вещи на их собственные модули, я имею в виду дать им свой собственный репозиторий git, свой собственный файл package.json и опубликовать их в npm как отдельный модуль. Я вернусь и уточню терминологию, чтобы отличить модуль CommonJS от пакета npm. - person Peter Lyons; 26.10.2015