.NET Fest: полная программа конференции на сайте. Присоединяйся к самому большому .NET ивенту
×Закрыть

Node.js/Express/Socket.io от ProCode

занятие — 1

Дисклеймер
Этот текст вполне можно использовать как учебник, он ничем не хуже и не лучше большинства туториалов в интернете, по крайней мере это не копипаст с более древних статей. Однако, в первую очередь, это адаптировано для людей которые по каким-то причинам пропустили урок или хотят дополнительно структурировать информацию. На живом уроке вы можете задать вопрос, попросить посмотреть код или объяснить незнакомый момент. Тут для понимания скорее всего нужно уже обладать какими-то азами.

«Вы тут ...., когда все знают что ....». Нет, не все знают. Но обязательно напишите.

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

Беклог занятий
☑ 30.06.2018 — вступительное занятие, кратко обо всем.
☐ 07.07.2018 — ставим Express. Логи, конфиги.
☐ 14.07.2018 — донастраиваем http сервер, аглоритм инициализаций, база данных.
☐ 21.07.2018 — ....

Место проведения Олень и чай 10:00-14:00, занятия бесплатны, коворкингу 90 грв за помещение.

Репозиторий

Давайте начнем

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

Базовое приложение создаем используя генератор поставляемый отдельно от Express

— Ставим сам генератор:
— npm install express-generator -g
— Генерируем:
express —view=pug —css=sass myapp
— устанавливаем зависимости:
npm i

тут использован шаблонизатор pug, вы можете использовать любой другой. Это не имеет вообще никакого значения, так как фронт сервер делается отдельно, тут шаблонизатор используется только для генерации страниц ошибок, которые уже сверстаны в базовом приложении. Однако, если в вашем случае это не так и вы никогда не работали с шаблонизаторами, используйте ejs (ejs-locals), он наиболее близок к оригинальному HTML, потому он будет прост для новичка. Также мы используем scss, но устанавливается sass, так как scss одна из его разновидностей. Для включения scss вам надо найти настройки sass в app.js и сменить indentedSyntax: false на true

— Зайдем в bin/www app.js заменим var на const. В теории это не играет роли, но так как далее мы будем использовать ES6+, неплохо если код будет выдержан в едином стиле.
— помним, ES6 модули в node.js не используются. Да вы можете включить их поддержку используя разные флаги, однако эта апи обозначена как нестабильная, все может измениться, многие важные аспекты все еще не описаны, неизвестно как это будет работать при введении стабильной апи. Потому мы используем старый добрый require и приемы для работы с ним, пока не выйдет стальной и задокументированной апи по import\export.

Нельзя не вспомнить тут про babel, но надо понимать что ES6 модули отличаются от require не только синтаксически. require — синхронная конструкция, в то время как import предполагает варианты. С babel же вы получите тот же require, просто написав его по другому, вы не получите возможностей import. Потому незачем придумывать себе головную боль, до выхода стабильной апи.

Для начала установим cross-env

Большая часть серверов работает на linux, однако часть ваших разработчиков работает на windows, переменные окружения в этих ос записываются разным синтаксисом. Нам понадобиться модуль cross-env, который позволит писать один синтаксис для всех ос

— Ставим cross-env
npm install —save-dev cross-env
— заменим раздел scripts на
«start»: «cross-env NODE_ENV=production NODE_PATH=. ./bin/www»,
«dev»: «cross-env NODE_ENV=development NODE_PATH=. ./bin/www»

тут мы помимо классического NODE_ENV добавили также NODE_PATH=. , что позволит писать нам пути модулей от корня проекта. В ES6 это будет работать как-то по другому, но пока мы не знаем как именно, потому оставим этот прием.


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


Вспомним и про eslint. Многие спрашивают, «какой синтаксис мне использовать?», ответ — такой, какой принят в компании где вы работаете. Следовательно нет какого либо единого конфига eslint для всех компаний.

Теперь немного поработаем напильником.

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

— app.js переименовываем в httpServer.js
— В bin/www находим строку
var app = require(’../app’);
исправляем путь на ’httpServer.js’ и заменяем все упоминания app на expressServer.
Найдем строку
var server = http.createServer(expressServer);
Для лучшей семантичности переименуем server в nativeHttpServer, это понадобиться нам в будущем.
Заодно заменим var на const, по тойже причине что мы делали это в app.js


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

Теперь сделаем модуль конфигов.

Многие часто используют обычный .json файл либо переменные окружения для управления параметрами приложения, но лучше использовать специализированный модуль. Отдельный модуль позволяет свести конфиги полученные из разных источников в один интерфейс. Как основу мы используем nconf. Это не лучший и не худший вариант, не всегда он нужен, но практика показывает что в некоторых проектах это нужно, а такой модуль как вы понимаете кочует из проекта в проект.

— В корне проекта создаем папку config и файл index.js в нем. Почему-то часто оказывается что новички не знают об этом, поэтому отдельно замечу это один из вариантов создания модуля, подробнее конечно можно узнать прочитав про модули в офф. документации или любом туториале про модули Node.js.
— Копируем код модуля с репозитория.

Этот код находит все файлы в папке config, и собирает их в один большой массив конфига.
В нашей компании принято, что название файла соответствует его ключу в массиве конфига. То есть например файл app.js вернет массив конфигов которые лежат в ключе app, посмотрите код, он достаточно простой чтобы в нем разобраться.
Не используйте этот модуль для хранения каких-то динамических значений.

— Теперь когда есть модуль конфигурации, надо создать сами конфиги, в репозитории уже есть 4 конфига:
‣app — общие настройки приложения. Тут у нас есть ссылка на корень проекта, как показывает практика это очень удобно и ссылка на временную папку tmp (заодно и создаем ее) эта папка иногда нужна для временного хранения файлов в некоторых скриптах.
‣httpServer — настройки http сервера как и понятно с названия
‣i18n — многоязычность (понадобиться позже)
‣logger — логирование (понадобиться позже)
Используйте их.
— У нас уже есть модули www/bin и httpServer, потому встроим в них переменные с наших конфигов
‣в www/bin порт из httpServer:port
‣в httpServer директорию статики из httpServer:staticDir. Это нужно так как иногда статика лежит вовсе не в директории express. Помним scss тоже относиться к статике.

Посмотрите пример на репозитории как получать значения с модуля конфигурации, или прочитайте в документации к nconf, это достаточно просто.

Логированние.

По аналогии с config, мы создаем модуль logger. Логгер заменит в работе нам стандартный console.log. Суть логера в том что им можно легко управлять в отличии от обычного модуля console. К примеру на продакшене записывать сообщения консоли в файл. Помимо этого, логгер из нашего примера умеет модифицировать стандартную консоль так что она пишет файл и строку откуда ее вызвали(только для девелопмента, так как это достаточно тяжелая операция).


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

— ставим логгер с репы(или сам делаем, по причинам озвученным выше)
— открываем www/bin, после строк комментариев в начале файла пишем
require(‘logger’)
это необходимо для того чтобы логер подцепился к стандартной консоли
— В httpServer.js находим строку const log... и заменяем на
const log = require(’logger’).express;
Также меняем app.use(log(‘dev’)) на
app.use(log);

Продолжение будет

Это все что мы успели сделать с группой на 4-х часовом бесплатном ивенте 07.07.2018.
На ивенте 14.07.2018. по плану рассмотреть и довести до ума непосредственно http сервер и подключить базу данных

Всем приятного отдыха.

LinkedIn
Допустимые теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
Допустимые теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter

Я «ЗА» то чтобы поменять аватар с ковром))

Скоро уже 2020 год, а socket.io все еще живое...

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

Что же касательно библиотек в целом, тот же Socket.io начался как кроссбраузерное решение, но помимо этого содержал много инструментов. Учитывая популярность нативных сокетов, думаю тут есть неких недостаток учебных материалов и как следствие, сокеты используют на самом примитивном уровне, ведь согласитесь, очень вряд ли все эти люди будут делать велосипеды каждый раз, вместо использования готовых библиотек.

Как по мне, то socket.io и есть тот велосипед, который используют только потому, что по нему полно всяких туториалов а-ля хеллоу ворлд. А по сути он не предоставляет ничего, кроме оверхеда.
Неймспейсы реализуются в пару строк через обычные вебсокеты. Комнаты по большей части нужны для всяких чатиков, да и в любом случае их реализовать не проблема. А вот избавится от ненужного слоя абстракции и тормозов, которые он привносит — гораздо сложнее.
По итогу на выходе при таком подходе получаются манкикодеры без малейшего понимания как что-то работает под капотом.

Приходите на ивент =) благо он бесплатный, объясню для чего неймспесы и комнаты, чатики — это легендарная ошибка новичков в сокетах, приходящая от неудачного примера в екзамплах, достигшая поистине грандиозного размера, «это же просто пример» — так они сказали, реально же это используется для другого. И не помешало бы еще пару вещей схожих с комнатами добавить.

👍 не видел анонса, но дело хорошее

dou.ua/calendar/21900
Только место поменяли на Олень и Чай
www.facebook.com/...​ef=page_internal&mt_nav=1

У нас есть ещё около 7 мест в этой группе.
Анонсы бесплатных ивентов ProCode в телеграм канале
t.me/procode_events
И доу календаре

Подписаться на комментарии