Текст
                    САМОЕ ПОЛНОЕ РУКОВОДСТВО ДЛЯ ВЕБ-РАЗРАБОТЧИКОВ

\О1В1 .

в примерах от сообщества 51аск Оуег^о\/у

САМОЕ ПОЛНОЕ РУКОВОДСТВО ДЛЯ ВЕБ-РАЗРАБОТЧИКОВ \О1>1. V Москва 2025
УДК 004.43 БЕК 32.973.26-018.1 Н85 Последнюю версию этой книги на английском языке можно скачать с сайта: ЪПр$://г1рШопа1.сот/еЬоок/пос1е-]'5. Вы можете поделиться этим РОР-файлом со всеми, кому он может быть полезен. Книга «1_еагп1п§ б1ос/е.]5» составлена на основе документации 5шск Омегф/ош (1трз://агс1з1Уе.ог§/дегаН8/с1сситетааоп-дитр.7г), содержание которой написано мно- гими трудолюбивыми людьми из 5гаск Оиег/1ош. Текстовые материалы публикуются на условиях СгеаПме Соттопз ВУ-$А (Тщрзм/сгеайиесоттопя.ог^Нсепзез/Ьу-за/З.О/). Список авторов каждой главы приведен в разделе «Благодарности» в конце этой книги. Изображения могут являться объектами авторского права соответствующих владельцев, если не указано иное. Мос1е.]$. Самое полное руководство для веб-разработчиков в примерах Н85 от сообщества 51:аск ОуогЛоу/. — Москва : Издательство АСТ, 202.6. — 480 с.: ил. — (Быстрый старт в программирование). 15ВЫ 978-5-17-162197-1. Книга «МоЗе)5. Самое полное руководство для веб-разработчиков в приме- рах от сообщества 5(аск ОхегЛол» представляет собой продвинутое учебное пособие по работе на языке 1амаБсг1рС в кроссплатформенной среде выполнения Модель — чрезвычайно популярной и важнейшей в области веб-разработки. Вспо- могательный контент для программистов с любым опытом и уровнем знаний осно- ван на практических примерах кодов написанных экспертами широко известного в профессиональных кругах сообщест ва Зтаск ОхегЛои/, где лучшие ИТ-специалисгы со всего мира делятся своими наработками, отвечая на многие технические вопросы. Издание содеожит подробное объяснение важнейших концепций и приемов работы с Ыос1е.]5, дополненное примерами их практического применения, что даст возможност ь молодым разработчикам программного обеспечения быстро । ювыси гь уровень своих компетенций, а опытным — найти актуальные решения для сложных задач. В книге приведен мощный и современный инструментарий для создания серверов, АР1, разработки веб-приложений, работы с базами данных, исполазования УУеЬЗоске) Отдельные главы посвящены работе с менеджерами пакетов ЫРМ иУагп, эффективной обработке событий и повышению производительности. УДК 004.43 ББК32.973.26-018.1 18ВЫ 978-5-17-162197-1 Перевод на русский язык: ООО «Интеджер» Издание на русском языке: ООО «Издательстве АСТ»
Содержание Глава 1. Начало работы с Мойе.]8..................................25 Примечания......................................................25 Версии................................-.........................25 Примеры..................................................... 29 НТТР-сервер «Не11о Шог1й»....................................29 Пример «Не11о 5Л’ог1г]» в командной строке.................. 30 Установка и запуск Мойе.зз................................ 31 Запуск программы Кос!е.)8.......................................33 Развертывание вашего приложения в онлайн-среде...............33 Отладка вашего Поскф-приложения..............................34 Отладка нативно......................................... 34 «Не11о УУог!с1» с использованием Ехргезз.....................34 «Не11о \Уог1с1» с базовой маршрутизацией.....................36 ИЗ 8оске1: сервер и клиент.................................. 37 Как создать ключ и сертификат............................37 Важно1................................................. 38 ТЕ8 ЗоскеТ 8егуег........................................38 НеПо М/ог1с1 в КЕРЕ..........................................40 Соге-модули..................................................40 Все соге-модули: краткий обзор.......................... 41 Как запустить базовый НТТР8 веб-сервер?......................46 Шаг 1: создание центра сертификации......................46 Шаг 2: установка вашего сертификата в качестве корневого.... 47 Шаг 3: запуск вашего Кто<1е-сервера......................47 Глава 2. Взаимодействие Агйишо с Лойе.]8..........................49 Введение........................................................49 Примеры..................................................... 49 Связь Мо(1е.]8 с Агсййпо через ьепа1роП......................49 Код Мобе.]8........................................... 49 Код Агсййпо............................................ 50 Запуск................................................. 51
Глава 3. а8упс.]8.................................................52 Синтаксис.......................................... 52 Примеры.........................................................52 Параллельное выполнение: многозадачность.....................52 Вызов азупс.ратайеК) с объектом..........................53 Обработка нескольких значений............................54 Последовательное выполнение: независимый монотаскинг.........55 Вызов азупс.зепезО с объектом............................55 Водопад (ша1.егГай): зависимый монотаскинг...................56 азупс.йшез (для более удобной обработки циклов)..............57 аьупс.еасй (д-тя эффективной обработки массива данных).......57 азупс-зепез (для обработки событий по одному)................58 Вывод...........................................................59 Глава 4. Азупс/АмаП_________________________________________ 60 Введение ... .... . ..... .................................... 60 Примеры...................................................... 60 Асинхронные функции с обработкой ошибок через (ту сатсй......60 Сравнение Ртопйзез и Азупс/Ам/ай.............................61 Переход от обратных вызовов..................................62 Остановка выполнения на амгай................................63 Глава 5. Асинхронное программирование.......................... 64 Введение.................................................. 64 Синтаксис.......................................................64 Примеры.........................................................64 Функции обратного вызова в ]аса.8спр(........................64 Синхронные функции обратного вызова......................64 Асинхронные функции обратною вызова..................... 66 Функции обратного вызова (саПЬаскз) в Иоскф..................67 Пример кода_____________________________________ 68 Вывод....................................................68 Обработка ошибок в асинхронном коде......................69 Обработчики событий............................................ 69 Домены......................................................... 69 СаИЬаск Ней............................................... 70 Как избежать сайЬаск Ней................................... 71 Нативные Ргоппяе (Промисы)...................................71 Глава 6. Автоматическая перезагрузка при изменениях.................................................. 73 Примеры.........................................................73 Автоперезагрузка при изменении исходного кода с использованием пойетоп.....................................73
Установка пойепюп глобально..............................73 Установка побетоп локально............................ 73 Использование побетоп....................................73 Вгом/зегзупс............................... ..... 74 Обзор....................................................74 Установка................................................74 Пользователи Шшйоигз...........................................75 Основное использование.................................. 75 Продвинутое использование............................... 75 (;гип1.]8................................................75 Си1р.]з................................................. 75 ЛИ..........................................................76 Глава 7. Избегайте ада обратных вызовов (саПЬаск Ье11)...........77 Примеры....................................................... 77 Модуль Азупс............................................ 77 Еще о модуле Азупс..........................................78 Пример использования Азупс \уа(егГа11...................... 78 Глава 8. В1иеЫгб Ргоппзез (промисы)........................... 79 Примеры................................................... 79 Преобразование библиотеки побеЬаск в Ргоппзез...............79 Функциональные Ргоппзез................................... 79 Корутины (согоиппез)....................................... 80 Автоматическое освобождение ресурсов (Ргоппзе.изт#).........80 Последовательное выполнение....................... 80 Глава 9. Преобразование функций обратного вызова в Ргоппзез (промисах)........................................ 81 Примеры........................................................81 Промисификация функций обратного вызова.....................81 Ручная промисификация функции обратного вызова..............82 Промисификация зеГТйпеоиГ...................................83 Глава 10. Интеграция с Саззапбга.................................84 Примеры........................................................84 НеИо и,'ог1(1...............................................84 Глава 11. Интерфейс командной строки (СЫ)........................86 Синтаксис......................................................86 Примеры.................................................. 86 Опции командной строки......................................86 Глава 12. Взаимодействие «клиент — сервера.......................91 Примеры........................................................91 Использование с Ехргезз, )(Щегу апб ]абе....................91
Глава 13. Модуль С1ик1ег..................................... 94 Синтаксис............................................. 94 Примечания.................................................. 94 Примеры................................................... 95 Не11оШог1й.... .. .. ................................. 95 Пример кластера......................................... 96 Глава 14. Подключение к Моп^оВВ ............. . .... 97 Введение.................................................... 97 Сишаксис.....................................................97 Примеры......................................................97 Простой пример подключения к Моп^оПВ из Мойе.]5...........97 Простой способ подключения к МопдоВВ с использованием чистого Мойе.]5..........................98 Глава 15. Создание библиотеки Гчойе.]8, поддерживающей как Ргопизез, так и функции обратного вызова с первым аргументом ошибкой.............................. 99 Введение.................................................... 99 Примеры............................................... 99 Пример модуля и соответствующей программы с использованием В1пеЫгй..................................99 Глава 16. Создание АР1 с помощью Мос1е.]8................... 102 Примеры.....................................................102 СЕТ АР1 с использованием Ехргеяз........................ 102 РОЯТ ЛР1 с использованием Ехргезз........................102 Глава 17. Парсер С5У в Мойе.]8................................ 104 Введение....................................................104 Примеры.....................................................104 Использование Г.8 для чтения С8У.........................104 Глава 18. Работа с базой данных (Моп§о1)В с Мощщозе)..........105 Примеры.....................................................105 Подключение Мопдоозе.................................. 105 Модель...................................................105 Вставка данных...........................................106 Чтение данных........................................... 106 Глава 19. Отладка Мойе ^-приложения.... ................ ...108 Встроенный отладчик Мойе.]’з и пойе шзресЮг..............................................108 Использование встроенного отладчика..................... 108 Команды отладки.......................................108 Использование встроенного инспектора Мойе................110
Глава 20. Доставка НТМЬ или других типов файлов.................111 Синтаксис.................................................... 111 Примеры................................................. 111 Доставка ПТМГ по указанному пути......................... 111 Структура папок.........................................111 зегтег.)?...............................................111 Глава 21. Внедрение зависимостей......................... .....ИЗ Почему следует использовать внедрение зависимостей.........113 Глава 22. Развертывание приложения Мобе.]8 без простоя. .... ...114 Примеры.................................................... 114 Развертывание с использованием РМ2 без простоя.............114 Глава 23. Развертывание приложений 1Чойе.)8 в продакшене........116 Примеры.......................................................116 Установка ПОПЕ _ЕМУ="ргос1исйоп"...........................116 Флаги выполнения........................................116 Зависимости......................................... 116 Менеджер процессов РМ2.....................................118 Развертывание с использованием РМ2.........................118 Полезные команды при работе с РМ2.......................119 Гогетег................................................... 119 Использование разных свойств, конфигураций для разных окружений, таких как Деу, да, 8(.а$рп§ и т. д...120 Использование преимуществ кластеров........................121 Глава 24. ЕСМЛбспрг 2015 (Е86) с Мойе.]8...................... 123 Примеры...................................................... 123 Объявления соп8(71е(.............................. 123 Стрелочные функции.........................................123 Пример стрелочной функции..................................124 Десгруктуризация...........................................124 Пота-......................................................125 Класс Е86.............................................. 125 Глава 25. Окружение .......................................... 127 Примеры...................................................... 127 Доступ к переменным окружения.......................... ...127 Аргументы командной строки ргосе88.аг§у................. 127 Использование различных свойств/конфигураций для разных окружений, таких как Дес, да, 81а{рп§ и т. д....128 Глава 26. Источники событий.....................................131 Примечания............................................... 131 Примеры.................................................. 132
Аналитика НТТР через источник событий .....................132 Основы............................................... 133 Получение имен событий, на которые подписаны..............134 Получение количества слушателей, заретистрированньгх для определенного события............ 134 Глава 27. Еуеп! 1оор (цикл событий)............................136 Введение.....................................................136 Примеры.................................................... 136 Еуепт 1оор на псевдокоде................................ 136 Пример ОДНО1ЮТОЧНОГО НТТР-сервера без еуеп! 1оор..........136 Пример многопоточного НТТР-сервера без еуепТ 1оор.........137 Пример НТТР-сервера с еуспг 1оор..........................137 Глава 28. Обработка исключений............................. 139 Примеры......................................................139 Обработка исключений в Мос1е.]8......................... 139 Управление необработанными исключениями...................141 Тихая обработка исключений.............................141 Возврат к начальному состоянию . ................... 142 Ошибки и Ргоппзез (промпсы)...............................143 Глава 29. Выполнение файлов или команд с помощью дочерних процессов...................................144 Синтаксис....................................................144 Замечания....................................................144 Примеры.............................................. 144 Создание нового процесса для выполнения команды...........144 Создание оболочки для выполнения команды................. 145 Создание процесса для запуска исполняемого файла..........146 Глава 30. Экспорт и использование модулей .......... .... ... 148 Примечания................................................. 148 Примеры............................................. 148 Загрузка и использование модуля......................... 148 Создание модуля ИеПо-хмогШдз..............................149 Признание недействительным кеша модуля................... 151 Создание собственных модулей............................. 151 Каждый модуль затружается только один раз................ 152 Загрузка модуля из пойедтюсШез............................153 Папка (директория) как модуль.......................... 153 Глава 31. Экспорт и импорт модулей в Ыойедв....................155 Примеры......................................................155 Использование простого модуля в Ыо<1е.]’8.................155
Использование Ттропх в Е56...............................156 Экспорт с использованием синтаксиса Е86..................157 Глава 32. Загрузка файлов.................................... 158 Примеры.....................................................158 Загрузка одного файла с использованием птийег............158 Как фильтровать за!рузку по расширению...................159 Использование модуля ГогппйаЫе...........................160 Глава 33. Файловый ввод/вывод (Н1е$у$1ет 1/0).................162 Примечания..................................................162 Примеры................................................. 162 Запись в файл с использованием мтйеЕйе или отйеГйебупс..........................................162 Асинхронное чтение из файлов............................ 163 С использованием кодировки............................163 Без использования кодировки...........................164 Относительные пути.....................................164 Список содержимого каталога с использованием геаскйг или геайсйгбупс.................164 Использование генератора...............................165 Синхронное чтение из файла............................. 165 Чтение строки........................................ 165 Удаление файла с использованием ипкпк или ипйпкбупс......166 Чтение файла в Впйег с использованием потоков............166 Проверка прав доступа к файлу или директории.............167 Асинхронно......................................... 167 Синхронно............................................ 168 Избегание состояния гонки (гасе сопсййоп) при создании или использовании существующего каталога.................168 Проверка, существует ли файл или директория..............169 Асинхронно.............................................169 Синхронно........................................... 169 Клонирование файла с использованием потоков..............170 Копирование файлов с использованием соединения потоков....170 Изменение содержимого текстового файла...................171 Определение количества строк в текстовом файле...........171 Чтение файла построчно.................................. 172 Глава 34. Начало работы с профилированием Хос1е.)8............173 Введение................................................ 173 Замечания...................................................173 Примеры................................................. 173 Профилирование простого приложения на Мойе.]5............173
Глава 35. Хороший стиль кодирования....................... 176 Примечания................................................ 176 Примеры......................................................176 Базовая программа .для регисграции....................... 176 Глава 36. Корректное завершение................................181 Примеры......................................................181 Корректное завершение — 81СГЕКМ...........................181 Глава 37. Сгип!............................... . ... .. .... 182 Примечания...................................................182 Примеры......................................................183 Введение в СгипС]8....................................... 183 Установка плагинов (Згиш..................................184 Глава 38. Совет по упрощению работы....................... 186 Добавление новых расширении в гедшгеО.....................186 Глава 39 Обработка РОЗТзапросов в Мойе,)®.................. 188 Замечания....................................................188 Примеры..................................................... 189 Глава 40. Как затружаются модули.......................... 190 Примеры..................................................... 190 Режим глобальной установки................................190 Загрузка модулей..........................................190 Загрузка модуля из панки (директории)..................191 Глава 41. НГГР.................................................192 Примеры......................................................192 НТТР-сервер...............................................192 ШТР-клиент................................................193 Глава 42. Установка Мойе)®.....................................195 Примеры......................................................195 Установка Хойе.]’® на ПЬшйи.............................. 195 Использование пакетною менеджера арс...................195 Использование последней или конкретной версии (например 1.Т8 6.x) непосредственно из пойе®овгсе......195 Установка Мойе.]® на Мтйом'®..............................196 Использование Мтойе Уегаоп Мапа^ег (пулт).................196 Установка Мойе.]’® из исходных кодов с помощью пакетного менеджера АРТ........................ 198 Установка Мойе.]® на Мас с помощью пакетного менеджера.............................199 НотеЬгегу..............................................199 Масрогт®...............................................199
Установка с помощью МасО8 X ПыаПег..........................200 Проверка установки Хойе.................................200 Установка Хойе.]8 на КазрЬеггу Р1...........................201 Установка с помощью Мойе Уегзюп Мапа^ег в 118118йе11 с О1г Му Г18Й.201 Установка Цойе.]8 из исходников на Сеп1О8, КНЕЬ и Е'ейога...202 Установка Ыойе.]8 с помощью п............................ 203 Глава 43. Взаимодействие с консолью........................... 205 Синтаксис..................................................... 205 Примеры.... ........................................... 205 Локирование... . .................................... 205 Модуль Соп8о1е..........................................205 соП8о1е.1о$....................................................205 соп8о1е.еггог..................................................205 соп8о1е.йте, соп8о1е.(шгеЕпй...................................206 Модуль Ргосезз....................................... 206 Форматирование....................................... 206 Общее..........................................................207 Цвет шрифта....................................................207 Цвет фона____________________________________________ 207 Глава 44. Постоянное выполнение Мойе.)8-приложения...............208 Примеры..................................................... 208 Использование РМ2 в качестве менеджера процессов............208 Запуск и остановка йаетол Гогемег.......................209 Непрерывная работа с помощью пойир..........................209 Управление процессами с помощью Еогсуег.....................210 Глава 45. Фреймворк Коа у2.......................................211 Примеры........................................................211 Пример НеПо УУог1й..........................................211 Обработка ошибок с использованием т1йй1емтаге (промежуточного ПО).............................211 Глава 46. Еойаяй....................................... ..212 Введение............................................... 212. Примеры.................................................... 212 Фильтрация коллекции...................................... 212 Глава 47. ЬоорЬаск — ЯЕЗТ-соединитель............................213 Введение.......................................................213 Примеры.................................................. 213 Добавление веб-соединителя..................................213 Глава 48. теШзтйЪ...................................... 215 Примеры........................................................215 Создание простого блога.....................................215
Глава 49. Интеграция с Моп§оОВ........................................ 217 Синтаксис......................................................... 217 Параметры...........................................................217 Примеры............................................................ 218 Подключение к Моп^оВВ ... ..................................... 218 Метод СоппесЦ) для Моп^оСИегР.....................................219 Добавление документа..............................................219 Метод коллекции шзеПОпеО..........................................219 Чтение коллекции..................................................220 Метод коллекции Гтпс1()...........................................220 Обновление документа..............................................221 Метод коллекции ирсИпеОпеО........................................221 Удаление документа.......................................... 222 Метод коллекции <1е1еге()пе().....................................222 Удаление нескольких документов ................................. 222 Метод коллекции <1е1е(еМапу0......................................223 Простое подключение...............................................223 Простое подключение с использованием промисов.....................224 Глава 50. Интеграция МопноПВ для \ос!е.]8'Ехрге88.]8...................225 Введение.......................................................... 225 Примечания..................................................... 225 Примеры.............................................................225 Установка Моп§оОВ.............................................. 225 Создание модели Моп§оозе..........................................226 Запрос к вашей базе данных Моп§о..................................227 Глава 51. Библиотека Моп§оозе......................................... 228 Примеры........................................................... 228 Подключение к МоперПВ с использованием Мспдоове...................228 Сохранение данных в МопроПВ с использованием Мопцоозе и маршрутов Гхрге88.)5..................229 Настройка................................................... 229 Код...........................................................229 Использование.................................................230 Поиск данных в Моп§оГ)В с использованием Моп^оозе и маршрутов Ехрге85.)5..................231 Настройка.....................................................231 Код...........................................................231 Использование.................................................232 Поиск данных в Моп^оОВ с использованием Моп^оозе. маршрутов Гхргез8.]5 и оператора 2(ех(.233 Настройка................................................... 233 Код...........................................................233 Использование.................................................235
Индексы в моделях....................................... 236 Полезные функции Моп^оозе................................238 Поиск данных в Моп^оИВ с использованием промисов.........238 Настройка....................................... 238 Код...................................................239 Использование.................................... 240 Глава 52. Интеграция М88фЕ................................ 242 Введение.............................................. 242 Примечания..................................................242 Примеры............................................ 243 Подключение к 5рЬ через модуль прш тззд!............... 243 Глава 53. Многопоточность................................... 246 Введение....................................................246 Замечания __________________________________________ 246 Примеры................................................ 246 С1Шег....................................................246 СЫ1<1 Ргосезз........................................... 247 Глава 54. Пул соединений Му8р1 ......................... 249 Примеры.................................................... 249 Использование пула соединений без указания базы данных...249 Глава 55. Интеграция Му8(Д....................................251 Введение................................................... 251 Примеры.....................................................251 Запрос объекта подключения с параметрами.................251 Использование пула соединений............................252 Выполнение нескольких запросов одновременно...........252 Подключение к Му5(Д......................................252 Запрос объекта соединения без параметров................ 253 Выполнение нескольких запросов с одним соединением из пула.253 Возврат запроса при возникновении ошибки.................254 Экспорт пула соединений................................. 255 Глава 56. МАРТ............................................. 256 Введение.................................................. 256 Примеры............................................... 256 Приветствие в Ы-АР1.................................... 256 Глава 57, Локатизация Хойе.]8 ................................259 Введение................................................ 259 Примеры.................................................. 259 Использование модуля П8п для поддержания локализации в приложении на йойе.)8..................... 259
Глава 38. Сервер Мойе без фреймворка......................... 261 Примечания.......................................... ....... 261 Примеры......................................................261 Сервер на Мойе без фреймворка.............................261 Решение проблем с СОК8... ... 262 Глава 59. Мойе.]8 (ехрге88.|8) с Ап§и1аг.]8....................264 Введение ................................................ 264 Примеры......................................................264 Создание проекта..........................................264 Как создать каркас проекта на ехргезз?....................264 Как работает Ехрге.зз?....................................265 Установка Ри§ и обновление шаблонизагора Ехртезз..........266 Как Апди1аг}8 вписывается во все это?.....................266 Глава 60. Мойе^'з и МопдоИВ.............................. 269 Примечания................................................. 269 Примеры......................................................269 Подключение к базе данных.................................269 Установка Моп^оозе........................................269 Создание новой коллекции..................................270 Вставка документов..................................... 271 Чтение................................................... 271 Обновление.............................................272 ПрйаГеО................................................273 Ирйа(еОпе..............................................273 Прйа1еМапу.............................................273 Кер1асеОпе........................................... 274 Удаление................................................ 274 Глава 61. Архитектура и внутренняя работа Мойе.]8............ 275 Примеры..................................................... 275 Мойе.]8 — «под капотом»...................................275 Мобе.]5 — «в движении»....................................275 Глава 62. Код Ыойедз для 8ТШМТ и 8ТООЦТ без использования библиотек ...276 Введение.....................................................276 Примеры..................................................... 276 Программа.......................................... 276 Глава 63. Основы проектирования Мойе )8.................... 277 Примеры..................................................... 277 Малое ядро, малые модули..................................277 Шаблон КеасЮг.... . ............................... 277 Неблокирующий движок ввода-вывода Хойе.)8 — йЬну..........277
Глава 64. Управление ошибками в ЯоДедз...................... ..278 Введение.... ............................................. 278 Примеры .....................................................278 Создание объекта ошибки (Еггог)................. 278 Выброс ошибки.............................................279 Блок сгу...сакИ...........................................279 Глава 65. Производительность Ыойедз.................... ....281 Примеры......................................................281 Цикл событий............................................ 281 Пример блокирующей операции............................281 Пример неблокирующей операции ввода-вывода (10-Ьоипй)..281 Рекомендации по производительности.....................282 Увеличение тахБоскеш..................................... 283 Основы.................................................283 Установка собственного агента..........................283 Полное отключение пула сокетов.........................283 Подводные камни........................................ 283 Включение #21р........................................ 283 Глава 66. Новые функции и улучшения т^ойе.]8 тб................285 Введение.................................................... 285 Примеры......................................................285 Параметры по умолчанию для функций....................... 285 Остаточные параметры ____________________________ 285 Оператор расширения (Бргеай ОрегаГог).....................286 Стрелочные функции (Лггои/ ЕипсПопз)......................286 Йиз в стрелочных функциях.................................286 Глава 67. Мойедз с СОК8..................................... 289 Примеры......................................................289 Включение СОК8 в ехрге88.)8............................. 289 Глава 68, Мойедз с Е86.................................... 291 Введение................................................ 291 Примеры............................................. 291 Поддержка Е56 в \ос1е.]8 и создание проекта с ВаЬе!.......291 Использование Е86 в вашем Ыо<1е.]8-приложении ........ 293 Предварительные условия................................293 Глава 69. Использование Ыойе.)8 с Огас1е.......................297 Примеры......................................................297 Подключение к Огас1е ОВ...................................297 Выполнение запроса на объекте соединения без параметров...298 Использование локального модуля для упрощения запросов....299
Глава 70. Руководство для начинающих по Кос1е.)8................. 301 Примеры....................................................... 301 Не11о УУогШ! .................................................301 Глава 71- Фреймворки Мойефз........................................302 Примеры....................................................... 302 Фреймворки для веб-серверов...................................302 Ехргеяз............................................... 302 Коа.......................................................302 Фреймворки для интерфейса командной строки....................303 Со1втапбег.)8........................................... 303 Уогра1.]5............................................... 303 Глава 72. История ГЧойе.]8................................... ... ЗОЛ Введение........................................................304 Ключевые события по годам.....................................304 2009..........................................................304 2010..........................................................304 2011..........................................................304 2012..........................................................305 2013..........................................................305 2014..........................................................305 2015..........................................................306 (^1.......................................................306 р2........................................................306 (?3.......................................................306 (?4.......................................................306 2016..........................................................307 р1........................................................307 (?2.......................................................307 (}3.......................................................307 (}4.......................................................307 Глава 73. Маршрутизация в Койе.]8................................. 308 Введение........................................................308 Примечания......................................................308 Примеры.........................................................308 Маршрутизация веб-сервера Ехргезз.............................308 Глава 74. Мос1е.]5 с Весйз.........................................312 Замечания................................................... 312 Примеры.........................................................312 Начало работы.................................................312 Сохранение пар «ключ-значение»............................... 313 Некоторые дополнительные операции, поддерживаемые побе_ге(Й8.... 316
Глава 75. Мойе Раскате Мападег (прт)............................318 Введение................................................... 318 Синтаксис................................................... 318 Параметры.................................................... 319 Примеры.......................................................320 Установка пакетов ........................................ 320 Введение.............................................. 320 Установка МТРМ..........................................320 Как установить пакеты...................................321 Установка зависимостей..................................323 №М за прокси-сервером................................. 324 Скоупы и репозитории.......................................325 Удаление пакетов...........................................325 Основы семантического версионирования......................326 Настройка конфигурации пакетов.............................327 Публикация пакета..........................................328 Запуск скриптов........................................... 329 Удаление лишних пакетов....................................330 Список установленных пакетов...............................330 Обновление прт и пакетов.................................. 331 Закрепление модулей на конкретных версиях..................331 Настройка для глобально установленных пакетов..............332 Связывание проектов для более быстрой отладки и разработки............................................. 333 Код помощи............................................ 333 Шаги для связывания зависимостей проекта............... 333 Шаги для связывания глобального инструмента.............333 Проблемы, которые могут возникнуть......................333 Глава 76. Мойе Уегяюп Мапа^ег (пуш)........................... 335 1 [римечания..................................................335 Примеры.......................................................335 Уст ановка М'УМ............................................335 Проверка версии МУМ........................................ЗЗС Установка конкретной версии Мойе ......................... 336 Использование уже установленной версии пойе................336 Установка пут на Мас О8Х....................... ЗЗС Процесс установки..................................... 336 Проверка корректности установки МУМ.....................337 Установка псевдонима для версии пойе..................... 337 Запуск любой произвольной команды в подсистеме с нужной версией пойе......................................338
Глава 77. ОАШЪ 2.0..............................................339 Примеры.................................................... 339 ОАпНг 2 с реализацией Кесйз — згагй.Суре: раззм'огб........339 Глава 78. раскате.}зоп ................................. 347 Замечания.....................................................347 Примеры.............................................. .....347 Основное описание проекта................................. 347 Зависимости............................................... 348 йеуВерепйепаез..........................................348 Скрипты................................................... 349 Предопределенные скрипты................................349 Пользовательские скрипты............................... 349 Расширенное определение проекта............................350 Изучение файла раскадефзоп.............................. 351 Глава 79. Разбор аргументов командной строки....................355 Примеры.......................................................355 Передача действия (глагола) и значений.....................355 Передача булевых переключателей............................355 Глава 80. Интеграция Раззроп................................. 356 Примечания................................................... 356 Примеры...................................................... 356 Начало работы......................................... 356 Локальная аутентификация................................. 357 Аутентификация через ГасеЬоок ............................ 359 Простая аутентификация по имени пользователя и паролю......360 Аутентификация через Соо^1е с использованием РаззрогГ......361 Глава 81. раззрогГ.]з...........................................364 Введение......................................................364 Примеры.......................................................364 Приме р 1. о са!51 гаседу в раззроп. )з....................364 Глава 82. Проблемы производите, гьности.........................366 Примеры.......................................................366 Обработка длительных запросов в Мойе.]з....................366 Глава 83. Интеграция с Розц>ге8р(...............................371 Примеры.......................................................371 Подключение к Розц>ге8(Д.................................. 371 Запрос с использованием объекта подключения................371 Глава 84. Структура проекта.....................................372 Введение................................................... 372 Примечания............................................ 372
Примеры........................................................ 372 Простое Хойе.]5-приложение с использованием МУС и ЛР1.........372 Глава 85. Ризй-уведомления ................................. 375 Введение..._____________________________________________ 375 Параметры..................................................... 375 Примеры.................................................. 376 Веб-уведомление.............................................. 376 Лрр1е........................................................ 377 Глава 86. КеасШпе..................................................378 Синтаксис.......................................................378 Примеры.........................................................378 Построчное чтение файла.......................................378 Запрос ввода от пользователя через СЫ.................379 Глава 87. Удаленная отладка в Х'ойедз........................ ..380 Примеры.........................................................380 Конфигурация запуска Нобе.)8................................ 380 Конфигурация 1п(еШ|ЛУеЬ$(опп................................ 380 Использование прокси для отладки через порт в Ыпих..................................... 381 Глава 88. АедшгеО............................................................382 Введение........................................... 382 Синтаксис..................................................... 382 Примечания..................................................... 382 Примеры.................................................. 382 Начало использования гедшгеО с функцией и файлом.............382. Начало использования гедшгеО с №М-пакетом.....................384 Глава 89. КЕ8ТТи1 АР1: лучшие практики.............................385 Примеры.........................................................385 Обработка ошибок: СЕТ всех ресурсов......................... 385 Глава 90. Структура ВоиГе-СогИгоПег-Зеплсе для Ехргезздя................................................ 387 Примеры....................................................... 387 Структура директорий Мобек Коо1е5-Соптго1]ег5-5еп,тсе8............................ 387 Пример структуры кода МобеГКоиГез-СотйгоПегз-Зепчсез..........388 О8ег.тобе1.]8....................................... 388 и8ег.гоиТС8.]8.......................................... 388 и8ег.соп1го11ег8.]8.......................................388 и8ег.8епчсс8.]8.......................................... 388
Глава 91. Маршрутизация а)ах-запросов с помощью Ехрге88.]8....................................... .....390 Пример] >1.................................................... 390 Простая реализация А]АХ......................................390 Глава 92. Запуск Ыойедз как сервиса. ......................... 392 Введение .................................................... 392 Примеры........................................................392 1\о(1е.]8 как йаетоп зузгетс!................................392 Глава 93. Обеспечение безопасности приложений ?Чос1е.]8...........394 Примеры....................................................... 394 Предотвращение межсайтовой подделки запроса (С8КГ)...........394 881ЛТ8 в Мос1е.]8......................................... 395 Использование НТТР8........................................ 396 Настройка НТТГ8-сервера................................... 397 Шаг 1. Создайте центр сертификации.......................397 Шаг 2. Установите свой сертификат в качестве корневого.....................................398 Глава 94. Отправка веб-уведомлений............................... 399 Примеры.................................................... 399 Отправка веб-уведомления с использованием ССМ (Соо§1е С1оис1 Мезза^ш^ 8уз1ет)...... ............ 399 Глава 95. Отправка файлового потока клиенту.......................402 Примеры...................................................... 402 Использование Гз и р!ре для потоковой передачи статических файлов с сервера.................................402 Потоковая передача с использованием ДиепЬйтред..................................403 Глава 96. 8ецие11ге.]8............................................404 Примеры........................................... 404 Установка.................................................. 404 Определение моделей........................................ 405 1.8едие112е.(1еГ1Пе(то(1е!Кап1е, айпЬШез, [орйопз])......406 2. зедиейхелтроПфаШ).................................... 407 Глава 97. Простой СКШ) АР1 на основе КЕ8Т....................... 408 Примеры........................................................408 ВЕ8Т АР1 для СК1Ш в Ехргезз 3+...............................408 Глава 98. Связь через 8оскеС1о .............................. ... 410 Примеры...................................................... 410 «Не11о ууог1с!!» с сообщениями через сокеты..................410
Глава 99. Синхронное и асинхронное программирование вМойе.]8....... . .... .. ............................. 412 Примеры................................................... 412 Использование азупс......................................412 Глава 100. ГСР-сокегы______________________________________ 414 Примеры.....................................................414 Простой ТСР-сервер.................................... 414 Простой ТСР-клиент.......................................415 Глава 101. Шабло1гные фреймворки..............................417 Примеры.....................................................417 Чппщскз..................................................417 Глава 102. Удаление Мойе.]8.. ............................. 420 11римеры....................................................420 Полное удаление Мойе.]8 на Мас О8Х.......................420 Удаление Т4ос1е дз на УУшйом’з......................... 420 Глава 103. Фреймворки для модулвного тестирования.............421 Примеры.....................................................421 Моска синхронный..................................... 421 Моска асинхронный (саПЬаск)..............................421 Моска асинхронный (Ргопизе)..............................421 Моска асинхронный (азупс/аигай)..........................422 Глава 104. Сценарии использования Хойедз......................423 Примеры.....................................................423 Н ТТР-сервер.......................................... 423 Консоль с командной строкой..............................424 Глава 105. Использование ВгоигеегПу для устранения ошибки ‘гещнгей’ в браузерах...................426 Примеры................................... 42С Пример — Ше.]5.......................................... 426 Что делает этот фрагмент кода?........................426 Установка Вготоегйу...................................426 Важно............................................ 427 Что это значит?.......................................427 Глава 106. Использование И8Мойе для размещения веб приложений Яойе.}8 в И8....................428 Примечания................................................. 428 Проблема с виртуальным каталогом / вложенным приложением с представлениями.....................................428 Версии................................................428
Примеры..................................................... 428 Начало работы.............................................428 Требования.. ................................. 429 Простой пример НеПо \Л/ог1с1 с использованием Ехртезз................................. 429 Структура проекта..................................... 429 зегуег.рз-приложение на Ехртезз........................430 Конфигурация и М’еЬ.сопй#............................ 430 Конфигурация............................................... 430 Обработчик ПЗМобе........................................ 430 Правила ПКЕ-Кешгпе.......................................... 431 Использование виртуального каталога 118 или вложенного приложения................................ 431 Использование Зоскехло с ПЗМойе...........................434 Глава 107. Использование потоков.... .................. ....435 Параметры....................................................435 Примеры......................................................435 Считывание данных из текстового файла с использованием потоков................................ 435 Перенаправление потоков (Рхрш# зХтеатз)...................436 Создание собственного читаемого/занисываемого потока............................437 Зачем нужны потоки?.......................................438 Глава 108. Использование И/еЬЗоске» с Мойе.рз..................441 Примеры......................................................441 Установка М/еЬ8оскеХ......................................441 Добавление УУеЬЗоскех в ваши файлы........................441 Использование И'еЬ.ЗоскеХ и УУеЬЗоскеХ Зегуег.......................................441 Простой пример МГеЬЗоскеХ-сервера....................... 442 Глава 109. Веб приложения с Ехргеяз............................443 Введение.....................................................443 Синтаксис....................................................444 Параметры....................................................444 Примеры......................................................444 Начало работы............................................ 444 Основное маршрутизирование................................445 Получение информации из запроса.......................... 447 Модульное приложение на Ехртез.з......................... 448 Более сложный пример...................................449
Использование шаблонизатора.....................................450 Пример с шаблоном Е|5....................................450 АР1 с Ехрге88.]8........................................451 Обслуживание статических файлов..............................452 Несколько панок........................................ 453 Именованные маршруты в стиле 1)]'апяо........................453 Обработка ошибок........................................... 454 Использование промежуточного ИО и образного вызова пехт......................................455 Обработка ошибок.............................................457 Как выполнить код перед любым запросом и после любого ответа........................................459 Обработка РО8Т-запросов..................................... 160 Установка соокзез с использованием соокзе-рагзег.............461 Пользовательское пибсИемаге (промежуточное ПО) в Ехргезз....................................................462 Обработка ошибок в Ехргезз...................................462 Добавление промежуточного ПО (тзбзИемаге)....................463 Не11о\Уог1й..................................................463 Глава 110. У/зпОомгз-аутенгификапия в Хойе.]?.,...................465 Примечания......................................................465 Примеры.........................................................465 Использование асТшесПгес^огу.................................465 Установка................................................466 Использование............................................466 Глава 111. Менеджер пакетов Уагп.............................. 467 Введение........................................................467 Установка Уагп.............................................. 467 тпасО8.......................................................467 НотеЬгеху................................................467 МасРопз............................................... 467 Добавление Уагп в РАТН...................................467 ХУш(1оуу8....................................................467 Установщик...............................................467 С1тосо1а(еу............................................. 468 Ешпх.........................................................468 ОеЫап / ОЬипСи...........................................468 СепЮ8 / Ге<1ога / КНЕЬ...................................468 АгсЬ.....................................................468
8о1из................................................ 469 Все дистрибутивы.........................................469 Альтернативный метод установки...............................469 Скрипт оболочки..........................................469 ТагЬаП................................................. 469 МРМ......................................................469 После установки............................................... 469 Создание базового пакета.....................................469 Установка пакета с помощью Уагп..............................470 Благодарности.....................................................472
Глава 1. Начало работы с Мос1е.]8 Примечания Кос1е.]5 — эго основанная на событиях неблокирующая асинхронная платфор- ма ввода вывода, использующая ]ауа8спр6движок У8 от Соо#1е. Она примени ется для разработки приложений, которые активно задействуют возможность выполнения ^аVаЗс^^рг как па стороне клиента, так и на стороне сервера, что по- зволяет выгодно применять повторное использование кода и отсутствие пере- ключения контекста. Мо<1е.]8 является открытым кроссплатформенным реше- нием. Приложения Хойе.р пишутся на языке ]ауа8спр1 и могут быть запущены в среде Ио<1е.]з на 1ЛГш(1<Ж8, Ыпих и т. д. Версии Версия Дата выхода У22.8.0 2024-09-03 у21 .7.3 2024-04-10 У20.17.0 2021-08-21 У19.9.0 2023-04-10 У18.20.4 2024-07-08 У17.9.1 2022-06-01 У16.20.2 2023-08-08 У15.14.0 2021-04-06 У14.21.3 2023-02-16 У13.14.0 2020-04-29 У12.22.12 2022-04-05
У11.15.0 2019-04-30 VI 0.24.1 2021-04-06 У9.11.2 2018-06-12 У8.2.1 2017-07 20 У8.2.0 2017-07-19 У8.1.4 2017-07-11 У8.1.3 2017-06-29 У8.1.2 2017-06-15 У8.1.1 2017-06-13 у8.1.0 2017-06-08 У8.0.0 2017-05-30 У7.10.0 2017-05-02 У7.9.0 2017-04-11 У7.8.0 2017-03-29 У7.7.4 2017-03-21 У7.7.3 2017-03-14 У7.7.2 2017-03-08 У7.7.1 2017-03-02 у7 7.0 2017-02-28 У7.6.0 2017-02-21 У7.5.0 2017-01-31 У7.4.0 2017-01-04 У7..3.0 2016-12-20 У7.2.1 2016-12-06 У7.2.0 2016-11-22 У7.1.0 2016-11-08 У7.0.0 2016-10-25 уб.11.0 2017-06-06 Уб.10.3 2017-05-02 Уб. 10.2 2017-04-04 уб.Ю 1 2017-03-21
уб.10.0 2017-02-21 уб.9.5 2017-01-31 уб.9.4 2017-01-05 уб.9.3 2017 01 05 уб.9.2 2016-12-06 уб.9.1 2016-10-19 уб.9.0 2016-1018 уб.8.1 2016-10-14 Уб.8.0 2016-10-12 уб.7.0 2016-09-27 уб.6.0 2016-09-14 Уб.5.0 2016-08-26 Уб.4.0 2016-08-12 уб.3.1 2016-07-21 Уб.3.0 2016-07-06 Уб.2.2 2016-06-16 Уб.2.1 2016-06-02 Уб.2.0 2016-05-17 Уб.1.0 2016-05-05 Уб.0.0 2016-04-26 У5.12.0 2016-06-23 У5.11.1 2016-05-05 У5.11.0 2016-04-21 У5.10.1 2016-04-05 У5.10 2016-04-01 У5.9 2016-03-16 У5.8 2016-03-09 У5.7 2016-02-23 У5.6 2016-02-09 У5.5 2016-01-21 у5.4 2016-01-06
у5.3 2015-12-15 у5.2 2015-12-09 у5.1 2015-11-17 у5.0 2015-10 29 у4.4 2016-03-08 у4.3 2016-02-09 у4.2 2015-10-12 у4.1 2015-09-17 5/4.0 2015-09-08 1О.]8 уЗ.З 2015-09-02 1О.)8 у3.2 2015-08-25 1О.]8 У3.1 2015-08-19 1О.)8 уЗ.О 2015-08-04 ю.)8 у2.5 2015-07-28 1О.]8 5’2.4 2015-07-17 1о.)8 у2.3 2015-06-13 1О.)8 у2.2 2015-06-01 1О.)8 5’2.1 2015-05-24 1о.|8 у2.0 2015-03-04 1о.)8 У1.8 2015-04-21 1о.)8 У1.7 2015-04-17 1о.)8 У1.6 2015-03-20 1О.)8 VI.5 2015-03-06 Ю.)8 У1.4 2015-02-27 1о.)8 У1.3 2015-02-20 1о.)8 У1.2 2015-02-11 1О.)8 VI I 2015-02-03 1О.)8 У1.0 2015-01-14 уО.12 2016-02-09 уО.И 2013-03-28 уО.10 2013-03-11
уО.9 2012-07-20 у0.8 2012-06-22 у0.7 2012-01-17 у0.6 2011-11 04 у0.5 2011-08-26 с0.4 2011-08-26 уО.З 2011-08 26 у0.2 2011-08-26 \'0.1 2011-08-26 Примеры НТТР-сервер «НеНо Мог И» Сначала установите Иоскф для вашей платформы. В этом примере мы создадим НТТР-сервер, который будет слушать на порту 1337 и отправлять «НеИо, Иог1б1» в браузер. Обратите внимание, что вместо порта 1337 вы можете использовать любой другой номер порта по вашему выбо- ру, который в данный момент не задействован другими службами. Модуль Ш1р является основным модулем Мос1е.]8 (модулем, который вклю- чен в исходный код Мос1е.]8 и не гребует установки дополнительных ресурсов). Он предоставляет функциональность для создания НТТР-сервера с использова нием метода ШДр. сгеаге8ег^ег(). Чтобы начать разработку приложения, соз- дайте файл, содержащий следующий ]аеа5спр(-код: сопзС 1НГр = гери!ге('ЬГХр'); // Загружает модуль бПр 1тГ1р.сгеате8егуег((героезт, гезропзе) => { // 1. Сообщаем браузеру, что все в порядке (Код состояния 200) и данные в обычном тексте гезропзе «/Г1ГеНеаб(200, { 'СопсепС-Гуре': 'сехт/р1а1п' }); // 2. Записываем обьявленный текст в тело страницы гезропзе ,»г11е(' НеПо, Йог1б! \п ’) ; // 3. Сообщаем серверу, что все заголовки ответа и тело отправлены гезропзе.епЩ);
}).115геп(1337); // 4. Сообщаем серверу, на каком порту слушать Сохраните файл под любым именем. В данном случае, если мы назовем ею Пе11о.]5, мы можем запустить приложение, перейдя в каталог, где находится файл, и используя следующую команду: побе Ье11о.]з Созданный сервер затем будет доступен в браузере по СКЬ НПр:// ТосаИтозС: 1337 или Ы1р//127.0.0.1 '1337. Появится простая веб страница с текстом «Не11о, Мог1б!» вверху, как показано на скриншоте ниже: 1оса1Ьо5М337 «Ф) С ± » Ие11о, Ног14! Пример «Не11о Мог1с1» в командной строке Чобе.]8 также может быть использован для создания утилит командной стро- ки. Пример ниже считывает первый аргумент из командной строки и выводит' сообщение «Не11о». Чтобы запустить этот код на Пп1х-сисгеме' 1. Создайте новый файл и вставьте в него код, представленный ниже. Имя файла не имеет значения 2. Сделайте этот файл исполняемым с помощью команды сбтоб 780 РПЕ_ МАМЕ 3. Запустите приложение командой ./АРР_КАМЕ Оаулб. Па ААтшс1ом'8 выполните шаг 1 и запустите приложение командой побе АРР-ИАМЕ Са71б
#!/изг/Ып/еоу побе 'изе 81Г1СС'; /* Командные аргументы сохраняются в массиве ргосезз ,агду ', который имеет следующую структуру [0] Путь к исполняемому файлу, который запустил процесс 1чобе.]3 [1] Путь к этому приложению [2-п] Аргументы командной строки Пример: [ '/Ьтп/побе1, '/ратН/го/уоигзсгтрг ’, 'агдГ, 'эгд2', ... ] зге: НТТрз://посе]з.огд/арт/ргосезз. 1тТт1#ргосезз. ргосезз_агду */ // Сохраняем первый аргумент как имя пользователя. уаг изегпате = ргосезз.агду[2]; // Проверяем, предоставлено ли имя пользователя. 1Г ('изегпате) { // Извлекаем имя файла уаг аррМате = ргосезз.агду[ 1 ] .зр1±1(гецо1ге('ра1:1т1).зер) рор(); // Даем пользователю пример, как использовать приложение сопзо1е.еггог(Т1зз1пд агдитепТ1 Ехатр1е: %з УО11К.МАМЕ', аррйате), // Завершаем выполнение приложения (успех. 0. ошибка: 1). // Ошибка остановит выполнение цепочки команд. Например: // ,/арр да && 1з -> команда 1з не выполнится // ,/арр ]з 0ау1б && 1з -> команда 1з выполнится ргосезз.ех11(1); } // Выводим сообщение в консоль. сопзо1е.1од('не11о %з1 ', изегпате); Установка и запуск Модема Для начала установите Мойе р на ваш рабочий компьютер. Шпйои'з: Перейдите на страницу за]рузки по ссылке Ьйрз://по(1е)8.ог§/ец/ <1о\уп1оас1/раска^е-тапа§ег или по ОК коду ниже и скачайте/запустите установоч- ный файл.
Мас: Перейдите на страницу загрузки по ссылке ИПр8://по(1е]8.ог^/еп/ 11ом/п1оаб/раска^е-тапа§ег или по рВ. коду ниже и скачайте/запустите устано- вочный файл. Альтернативно вы можете установить Пойе через НотеЬгеи?, используя ко- манду Ьгел 1П51а11 пос!е НотеЬгем/ — это менеджер пакетов командной стро- ки для МаспйозИ, и дополнительную информацию о нем можно найти на сайте НотсЬгету, перейдя по ссылке йпр8://Ьге\у.81з/ или по рВ-коду ниже. Ьтих: Следуйте инструкциям для вашей дистрибуции на странице усгановки из командной строки, перейдя по ссылке Ипр8://пос1е]8.ог8/еп/с1ои’п1оаб/раска§е- гаапа§ег/ или по рК-коду на следующей странице.
вШЙ Запуск программы Кодера Чтобы запустить протрамму на Мобе.)з, выполните команду побе арр. ] 5 или побе] з арр. ] з, где арр. ] з — это имя файла с исходным кодом ваше- го Мобе приложения. Вам не нужно включать суффикс . ]8, чтобы Мойе нашел скрипт, который вы хотите запустить. Альтернативно в операционных системах на базе 16М1Х программа Мобе может быть выполнена как скрипт терминала. Для этого она должна на- чинаться с «шейбэнга», указывающего на интерпретатор Мобе, такого как #!/изг/Ьтп/епу побе. Файл также должен быть помечен как исполняемый, что можно сделать с помощью команды сйтоб. Теперь скрипг можно запускать непосредственно из командной строки. Развертывание вашего приложения в онлайн-среде Когда вы разворачиваете ваше приложение в среде хостинга (специфичной для Мобе.)з), эта среда обычно предоставляет переменную окружения РОКТ, ко- торую вы может е использовать для запуска вашего сервера. Изменение номера порта на ргооезз. епу. РОПТ позволяет получить доступ к приложению. Например: Н1Ср.сгеа('е2ег\ег((:ипсС1оп(^ие81;1 гезропзе) { // ваш код сервеоа }) .11зСеп(ргосезз .епу.РОКТ); Также если вы хотите получить доступ к приложению офлайн во время отлад- ки, вы можете использовать следующее: Истр.сгеа1:е8егуег(Типс1:1оп(гериез1:, гезропзе) { // ваш код сервера }) .11зСеп(ргосезз.еп7.РОРТ || 3000); ...где 3000 — это номер порта для офлайн-доступа.
Отладка вашего 1Чос1е.]8-приложения Вы можете использовать побе-ю&ресТог. Выполните следующую команду, чтобы установить его через МРМ: прт 1пз1а11 -д побе-нпзресСсг Затем вы можете отлаживать ваше приложение, используя: пойе йеЬид арр . д з Репозиторий на СпНпЬ можно найти здесь: Ийрз^/рЙшЬ.сош/побе-шзресТог/ побе-тзресШг или по уК-колу ниже. Отладка нативно Вы также можете отлаживать Мойедз нативно, запустив его следующим об- разом: пойе беЬид уоиг-зсгйрТ.уз Чтобы установить точку останова (ЬгеакротО в нужной строке кода, исполь зуйге это: беЬоддег; В Мос1е.]8 версии 8 используйте следующую команду: пос1е --назреет-Ьгк уоог-зспрТ. ]3 Затем откройте аЬооТ://1пзрес1: в последней версии Соо§1е Сйгоше и вы- берите свой Мойе-скрипт, чтобы получить опыт отладки с помощью ОеуТоо]з Сйгоше. «Не1Ео \А/ог1й» с использованием Ехргезз В следующем примере используется Ехргезз для создания НИР-сервера, кото- рый слушает порт 3000 и о гвечает «РеПо, Иог1й!». Ехргезз — это широко приме- няемый веб-фреймворк, который полезен для создания НИР АР1.
Сначала создайте новую панку, например туАрр. Перейдите в папку туАор и создайте новый ]ауа8спрт-файл, содержащий следующий код (назовем его, например, Ие11о ]з). Затем установите модуль ехргезз, используя команду прш 1пзта11 --зауе ехргезз в командной строке. Ознакомьтесь с документа- цией по ссылке йир8://г1р(Щопа1.сот/пос1е-)8/ехатр1е/158ЯДп;ДаШп^-раска§е8 или по рК-коду ниже для получения дополнительной информации о том, как устанавливать пакеты. // Импортируем верхнеуровневую функцию ехргезз сопзС ехргезз = геци!ге('ехргезз'); // Создаем приложение Ехргезз, используя верхнеуроеневую функцию сопзт арр = ехргезз(); // Определяем номер порта как 3000 сопзС рог! = 3000; // Обрабатываем НТТР ОЕТ-запоосы по указанному пути "/' с указанной функцией обратнее вызова арр.де1('/', ГипсС1оп(гециез!, гезропзе) { гезропзе.зепб('Не11о, ИогХсН’); }); // Заставляем приложение слушать на порту 3000 арр.ХтзХеп(рогС, ГипсХюпО { солзо1е.1од( Зегуег 11зСеп1пд оп Ытр://1оса11тозТ;' + рогт); }); Из командной строки выполните следующую команду: пос1е Ье11о.]з Откройте браузер и перейдите по адресу 1гЩр://1оса1Иозт :3000 или КТСр: / /127.0.0.1 :3300, чтобы увидеть ответ.
«Не11о М/оН<1» с базовой маршрутизацией Как только вы поймете, как создать Н'ПР-сервер с Тчос1еД8. важно понять, как заставить его «делать» что-то в зависимости ст пути, по котором}’ пользова- тель перешел. Этот механизм называется маршрутизацией. Самый простой пример — проверка 1Г (гериезС.иг! === ' зоше/раПг/ Неге') и затем вызов функции, которая отвечает новым файлом. Пример этого можно увидеть здесь: сопзГ ГйСр = герсн ге ('пГЛр'); ГипсНоп 1пбех (гериезС, гезропзе) { гезропзе .иг11:еНеаб(200); гезропзе.епсЦ 'Не11о, Шог1с1!'); } ГтГГр. с геа1е8ег7е г (-Гипс-Поп (гериезС, гезропзе) { 1Г (гериез1:.иг1 === '/') { геГигп 1пбех(гериезт, гезропзе); } гезропзе .лг11:еНеай(404); гезропзе ,епб(Ыгр.8ТАТ118,СОВЕ8(404]); }) .Пз1:еп(1337); Однако если продолжать определять «маршруты» таким образом, вы в конеч- ном итоге получите одну огромную функцию обратного вызова, что может со- здать беспорядок. Давайте попробуем оптимизировать это. Сначала сохраним все наши маршруты в объекте: уэг гоиСез = { '/': Гипсноп тпбех (гериезт, гезропзе) { гезропзе.лг1сеНеаа(200); гезропзе.епб('Не11о, Иог1б!'); }, ’/Гоо': ГипсНоп Гоо (гериезГ, гезропзе) { гезропзе.пг11еНеаа(200): гезропзе.епб('Уои аге пси утентпд Гоо 1') ; } } Теперь, когда мы сохранили два маршрута в объекте, мы можем проверить их наличие в нашей основной функции обратного вызова. ГтИр.сгеаСеЗегуег(ГипсНоп (героезт, гезропзе) { 1С (гериез!: иг1 1п гоиСез) { геСигп гоиСез[гериез(:,иг1](гериезГ, гезропзе); }
гезропзе. лг:1ЛеНеас1(404); гезропзе епс!(К11р.8ТАТи8_СООЕ8[404]); }).11$Геп(1337); Теперь каждый раз, когда вы пытаетесь перейти по какому-либо пути на ва- шем сайте, сервер будет проверять наличие этого пути в ваших маршрутах и вы- зовет соответствующую функцию. Если маршрут не найден, сервер ответит ко- дом 404 (МоТ Еоипб). Вот и все — маршрутизация с использованием ЛР1 НТТР-сервера очень проста Т1_5 ЗоскеГ сервер и клиент Единственные значительные отличия между этим и обычным ТСР-соедипе- нием — это закрытый ключ и публичный сертификат, которые вам нужно будет установить в объекте опций. Как создать ключ и сертификат Первым шагом по обеспечению безопасности является создание приватно- го ключа. Что же такое приватный ключ? По сути, эго набор случайного шума, который использует ся для шифрования информации. Теоретически ьы могли бы создать один ключ и использовать его для шифрования чего угодно. Но луч- шая практика— иметь разные ключи для разных целей, потому что если кто- то украдет ваш приватный ключ, это похоже на кражу ключей от вашего дома. Представьте, что могло бы произойти, если бы вы использовали один и тот же ключ для запирания машины, гаража, офиса и т. д. эрепзз1 депгза -ои4 опуате-кеу.реш 1024 Теперь, когда у нас есть приватный ключ, мы можем создать С8К (запрос на подпись сертификата), который является нашим запросом на подпись при- ватного ключа авторитетной организацией. Именно поэтому нужно вводить ин- формацию, связанную с вашей компанией. Эта информация будет видна подписывающему органу и использована для ва- шей верификации. В нашем случае неважно, что вы введете, так как на следую- щем шаге мы сами подпишем наш сертификат: орепзз! гер -пел -кеу рпуаТе-кеу .рет -оиС сзг.рет Теперь, когда у нас есть все документы, пришло время притвориться, будто мы — авторитетный подписывающий орган власти: орепзз1 х5Э9 -гер -1п сзг.рет -зьдпкеу ргтуаТе-кеу.рет, -оиТ риЫлс- сегТ.рет
Теперь, когда у вас есть приватный ключ и публичный сертификат, вы мо- жете установить защищенное соединение между двумя приложениями Мобе.]8. Как видно в примере кода, это очень простой процесс. Важно! Поскольку мы создали публичный сертификат сами, честно гово- ря, он бесполезен, потому что мы на самом деле никем не являемся. Мобе.]$-сервер по умолчанию не будет доверять такому сертификату, и имен- но поэтому нам нужно указать ему доверять сертификату с помощью опции ге]есЫ1па1ЛГюг12ес1: Та1зе. Очень важно: никогда не устанавливайте эту пере- менную в 1гие в производственной среде. 715 ЗоскеТ Зегуег 'изе З1г1с1’; ’/аг 11з = геди1ге( ‘Из’) ; уаг Гз = геди!ге(Тз'); сопз! РОР1 = 1337; сопз! Н081 = '127 0.6 1' уаг орТюпз = { кеу; Гз. геабГ11е8упс( 'рпуасе-кеу.рет'), се г 1: Тз. геабЕИе8упс(' риЫю-сег! . рет') }; уаг зегуег = 11з.сгеа1;е8егуег(ор'11оп8, Гипс11оп(зоске1:) { // Отправить дружеское сообщение зоске! .ип1е("I ап 1Ье зегуег зепбхпд уои а теззаде ' ); // Вывести данные, которые мы получили зоске! оп('бата', Гипс1хоп(бата) { сопзо1е.1од('Ресехуеб: %з [11 13 %б ЬуХез 1опд]’, баба.1о81г1пд().гер!асе(/(\п)/дт,, бата.1епдгп); }); // Сообщить нам, когда передача закончена зоскеХ,оп('епб', ГипсГхоп() { сопзо1е.1од('ЕОТ (Епб ОТ Тгапзшхззхоп) ’) ; }); }); // Начать прослушивание на конкретном порту и адресе зегуег.11з1еп(Р0РТ, НО8Т, 1ипс11оп() { сопзо1е.1од( 1'т 1хз1:еп1пд а! %з, оп рог! %з ', Н08Т РОРТ); }); // При возникновении ошибки отобразить ее. зегуег.оп(’еггог’, ТипсТхоп(еггог) { сопзо1е.еггог(еггог);
// Закрыть соединение после возникновения ошибки зетуег ,с1е8сгоу(); }); Т1_8 Боскет С11еп1 'иве 51:пс1'; уаг Из = геди!ге('Из'); уаг Тз = геди1ге(' Тз') ; СОП51 РОРТ = 1337; сопз! Н08Т = 127.0.0.1 // Передать сертификаты серверу и указать ему обрабатывать даже неав- торизованные сертификаты уаг орИопз = { кеу. Тз. геабР11е8упс( ' рг!уаТе-кеу .рет'), сегС . Тз. геаОЕ11е8упс(1 робИс-сегТ .рет'), ге]есИ)паиГ1тог12е0. Та1зе }; уаг сИепИ = Т1з.сотлеет(РОРТ, Н08Т. орНопз, ГипсНоп() { // Проверить, сработала пи авторизация 1Т (сНепТ.аигЬогхгеб) { соп8о1е. 1од( "Соппестюп аиткопгеб Ру а СегИНсаТе АитЬогИу."); } е1зе { сопзо1е.1од("Соппес11оп пог аигЬсгхгеб: " + с!1еп1. аиХЬопгаИопЕггог) } // Отправить дружеское сообщение сИепТ .йг!1е( "I ат ТЬе с11епт зеполпд уои а теззаде."); }); с11епТ.оп( баТа' , ГипсНоп(с1а1.а) { соп5о1е.1од(' Ресехуеб• %з [11 хз %с1 ЬуТез 1опд]', баГа.то8тг1пд().гер1асе(/(\п)/дт," ), 0аса.1епд1Н); // Закрыть соединение после получения сообщения с11епс .епс1(); }); с11еп1.оп( сТозе', Типс1юп() { сопзо1е.1од( ’ Сог.песПсп сТозеа ); }); // При возникновении ошибки отобразить ее с11еп1.оп( еггог1, ТипсИсп(еггог) { соп8о1е.еггог(еггог); // Закрыть соединение после возникновения ошибки сИеп! .Ре81гоу(); });
Не11о Лог1й в АЕР1_ Когда Хо йе.]8 вызывается без аргументов, он запускает КЕРЕ (Кеай-Ета1-Ргт1- Ьоор), также известный как Хойе зЬе11. В командной строке введите пойе $ пойе На приглашении Хойе 5Ье11 > введите «Не11о Ио г 1й!»: $ поое > "Не Но Иог1й!" Не11о Пог1й1' Соге-модули Хойе ]8 — это движок ]ата5спр( (движок У8 от (Зоо^е для Сйготпе. написанный на С++), который позволяет запускать |ауа8спр( вне браузера. Хотя для расшире- ния возможностей Хойе.]8 доступно множество библиотек, движок поставляется с набором соте-модулей, реализующих основные функции. В настоящее время в Хойе.)8 включено 34 соге-модуля: [ 'аззегТ ' , 'ЬиГГег ’, 'с/с++_айоопз', ' с1т11й_ргосе58 ’, 'сХозУег', 'сопзо1е', ' сгурУо', ' йергесаТей.арйз', ' йпз' , ' йотант', ' еуепСз', 'Ез', 'НСср . 'ГтНрз', 'тойиЕе', ' пет’, 'оз', 'рас1т , 'рипусойе , 'ЯиегузТгтпд , ' геайНпе', 'гер1', ’ зТгеагтГ ,
' 51ппд_бесобег', ' Тиглегз , '115.(551)', ТгасЕпд’, '«у', ' с!д гат', ' иг1’, 'ЛИГ, у8’, ут ’, 'г11Ь' ] Этот список был поштучен из ЛР1 документации Ыос1е.]!>, на который можно пе- рейти по ссылке Йир8://по(1е]8.ог§/ар]/а1].1йт1 или по рК-коду ниже. Все соге-модули: краткий обзор а»8ег( Модуль а55ег 1: предоставляет простой набор тестов утверждений, которые можно использовать для проверки инвариантов. ЬиНег До введения Турес!А г г ау в ЕСМЛЗспрТ 2015 (Е86) в языке ]ауа$сг1р1 не было ме- ханизма для чтения или манипулирования потоками бинарных данных. Класс ВиТТег был введен как часть ЛР1 Ыос1е.]я, чтобы сделать возможным взаимодей- ствие с октетными потоками в контексте таких вешей, как ТСР-потоки и опера- ции с файловой системой. Теперь, когда ТуребАггау добавлен в Е86, класс ВиНег реализует АР1 1ЛрС8Аггэу таким образом, который более оптимизирован и подходит для слу- чаев использования ’МоЛеДз. с/с-г+_аск1оп8 Лбаспз в Кобе.]8 — это динамически связываемые общие объекты, написан- ные на С или С++, которые могут быть загружены в Мобе.]8 с помощью функции
гес|и! ге() и использовал вся так же, как обычный модуль Ыос1е.]8. Они применя- ются в основном для обеспечения интерфейса между ]ауа8спр1, выполняющим- ся в Мойе.]5, и библиотеками на С/С++. сЫИргосезз Модуль сб11О .ргосезз предоставляет возможность порождать дочерние про- цессы аналогично, но не идентично рореп(3) сктзГег Одна инстанция Мойецз работает в одном потоке. Чтобы воспользоваться преимуществами многопроцессорных систем, иногда нужно запустить кла- стер процессов Мойе ]8 для обработки нагрузки. Модуль с1изтег позволяет лег- ко создавать дочерние процессы, которые разделяют серверные порты. сопзо1е Модуль сопзо1е предоставляет простой отладочный консольный интер- фейс, похожий на механизм консоли ]ауаЗспрС, предоставляемый веб-брау- зерами. сгурСо Модуль сгурю предоставляет криптографические функции, включая набор оберток для функций ОрепЗЗЬ, таких как 1газ1т, НМАС, стрбег, бестрбег, зтдп и уегйТу. йергеса! ей .арьз Мос1е.]5 может «устаревать» ЛР1 в следующих с.гучаях: (а) использование ЛР1 считается небезопасным, (Ь] доступна улучшенная альтернатива АР1 или (с) ожидаются изменения, несовместимые с нре/цядущими версиями, в будущем крупном релизе. ЙПЗ Модуль без содержит функции, принадлежащие к двум разным катего- риям: 1. Функции, использующие возможности операционной системы для выполнения разрешения имен и не обязательно выполняющие сетевое взаимодействие. В эту категорию входит только одна функция: бпз.1оокир(). 2. Функции, которые подключаются к реальном)' ПМЗ-серверу для вы волнения разрешения имен и всегда используют сеть для вы волнения ВМЗ-запросов. В эту категорию входят все функции в модуле йпз, кроме бпз.1оокор().
с!ота1п Этот модуль вскоре станет устаревшим. Как только будет окончательно утверждено заменяющее АР1, этот модуль станет полностью устаревшим. Боль- шинство конечных пользователей не должны использовать этот модуль. Поль- зователи, которым необходима функциональность, предоставляемая доменами, мотут полагат ься на него в настоящее время, но должны быть готовы к переходу на другое решение в будущем. ЕуепЬ Большая часть основного АР1 Мос1е.)8 построена вокруг идиоматической асинхронной событийно-ориентированной архитектуры, в которой опре- деленные типы объектов (называемые еттТТегя) периодически испускают именованные события, которые вызывают объекты ЕопсДюп (называемые 11з1епегз). Ввод-вывод файлов осуществляется с помощью простых оберток вокруг' стандартных функций РО81Х. Чтобы использовать этот модуль, нужно вызвать геди1ге(' Тз ’). Все методы имеют асинхронные и синхронные формы. 1Н1р Интерфейсы НТТР в Пос1е.|8 спроектированы таким образом, чтобы поддер- живать многие особенности протокола, которые традиционно трудно использо- вать. В частности, это крупные, возможно, кодируемые фрагментами сообщения. Интерфейс никогда не буферизует целые запросы или ответы — пользователь может передавать данные в потоке. ЫГрз НТТР8 — это протокол НТТР поверх ТБ5/88Е В Кос1е.]8 это реализовано как от- дельный модуль. шо(1и!е \то<1е.]8 имеет простую систему загрузки модулей. В Ыо<1е.]8 файлы и модули находят ся в соответствии одно к одному (каждый файл рассматривается как от- дельный модуль). пет Модуль пеб предоставляет вам асинхронную сетевую оболочку. Он содержит функции для создания как серверов, так и клиентов (называемых потоками). Вы можете подключить этот модуль с помощью геди! ге( пеб').
08 Модуль оз предоставляет множество утилит, связанных с операционной си- стемой. ра(Ь Модуль ра!И предоставляет утилиты д.тя работы с путями к файлам и каталогам. рипусойе Версия модуля рипусобе, включенная в Ыоаедз, устаревает. циегу8(пп§ Модуль риегузГгтпд предоставляет утилиты для разбора и форматирования строк запросов ПКЬ. геасШпе Модуль геабИпе предоставляет интерфейс для чтения данных из потока КеабэЫе (например ргосезз. зСбтп) построчно. гер! Модуль гер1 предоставляет реализацию Кеаб-ЕгаЬРгтт-Ьоор (ВЕРЬ), которая доступна как отдельная программа или может быт ь включена в другие прило- жения. зТгеат Зггеат — это абстрактный интерфейс для работы с потоковыми данными в Г^ос1е.]5. Модуль зтгеат предоставляет базовое АР(, которое упрощает создание объектов, реализующих интерфейс потока. В Мойедз предоставляется множество объектов зТгеат. Например, запрос к НТТР-серверу и ргосезз. з! бои! являются экземплярами зСгеаш. ЩПП& йесойег Модуль зсппд.бесобег предоставляет АР1 для декодирования объектов ВиГТег в строки таким образом, который сохраняет закодированные многобай- товые символы ЕПТ-8 и ЪГТГ-16. (йпегз Модуль Нтег предоставляет глобальный ЛР1 для планирования вызовов функций в определенное будущее время. Поскольку функции таймера являются глобальными, нет необходимости вызывать геди!ге(' Нтегз ’) для использова- ния АР1.
Функции таймера в Хос1е.]3 реализуют АР1. аналогичное АР1 таймеров, предо- ставляемому7 веб-браузерами, но испо.тьзуют другую внутреннюю реализацию, построенную вокруг ЕуепГ Т.оор К’обе.]8. 118 (881) Модуль предоставляет реализацию протоколов ТгапзроП Ьаует Зесигйу (ГЕ8) и Весите ВоскеГ Ьаует (ВВЬ), построенпуто па базе ОрепЗВЬ 1гас1п§ Ттасе Еуеп( предоставляет механизм для централизованного сбора информа- ции о трассировке, генерируемой \?8. ядром Кобе и пользовательским кодом Трассировка может быть включена с помощью передачи флага --Егасе- еуепТз-епаЫеб при запуске приложения Ко<1е.)8. «У Модуль Ку предоставляет классы Ку. РеаОЗГ геат и Ку. Мг КеЗТ геат. В боль- шинстве случаев не потребуется или не удастся использовать этот модуль на- прямую, (1§гат Модуль бдгат предоставляет реализацию 1ЮР Вата&гат-сокетов. иг1 Модуль и г1 предоставляет утилиты для разрешения и разбора Е'КЕ. иШ Модуль иК1 предназначен в первую очередь для поддержки внутренних АР] Ыос1е.]ь. Однако многие утилиты полезны для разработчиков приложений и мо- дулей. у8 Модуль у8 предоставляет АР1, специфичные для версии У8, встроенной в би- нарный файл Кобе.)5. Примечание; АР1 и реализация могут изменяться в любое время. УШ Модуль ут предоставляет АР1 для компиляции и выполнения кода в контек- сте виртуальной машины У8. Код )аса5сг1р: может быть скомпилирован и вы- полнен немедленно тьли скомпилирован, сохранен и выполнен позже. Примечание: модуль ут не является механизмом безопасности. Не исполь- зуйте его для выполнения ненадежного кода.
гПЬ Модуль /ИЬ предоставляет функциональность сжатия, реализованную с ис- пользованием Сир и ОеТ1аСе/1пТ1аСе Как запустить базовый НТТР5 веб-сервер? После того как !^ос1е.|з установлен на вашу систему, вы можете просто сле- довать процедуре, представленной ниже, чтобы запустить базовый веб-сервер с поддержкой как НТТР, так и НТТР8. Шаг 1: создание центра сертификации 1. Создайте папку, где вы хотите хранить свой ключ и сертификат: ткбтг сопр 2. Перейдите в эту директорию (папку): сс1 сопТ 3. Скачайте файл са. спТ для использования в качестве конфигурационного ярлыка: «дес Кетоз: / /гаи.даТНиЬизегсопТепТ .соп1/ап^ег894/^IТТрз-аисI'|О^12е^- с1^епТз/тазТег/кеуя/са .спГ 4. Создайте новый центр сертификации, используя эту конфигурацию: орепзз! гед -пен -х5Э9 -бауз 9999 -сопГхд са.спТ -кеуоиТ са-кеу,рет -оит са-сегт,рет 5. Теперь, когда у нас есть центр сертификации в са-кеу.рет и са-се гТ.рет, сгенерируем приватный ключ для сервера: орепзз! депгза -ой! кеу.рет 4996 6. Скачайте файл зегуег.сп! для использования в качестве конфи- турационного ярлыка: идет ЬТТрз ://гаи.д1Т(1иЬизегсопТепТ.сот/апОегз94/1тТТрз-аиТ1тог12ес1- сИепТз/тазТе г/кеу з/зегуег. спТ 7. Сгенерируйте запрос на подпись сертификата, используя эту конфи- гурацию: орепзз! гед -пей -сопТтд зегуег.спГ -кеу кеу рек. -оиТ езг.рет 8. Подпишите запрос:
орепзз1 х599 -гея -ехгТ11е зегуег.спТ -оауз 999 •раззтп "разз:раззлогб -1п сзг.рет -СА са-сегТ.рет -САкеу са-кеу.рет -САсгеаТезегТа! -ооТ сегу рет Шаг 2: установка вашего сертификата в качестве корневого 1. Скопируйте ваш сертификат в папку с корневыми сертификатами: зиоо ср са-сгг.рет /изг/ТссаХ/зКаге/са-сегИТюеТез/са-сгс.рет 2. Обновите хранилище сертификатов СА: зибо ирбаУе-са-сетТтсаТез Шаг 3: запуск вашего Ыос1е-сервера Сначала создайте файл зег7ег.]з, который будет содержать код вашего сервера. Минимальная настройка для НТТР8-сервера в Мойе.]5 может выглядеть так: уаг ЬУУрз = гери1ге('КУУрз'); уаг Тз = геро1ге('Тз'); уаг НУТрзОрУюпз = { кеу: Тз.геабГ11е8упс('раУб/То/зегуег-кеу.рет'), сегУ: Тз геабЕ11е8упс('раУп/Уо/зегуег-сгУ.рет’) }; уаг арр = Типссюп (гер, гез) { гез,йг1УеНеаа(200); гез.епЩ"пе11о иог1б\п"); } бУУр8.сгеаУе8егуег(ЬУУрз0рУюпз, арр) ,11зУеп(4433); Если вы также хотите поддерживать НТТР-запросы, вам нужно внести лишь одно небольшое изменение: уаг НУУр = геро1ге(' бУтр'); уаг бУУрз = геяо1ге(’бУУрз'); уаг Тз = геро1ге( Тз’) ; уаг бУУрзОрутопз = { кеу: Тз.геабР11е8упс(’ратб/го/зегуег-кеу.реп’), сегУ: Тз геаоЕ11е8упс('раУб/то/зегуег-сг1 .рет’) }; уаг арр = ТопсУюп (гер, гез) { гез.«г1УеНеаа(200) ; гез.епсЦ 1те11о й'ог1б\п"); }
МЛр.сгеа1еЗег\/ег(арр) . 11 з!еп(8888) ; ПИрз .сгеаГеЗегуег^ССрзОрСюпз, арр). 1181еп(4433); 1. Перейдите в директорию (или папку), где находится ваш зегуег. ] з: се) /ратН/1о 2. Запустите зегуег.)з: поСе зегуег.]з
Глава 2. Взаимодействие АгсЫло с Мойе.р Введение В этой главе представлены способы, позволяющие Мос1е.)8 взаимодействовать с Агйщпо Ппо. Примеры Связь Модеме с Агбшпо через зепа1рог1 Код Коде ]8 Пример, с которого можно начать эту тему — сервер \ос1е.]'8, взаимодействую- щий с Агбшпо через зепа1рог1. прт 1гз1а11 ехргезз --зауе прш 1пз1а11 зег1а1рог1: -зауе Пример арр ]з: сопзС ехргезз = герыге('ехргезз'); сопзТ: арр = ехргезз(); уаг 8егга1Рог1 = геро1ге("зеггаХрогТ"); еаг роге = 3000 уаг агбизпоСОМРоге = "СОМЗ"; уаг агби1по8ег1а1Рог1 = пей 8ег1а1Рог1:(агби1пэС0МРогГ, { ЬаобгаТе 9660 }); агаи1по8ег1а1Рог!,ор('ореп', ^апст1оп() { сопзо1е.1од( 8ег1а1 Роге + агботпеСОМРог-с + ' тз орепеа.'); });
аор.дет.(' /', Типсгюп (гед. гез) { гетигп гез .зепа('Йогкшд ); }); арр.деТ (‘ / :асгюп', ТипсМоп (гед, гез) { уаг асТтоп = гед рагапз.асТаоп || гед .рагапц ' асИоп ’); аТ(ас^оп == ' 1есГ ){ агс!и1по8ег1а1РогТ .иг11е( "и"); ге1:игп гез.зепс1( '|_ес! Д1д1пг аз оп!'); } И(асИоп == 'оТГ1) ( агс1и1по8епа1Рог1: .лп1е( "г"); ге1игп гез.зепб("1_ес1 11д1т1 аз оТТ!"); } геТигп гез .зепс!(' Асиоп + асГюп); }); арр.11з1еп(рог1:1 ГипсИоп () { сопзо]е.1од( ‘Ехато1е арр 11згегчпд оп рост 1шр://0.0.0.0:' + рогт + }); Запуск примера Ехргезз-серьера: пойе арр.]з Код Агдшпо // Функция зе1:ир выполняется один раз при нажатии кнопки сброса или при включении питания платы уо1с1 зе1ир() { // инициализируем цифровой вывод 1_ЕО_В1!11-Т1М как выход Зегаа].Ьеда.п(9б80); // Начинаем прослушивание на порту 9600 р1пМос!е(1ЕО_ВОПИМ, 00ТР0Т) ; 01д11а1Ига.1:е(1ЕО_Ви11-Т1М, ЮИ); }
// Функция 1оор выполняется снова и снова уо!с1 1оор() { 1Г(8ег1а1 ,ауа1]аЫе() > 0) // Чтение данных из последовательного порта { сИаг ЕеасегЕго(тФ1эбе; // Сохраняем текущий символ Р.еабегЕготМобе = (сбаг) 8егт.а1. геаб(); сопуег'1То8'1а1е(РеэбегЕгоп1Ьо11е); // Преобразуем символ в состояние } бе1ау ((1000); } уо1с! сопуегГТо81:а1;е(сНаг сЬг) { 1Г(сЬг==’о'){ б1д11а1Иг11е(1.Е0.В1111_Т1М, НТСН); с!е1ау (100); } 1Г(сбг==’Г'){ Лд11а1Л1г11.е(1Е0.В1Л1Т1М, ЮЛ') ; бе1ау (100); } } Запуск 1. Подключите Агйшпо к вашему компьютеру. 2. Запустите сервер. Управляйте встроенным светодиодом через сервер Чос1е.]з Ехргезз. Чтобы включить светодиод: НЮр://0.0.0.0:3000/1еб Чтобы выключить светодиод: ИГГр://0.0.0.0:3000/оТТ
Глава 3. а$упс.]§ Синтаксис • Каждая функция обратного вызова (саШэаск) должна быть написан с использованием следующего синтаксиса: ТопсНоп са11Ьаск(егг, гези11: [, эгд1[, ...]]) • Таким образом, вы обязаны сначала вернуть ошибку и не сможете игнорировать их обработку' в будущем. В отсутствие ошибок принято использовать по11. Са11Ьаск(пи111 туВези1г); • Ваши саПЬаск могут содержать больше аргументов, чем егг и гезоИ, но это полезно только для определенного набора функций (например. ууаГегГаП, зедит. д.). са11Ьаск(по11, туРезиИ, туСизЮтЛгдитепб); • И, конечно, отправляйте ошибки. Вы должны это делать и обрабатывать их (или, по крайней мере, регистрировать). са11Ьаск(ег г); Примеры Параллельное выполнение: многозадачность азупс.раса11е1(1азкз, аГ1егтазкзСа11Ьаск) выполнит набор задач па- раллельно и будет ждать завершения всех задач (что будет отмечено вызовом функции обратного вызова) Когда задачи завершены, азупс вызывает основной саПЬаск со всеми ошибками и результатами задач:
ТипсХюп зНогТТ1шеЕиг1СС1оп(са11Ьаск) { зе1Т1п1еои1:(Типс'11Оп() { са11Ьаск(пи11, ‘ гези1гО+’8ЬогДТ1те’) ; }, 200); } ЕипсГюп тесИип’Т1П1еЕипс1:1оп(са11Ьаск) { зеГ11пеои1:('(:ипс11оп() { са11Ьаск(пи11, ‘ гезиИОТМебхитТдпе’) ; }, 500) ; } ЕипсТюп 1опдТ1теГипс1:1оп(са11Ьаск) { зе1'Т1п1еоиТ('(:ипс'(1оп() { са11Ьаск(пи11, ’ гезиИОТЮадИте ); }, 1000); } азупс.рагаПе! ([ зИоПТттеЕипсИоп, тес! гипТ 1теЕипс11оп, ХотдПтеЕипсДюг ]. ’ Типс1:1оп(егг, гези11з) { 1Т (егг) { геТигп сопзо1е еггог(егг); } сопзо1е.1од(гезиИз); }); Результат: [«гезиИОЕЗНогТПте», «гезиИгСИМесИитПте», «гезиИОЕкопдТхте»]. Вызов азупс.рагаИеЮ с объекто м Вы можете заменить параметр массива задач объектом. В этом случае резуль- таты также будут объектом с теми же ключами, что и задачи. Это очень удобно для выполнения нескольких задач и простого поиска каж дого результата: азупс.рага11е1({ зЬогД: збогтТгпеЕипсИоп, тебюп: тебютТттеЕипстлоп, Тота 1опдГ1пеЕопсХюп }. ' ЕипсТ1оп(егг, гезиНз) {
1Г (егг) { геТигп согзоХе,еггог(егг); } сопзо1е.1од( гезиНз); }); Результат: {зЬогГ: «гезиНОЕЗЬоПТХте», тектит: «гезиИОГМеЛитТхте», 1опд: «гезиИОГ1_опдТ1П1е»} Обработка нескольких значений Каждой параллельной функции передается саНЬаск. Этот свПЬаск может вернуть ошибку в качестве первого аргумента или успешные значения после этого. Если в функцию обратного вызова передано несколько успешны* значе- ний, эти результаты возвращаются в виде массива. азупс.рага11е1({ збот!: ТипсНоп зЬогЕТгпеЕипсИогЦсаИЬаск) { зе1:Т171еои1:('Гипс1:1оп() { са11Ьаск(пи11, ' гези1Х0Е51югтТ1теГ , ' ге5и110Т5ИоПТ1те2’); }, ?00); }, теЛит: ГипсТюп теЛитИтеЕипсЛогЦсаХХЬаск) { зе1:Т1П1еои(:(ТипсГ1оп() { са11Ьаск(пи11, ' гезиХЮГМебтитГпгеГ , ' гезиЛОЕМехатТ 1те2 ') ; }, 500); } }, )ипс11оп(егг, гезиНз) { 11 (егг) { геЕигп согзоХе,еггог(егг); } сопзоХе.1од(гезиХтз); }); Результат: { зЬогХ: [ 1 гезиИОТЗаосСИте!", 1 гезиИОЕЗНогСТтте? ], теЛит: [" гези110ГМеб1итТ11Т|е1 ', гези1гО*МеЛип1Т1те2" ]
Последовательное выполнение: независимый монотаскинг азупс. зег1е8(тазкз, аГтегТазкзСаИоаск) выполнит набор задач. Каждая задача выполняется последовательно одна за другой. Если какая-то задача нс вы- полнится, азупс немедленно прекращает выполнение и переходит к основному саПЬаск. Когда задачи успешно завершены, азупс вызывает «главный» саПЬаск со всеми ошибками и результатами всех задач: Гипскюп зЬог-(:Т1Г1е1-ипс1:1оп(са11Ьаск) { зеСТ1П1еои1:('Гипст1оп() { са11Ьаск(пи11. ' гезоПО'ГВЬогкТтте’); }, 200) ; } ЕипсИоп теб1ип'Т1ГпеЕипс'(:1оп(саПЬаск) { яе1Тппеои1(Типс11оп() { са11Ьаск(пи11, ‘ тезиИОТМескипТипе’); }, 500) ; } ЕипсПоп 1опдТ1теЕипсПоп(са11Ьаск) { зегТ1П1еоо1:('Гипс'(:1оп() { са11Ьаск(пи11. ‘ гези1сОТкопд71те ); }, 1000); } азупс.зег1ез([ тескипПтеЕипскюп, зЬогТТълеЕипсГкоп, 1опдТ1теЕипс11оп кипсЛоп!егг, гезиИз) { 1Т (егг) { гекигп сопзоТе.еггог(егг); } сопзо1е 1од( гезиПз); }); Результат: [«гезиИОЕМескитТипе», «гезиЕ'СО'РЗЬогтТгпе», « гезиИ ОккопдТтше»]. Вызов азупс.зегчсзО с объектом Вы можете заменить параметр массива задач объектом. В этом случае резуль- таты также будут объектом с теьш же ключами, что и задачи. Это очень удобно для выполнения нескольких задач и простого поиска каждого результата. азупс.зег1ез({
збогГ: збоПИтеЕопсНоп, тесИит: тесИитИтеЕипсТтоп 1опд: 1опдТ1теЕипс11оп }, ' Еипс1:1оп(егг, гезиИз) { 1Т (егг) { ге1:игп соп5о1е.еггог(егг); } сопзо1е.1од(ге8иИз); )); Результат: {зНог! : ’гезиХтОГЗЬогтТтте", тескит: гезиИОЕМескитПте", 1опд: " гезиИОТЮпдТипе } Водопад (ууаТегТаП) зависимый монотаскинг азупс.^агегЕа11(1азкз, а-ГТегТазкзСаПЬаск) выполняет набор за- дач. Каждая задача выполняется последовательно, и результат одной задачи передается в следующую задачу Если какая-то задача не выполнится, азупс, как и азупс зегьез (), прекращает выполнение и немедленно вызывает основ- ной саПЬаск. Когда задачи успешно завершены, азупс вызывает «главный» саПЬаск со всеми ошибками и результатами всех задач. ТопсНоп деС11зегРедиезЦса11Ьаск) { // Имитация запроса с помощью тайм-аута 5е1Т1теоиС(ГипсЫоп() { уаг изегРезиИ = { пате: 'Аати’ }; сэ11Ьаск(пи11, изегРезиП), }, 500); } Типсбюп дегбзегЕг1епйзРедиезт(изег, саПЬаск) { // Еще одна имитация запроса с помощью тайм-аута 8егТ1теоиГ(Типс11оп() { уаг ЕгтепбзРезиИ = []; И (изет.пате === Аати') { ГгХепбзРезиП = [{ папе: АИсе }, { папе: Воь' }]; }
са11Ьаск(пи11, ГпепйзЯезсЗл); }, 500); } азупс ла1егГа11([ деСбзегРедиез!:, аеШзегЕгтепсзРедиезГ ГипсГ1оп(егг, гезиИз) { 1Г (егг) { геДигп сопзоГе еггог(егг); ) сопзо1е.1од(Э80М.зГг1пд1Гу(гезиИз)) ; }); Результат: гезиИз содержит второй параметр саНЬаск последней функции водопала йллйегГаП), который в данном случае является Гг1епбзРези1т азупс.йтез (для более удобной обработки циклов) Для выполнения функции в цикле в Кос1е.]8 можно применять цикл (о г для коротких циклов. Но если никл ,длинный, использование Гог может увели- чить время обработки, что может привести к зависанию процесса Мойе. В таких случаях можно задействовать азупс.Птез: ГипсЫоп гесог81УеАстюп(п, саНЬаск) { // Выполните необходимые действия многскоатно са11Ьаск(егг, гезиН); } азупс.Нтез(5, Гипс1юп(п, пех!) { гесигз1уеАсГ:юп(п, Гипс!топ(егг, гезиН) { пех!(егг, гезиИ); }); }, ГипсГ1оп(егг, гезиНз) { // Теперь у нас должно быть 5 результатов }); Это вызывается параллельно Если мы хотим вызывать это по одному за раз, используйте азупс НтезЗегхез, азупс.еасГ) (для эффективной обработки массива данных) Когда мы хотим обработать массив данных, лучше использовать азупс. еасб Когда нужно выполнить что-то с каждым элементом данных и получить оконча- тельный саНЬаск после завершения всех операций, этот метод будет полезен. Это выполняется параллельно.
ГипсФФоп сгеасеизег(изег№п1е, саПЬаск) { // Создание пользователя в базе данных са11Ьаск(пи11); // или ошибка в зависимости от результата создания } уаг аггауОФОаса = ('Нин , '816', 'Тош']; азупс. еасГ1 (а г гауЭТ0а1:а, ФипсТ1оп(еасЫ)зегМап1е, саПЬаск) { // Выполняем операцию для каждого пользователя. сопзо1е.1од(’СгеафФпд изег ' + еасЬОзегМате); // Возврат саПЬаск обязателен. Иначе мы не получим финальный саПЬаск, даже если пропустим один. сгеаФеОзе^еаспизе^апе, саПЬаск); }, Фипс-Поп(егг) { // Если создание любого из пользователей не удалось, может возник- нуть ошибка. 1Ф (егг) { // Одна из итераций вызвала ошибку. // Все дальнейшие процессы будут остановлены. сопзо1е.1сд('ипаЫе Фо сгеаФе изег’); } е!зе { сопзо1е.1од( АП изег сгеаФед зиссеззФиПу1); } }); Если необходимо выполнят!, одно действие за раз, можно использовать азупс,еасЬ8ег1ез. азупс.зепез (для обработки событий по одному) В азупс.зепез все функции выполняются последовательно, и объединен- ные результаты каждой функции передаются в финальный саПЬаск. Например: уаг азупс = геаи!ге(‘азупс’); азупс.зег1ез([ ФипсФюп(са11Ьаск) { сэпзо1е.1сд('ЕФгзф ЕхесиФе..’); са11Ьаск(пи11, 'изегРегзопа1ЭаФа'); }, ФипсФФоп(саПЬаск) { сопзо1е.1од( Весопб ЕхесиФе.. '); са11Ьаск(пи11, 'изегОерепбепЮаФа'); }
+ипс1:1оп(егг, гезиИ) { сопзо1е.1од(гези11); }); Вывод: Е1ГЗХ Ехеси^е. . Зесопс! Ехеси!е.. [ 'изегРегзопаЮага’, 'изегОерепдегтЕСаГа' ] // результат
Глава 4. А$упс/АшаН Введение Азупс/аигай — это набор ключевых слов, позволяющих писать асинхронный код в процедурной манере, без необходимости полагаться на обратные вызовы или цепочки промисов (. тЬеп (). тбеп (). тпеп ()). Это работает за счет использования к.почевого слова алаИ, которое приоста- навливает выполнение асинхронной функции до разрешения промиса, и ключе- вою слова азупс, которое объявляет такие асинхронные функции, возвращаю щие промис. Азупс/аиаИ доступен в Ыос1е.]5 по умолчанию, начиная с версии 8, или в вер- сии 7 при использовании флага --Нагтопу -азупс-алатГ. Примеры Асинхронные функции с обработкой ошибок через иу-са1сН Одной из лучших особенностей синтаксиса азупс/а«а1! является возмож- ность использовать стандартный стиль кодирования с Егу-сагсН, как если бы вы писали синхронный код. сопзД туЕопс = азупс Сгу { сопзГ гезоИ } сабсб (егг) { // обработка } }); (гер, гез) => { = аи/азЛ зотеРготтзе(); ошибок осуществляется здесь Вот пример с использованием Ехргезз и ргогшзе-туЗрЕ: гооТег .дет('/Надз/:1а', азупс (гед, гез) => { Игу { сопзб соппестюп = а«а11 роо1.сгеатеСоппест1оп();
ггу { сопз! зд1 = ’ЗЕЬЕСТ Т.1с1, Т.и/иШт, Т .НехдНХ, Т.собе, ЛТПепате ЕЙОМ Г1адз Т У/НЕРЕ Т.1с1 = ? ИМ1Т 1' ; сопз! Т1адз = а\ча11 соппес1юп.диегу(зд1, гед рагатз. 1с1) ; 1Т (Т1адз. 1епдтп === 0) геТигп гез.зга!из(404),зепс1({ теззаде: 'Т1ад по! ТоипсГ }); гесигп гез.зепб({ Г1адз[0] }); } Т1па11у { роо1.ге1еазеСоппес11оп(соппес11оп); } } са1сК (егг) { // обработка ошибок осуществляется здесь } }); Сравнение Ргогшзез и Азупс/АшаИ Функция, использующая промисы: ТипсЩоп пуАзупсЕипс11Оп() { ге1игп аЕипс11опТЬа1Ке1:игп8АРгот18е() // боЗотеСЫпд - это синхронная функция ,тЬеп( гезиИ => с1с8оггс1±1пд( гезиН)) ,сасс1т(1тапЛеЕггог); } Вот как азупс/аиаИ делает код более чистым: азупс ТипсИоп туАзупсЕипсТ1оп() { 1ег гезиИ; Ггу { гезиИ = аиаИ аЕипсг1опТба‘:йе1:игпзАРгоп118е(); } са!с1т (еггог) { ЬапЛеЕггог(еггог); } // боЗоиеТМпд - это синхронная функция геСигп доЗоп1еСЬ1пд(гези11:); } Ключевое слово азупс можно сравнить с написанием ге1игп пей Ргопнзе( (гезо17е, гедесТ:) => А ала 11 аналогичен получению резуль- тата в обратном вызове 1беп.
Переход от обратных вызовов Вначале мы использовали обратные вызовы, и эго было вполне приемлемо сопз1: деЬТетрегаГиге « (саПЬаск) => { Ьг1р.дес('и/йй.Гепрегасиге.сот/сиггепЬ', (гез) -> { са11Ьаск( гез .с!а1а ЛетрегаЬиге); }); } сопзЬ де1А1гРо11и1юп = (саПЬаск) -> { (пер дес( 'шшш.роПииоп сот/сиггеп!', (гез) -> { саПЬасЦгез.баГа.роПиГюп); }); } деЬ Гетре га1иге(Типс1: юл (гетр) { деьА! гРо11и1 юл (10001:100 (ооИисюп) { сопзоЗе.1од( 1Не Гетр 1з ${1етр) аоб 1_Ье роПоПоо 1з $(рс11и11оо}. ); // ТЬе 1етэ 15 27 аоб 1Ье роПиЫоп 1з 0.5. В; }); Но возникло несколько серьезных проблем, поэтому мы начали использовать промисьг сопзГ деГТетрегаГоге =()=>{ гегого пел Ргот1зе((гезо1уе, ге1ес1) => { ГгЬТр. деТ ( '«то.Гетоегагоге.сот/соггео!', (гез) => { гезо1уе(гез.с!а1:а ГетрегаЬоге) ; }); }); } соозГ деСА1 гРоПипэо =()=>{ геГиго пе« Ргот1зе( (геясПе, ге]ес1) => { ЬПр.де1('^«.ооПисюо.сот/сиггепГ', (гез) -> { гезоКе(гез ЬаГа роПигюо); }); }); } дегТс-трега1иге() .1Ьео(1:етр => соозо1е.1сд( 1пе Гетр 13 ${1етр} )) .1Иео(() => де1А1гРо11иМоо())
,тЬеп(ро11и'11оп -> сопзо1е 1од( 'агд Дбе роПипоп 15 ${рс11игюп}')); // ГПе ±етр 15 32 // апб тЬе роПиНоп 15 0.5 Все стало немного лучше. И, наконец, мы нашли аеупс/амаИ, который по-прежнему использует промисы «под капотом»: сопзД 1ешр = ала1Д де!Тетрега1иге(); сопзД роПиПоп = аи/азД де1А1гс’о11иИоп(); Остановка выполнения на амай Если промис ничего не возвращает, асинхронное задание может быть завер- шено с помощью алаДД: Тгу { алагГ 11зег.'Г1пс1₽.уТс1Апс111рс1а^е(и8ег._1с1, { $ризб: { токегю Гокеп } }) .ехес(); } саТсб (е) { Напс11еЕггог(е); }
Глава 5. Асинхронное программирование Введение Когда мы используем Мойе, все может выполняться асинхронно Ниже вы найдете несколько примеров и типичных аспектов работы в асинхронном ре- жиме. Синтаксис • бо8оте1:Мпд( [агдз], ТипсС1оп( [агдзСВ ]) { /* выполнение действия по завершении */ )); • бо8оте-(:Ь1пд( [агдз], ([агдзСВ]) => { /* выполнение действия по завершении */ }); Примерь! Функции обратного вызова в иауаЗспр! Функции обратного вызова (саПЬаск Гипсйопз) широко распространены в ]ауа8спр(, так как функции в этом языке являются объектами первого класса. Синхронные функции обратного вызова Функции обратного вызова могут быть синхронными или асинхронными. По- скольку асинхронные функции обратного вызова могут быть более сложными, рассмотрим простой пример синхронной функции обратного вызова. // функция, которая использует функцию обратного вызова с именем сЬ в качестве параметра ропсЫоп деТ8упсМе58аде(сЬ) {
сЬ( Не11о Йог1б! ) ; } согзо1е.1од("ВеТоге дебЗупсМеззаде са1Г ); // вызов функции и передача функции обратного Волова в качестве аргу- мента деСЗупсМеззаде(Тцпс1:1оп( теззаде) { сопзо1е.1од(пеззаде); }); сопзо1е.1од("АТ1:ег деСЗупсМеззаде са11 ); Вывод для приведенного выше кода будет следующим: > Вебоге дебЗупсМеззаде са11 > Не11о Л'ог1с1! > АТтег деХЗупсМеззаде са11 Рассмотрим пошагово, как выполняв гея этот код. Это больше для тех, кто еще не знаком с концепцией функций обратного вызова; если вы уже понимаете ее, можете пропустить этот абзац. Сначала код анализируется, затем выполняет- ся строка 6. которая выводит в консоль Ве^оге деТЗупсМеззаде са11. Далее строка 8 вызывает функцию детЗупсМсззаде. передавая анонимную функцию в качестве аргумента для параметра сЬ в функции деТЗупсМеззаде Теперь вы- полнение происходит внутри функции дебЗупсМеззаде на строке 3, где вызы- вается функция сб, которая только что была передана. Этот вызов передает строку «Не11о Йог16» в качестве аргумента для параметра теззаде в передан- ной анонимной функции. Выполнение затем переходит на строку 9, где в кон соль выводится Не Но Йо г 16 ! После этого выполнение проходит через процесс выхода из стека вызовов, достигая строки 10, затем строки 4 и, наконец, возвра- щаясь на строку 11. Вот что нужно знать о функциях обратною вызова в целом: • Функция, которую вы передаете в качестве функции обратного вызова, может быть вызвана ноль, один или несколько раз. Все зависит от реализации. • Функция обратно! овызоваможетбыть вызвана синхронно или асинхронно, а может и одновременно синхронно и асинхронно. • Как и в обычных функциях, имена, которые вы даете параметрам вашей функции, не важны, но порядок важен Например, на строке 8 параметр теззаде мог бы называться зга сетепС, пзд или как-нибудь нелепо вроде ]е11уЬеап. Поэтому вам следует знать, какие параметры передаются в вашу функцию обратного вызова, чтобы получить их в правильном порядке с подходящими именами.
Асинхронные функции обритного вызова Одно из важных замечаний о }а\та8спрГ заключается в том, что этот язык по умолчанию синхронный, но в среде (браузер, Мойедз и т. д.) существуют АР1, которые могут сделать его асинхронным. Перечислим некоторые распространенные вещи в средах |ауа.8спр1, которые принимают функции обратного вызова: • События (ЕуепТз) • зеТИпеоиС • зеПпСегуа! • ТеСсК АР1 • Промисы (Ргоппзез) Также любая функция, использующая одну из вышеуказанных функций, мо- жет быть обернута в функцию, которая принимает функцию обратного вызова, и эта функция обратного вызова тогда станет асинхронной (хотя оборачивание промисов в функцию, принимающую функцию обратного вызова, скорее всего, будет считаться антипаттерном, так как существуют более предпочтительные способы обработки промисов). Владея этой информацией, мы можем построить асинхронную функцию, ана- логичную синхронной. // функция, которая использует функцию обратного вызова с именем сЬ в качестве параметра ГипсЧоп деГАзупсМеззаде(сЬ) { зеСТ1теои1(ТипеСюо () { сЬ("Не11о Иог1сН") }, 1000); } сопзо1е 1од("ВеТоге де18упсМеззаде са11"); // вызов функции и передача функции обратного вызова в качестве аргу- мента де1:АзупсМеззаде(Типс1:1оп (тез заде) { сопзо1е.1од(ггеззаде) ; }); соп8о1е.1од(иАЕСег деСЗупсМеззаде са11 ); В результате в консоль будет выведено: > ВсТоге детЗупсМеззаде са11 > А'ГТег де18упсМеззаде са11 // пауза в 1000 мс без вывода > Не11о Лог 10!
Выполнение переходит к строке 6. выводя ВеТоге деТВулсМеззаде са11. За- тем выполнение переходит к строке 8. вызывая дебАзупсМеззаде с функцией об- ратного вызова для параметра сЬ. Далее выполняется строка 3, которая вызывает зетТт теои (: с функцией обратно! о вызова в качестве первою аргумента и числом 300 в качестве второго аргумента. зе^ТнпеоаТ удерживает эту7 функцию обратно- го вызова, чтобы вызвать ее позже, через 1000 миллисекунд, но после установки тайм аута и до паузы в 1000 миллисекунд он передает выполнение обратно — гуда, где оно было прервано, то есть на строку 4, затем на строку 11. После этого следует пауза в 1 секунду, и затем зегТипеои! вызывает свою функцию обратно- го вызова, что возвращает выполнение к строке 3, где вызывается функция об- ратного вызова деСАзупсМеззаде с аргументом «Не11о У/ог!с!» для ее параметра теззаде, который затем выводится в консоль на строке 9. Функции обратного вызова (саНЬаскя) в Мос1е ]$> Ыо(1е.]я поддерживает асинхронные функции обратного вызова и часто пе- редает два параметра в ваши функции, которые иногда условно называют егг и баба. Приведем пример с чтением текстового файла: сопзб Тз = гедшге( бз ); бз. геабЕ11е("./безб,бхб , обГ8', бопсбзоп(егг, баба) { ±Т(егг) { // обработка ошибки } е1зе { // обработка текста файла, переданного с баба } }); Это пример функции обратного вызова, которая вызывается один раз. Хорошей практикой является обработка ошибки каким-либо образом, даже если вы просто записываете ее в лог или выбрасываете. Конструкция е1зе не обязательна, если вы выбрасываете ошибку или используете гебогп, и ее можно удалить для уменьшения отступов, при условии, что вы прекращаете вы- полнение текущей функции в блоке 16, делая что-то вроде выбрасывания ошиб- ки или возврата. Хотя егг, ба! а — часто встречающийся паттерн, не всегда ваши функции обратного вызова будут использовать его. Лучше всего обращаться к документации. Приведем другой пример функции обратною вызова из библиотеки ехргезз (ехргезз 4.x): // этот фрагмент кода был на Кббр://ехргезз)з.сот/еп/4х/ар1 Шт1 сопзб ехргезз = гедибге('ехргезз’); сопзб арр = ехргезз(); // метод арр.деб принимает 11Р1_-маршрут для отслеживания и функцию об- ратного вызова,
// которая вызывается каждый раз, когда этот маршрут запрашивается пользователем. арр.деХ('/’, Типс1:1оп(гед, гез){ гез.зепсЦ 'ИеПо лог]сГ); }); арр.11з1еп(3000); Этот пример показывает функцию обратного вызова, которая вызывается многократно. Она получает два объекта в качестве параметров, названных здесь гед и гез, эти имена соответствуют запросу и ответу соответственно, и они пре доставляют способы просмотреть входящий запрос и настроить ответ, который будет отправлен пользователю. Существует множество способов использования функций обратного вызова для выполнения синхронного и асинхронного кода в )ага8спрС, и функции обрат- ного вызова широко распространены в этом языке. Пример кода Вопрос: каков вывод кода ниже и почему? зеТТмлеоиЦ Гипс11оп() { сопзо1е.1од( А ); }, 1090); зегТипеои-ЦТипсСюя)) { сэпзо1е.1од("В"); }, 0); деСОасаЕготГ)итаЬазе('ГипсС1оп(егг, баса) { сопзо1е.1од("С ); зеСТд.теои'ЦТипсНолО { сопзо1е.1од('0 ); }, 1000), }); сопзо1е.1од("Е"); Вывод Известно точно: ЕВАО. Неизвестно, когда С будет выведено в лог. Пояснение: компилятор не остановится на зеСИпеооС и методах деСОаСаЕготОэтаЬазе. Поэтому первой будет выведена строка Е. Функции обрат- ного вызова (первый аргумент зеИмпеоиТ) будут выполнены асинхронно после истечения времени, установленного в зет7 нгеоит. Подробнее: 1. Е не имеет зеСТтшеоиС. 2. В имеет зетТ1теоо1: на 0 миллисекунд.
3. А имеет зетТшеост на 1000 миллисекунд. 4. В должна запросить данные из базы данных, и после этого В должна подождать 1000 миллисекунд, поэтому она выполнится после А. 5. С неизвестна, потому что неизвестно, когда данные из базы данных будут запрошены. Это может произойти как до, так и после А. Обработка ошибок в асинхронном коде Ошибки всегда должны обрабатываться. Если вы используете синхронное программирование, можно применить Тгу-саТсИ Но это не работает при асин- хронном программировании! Моп^оозе Ггу { ее1:Т1теои1:(Типс11оп() { 1Ьгс« пел Еггог("Гт ап ипсаодЬТ еггог апб «111 зХор Тбе зегуег!"); }, 100); } сабсС (ех) { сопзо1е,еггог( "Пиз еггог «111 по1 «огк 1п ап азупсбгопсиз зниаИоп: " + ех); } Асинхронные ошибки будут обрабатываться только втгутри функции обрат- ною вызова! Обработчики событий В первых версиях \’обе.]з был доступен обработчик событий: ргосезз ,оп( "11псаидШЕхсер1юп", Типс11оп(егг, дата) { И (егг) { // обработка ошибок } }); у0.8 Домены Внутри домена ошибки обрабатываются через эмиттеры событий. При их ис- пользовании все ошибки, таймеры и методы обратного вызова регистрируются
только внутри домена. При возникновении ошибки генерируется событие ошиб- ки, и приложение не «падает»: Vа^ боташ = геои1ге( боташ ); уаг 01 = ботато.сгеаТеО ; уаг 02 = ОотаАп.сгеате(); 01 . гип(ТипсТ1оп() { 62 .а66(зе!:ТзтеоиТ(Типс1:боп() { СЬгол пел Еггог("еггог оп тбе Итег о!" боташ 2"); }, 0)); }); 61.оп("еггог", ЕипсИоп(егг) { сопзо]е 1од('еггог аГ ботато 1. + егг); }); 62.оп("еггог", Типс11оп(егг) { сопзо1е.1од( еггог аС бсташ 2: + егг); }); СаПЬаск Ье11 «Ад обратных вызовов» (саПЬаск Ье11) (также известный как «пирамида судь- бы» или «эффект бумеранга») возникает, когда вы вкладываете слишком много функций обратного вызова друг в друга. Вот пример чтения файла (в Е56): сопзТ Ез = геди1ге(’Ез’); 1е1 ЕНепате = ’${__01гпате}/туЕ11е.1:х1: ; Ез.ех181з(Е11епэте. еххзТз => { 1Е (ехгзсз) { Ез.зГаТЩХепэте, (егг, зСа(з) => { 1-Е (егг) { гбгол егг; } 1Т (зТаТз.хзРПеО) { Ез.геа6Е11е(Е11епате, пи11, (егг, 6а1а) => { (егг) { ТЬгол егг; } сопзо1е.1од(оага); }); } е1зе { гЬгол пел Еггог('ТЬ1з 1осаЕ1оп сопЕашз по! а Е11е ); ) });
} е1зе { ДЬгот/ пей Еггог("404: Н1е по! -Еоопб ); } }); Как избежать саНЬаск ЬеН Рекомендуется не вкладывать более двух функцтш обратного вызова Это по- может сохранить читаемость кода и упростит его поддержку в будущем. Если вам нужно вложить больше двух функций обратного вызова, попробуйте ис- пользовать распределенные события. Существует также библиотека азупс, которая помогает управлять обративши вызовами и их выполнением. Она улучшает читаемость кода обратных вызовов и дает вам больше контроля над их потоком, включая возможность выполнять их параллельно или последовательно. Нативные Ргопнзе (Промисы) У6 0.0 Промис (Ргот1зе| — это инструмент для асинхронного программирования. В ]ауа8спр1 промисы известны своими методами СЬеп. У промисов, то есть обе- щаний (ргогшзез), есть два основных состояния — «ожидание» (репсЛпд) и «за- вершено» (зегт 1еб). Как только промис становится «завершенным», онне может вернуться ь «ожидание». Это означает, что промисы в основном хороши для со- бытий, которые происходят только один раз. Состояние «завершено» также де- лится на два состояния — «разрешено» (гезоТуеб) и «отклонено» (ге)есГеб). Вы можете создать новый промис, используя ключевое слово пей и передав функ- цию в конструктор пей Ргот1зе(ТипсПоп( сезоне, гедесч:) {}). Функция, переданная в конструктор Ргопнзе, всегда получает первый и вто- рой параметры, обычно называемые гезо1уе и ге] есТ соответственно. Назва- ния этих двух параметров условны, но они переводят ргопнзе либо в «разрешен- ное», либо «отклоненное» состояние. Когда вызывается одна из этих функций, ргопнзе переходит из состояния «ожидания» в «завершено». гезо1уе вызывает- ся, когда желаемое действие, которое часто является асинхронным, было выпол- нено, а ге]есС используется, если действие привело к ошибке. В приведенном ниже примере Схтеоит — это функция, которая возвращает Ргопнзе: ЕопсСтоп ЫтеоиС (тз) { гетигп пет/ РгопнзеСтипсРтоп (гезо1уе, ге]ес1) { зегТхтесиЦТипсСюп () { гезс1уе( II т/аз гезо1тес1!"); }, тз)
)); } 11теои1(1Ое0) .Птеп^ипсИоп (баСаЕготРгопцзе) { // выводит "11 «аз гезо17еб' сопзо1е 1од(баСаРготРгопхзе); }) сопзо1е.1од(' лахПпд.. . ); Вывод в консоль: иатпд . // << пауза на одну секунду » 1Т лаз гезо1уес1! Когда вызывается ТхтеоиС, функция, переданная в конструктор Ргопизе, вы- полняется без задержки. Затем выполняется метод зетТхшеоиС. и его функция об- ратного вызова запланирована на выполнение через тз миллисекунд, в данном случае тз=1000. Поскольку функция обратного вызова зеТТхтеоиб еще не была вызвана, функция бцпеои! возвращает управление вызывающему коду. Цепочка методов бЬеп затем сохраняется для последующего вызова, когда/если Ргопизе будет разрешен. Если бы здесь были методы саТсб, они бы также были сохране- ны, но были бы вызваны, когда/если Ргопизе будет отклонен. Скрипт затем выводит «лахГхпд...». Через секунду зеСТхшеоиС вызывает свою функцию обратного вызова, которая вызывает функштю гезоЕуе со строкой «IС иаз гезо1уеб1». Эта строка затем передается в функцию обратного вызова мето- да Нтеп и выводится пользователю. Точно также, как вы можете обернуть асинхронную функцию зеСТьтеоиС, ко- торая требует функции обратного вызова, вы можете обернуть любое отдельное асинхронное действие с помощью эгопазе.
Глава 6. Автоматическая перезагрузка при изменениях Примеры Автоперезагрузка при изменении исходного кода с использованием пометой Пакет побетоп позволяет автоматически перезагружать вашу программу при изменении любого файла в исходном коде. Установка пометой глобально прт 1пз1а11 -д пометой (или прт 1 -д пометой) Установка по(1етоп локально прт 1пь1а11 --заVе-сIеV побетэп (или прт 1 -0 пойетоп) Использование поЛетоп Запустите вашу программу с побетоп. пометой епСгу.дз (или побетоп епГгу) Это заменяет обычное использование: побе еп1гу.]з (или побе епТгу) Вы также можете добавить запуск побетоп как прт-скрипт, что может быть полезно, если вы хотите передавать параметры и не вводить их каждый раз вручную. Добавьте в раскаде.]зоп:
зсгтртз’: { "з^агЧ : побепоп еп1гу.]з -ОеупоОе -зотеСПхпо 1" } Таким образом, вы сможете просто использовать команду: прт зсагг из вашей консоли. Вгоу/зегзупс Обзор Вголзегзупс — это инструмент, который позволяет следить за изменени- ями файлов в реальном времени и перезагружать браузер. Доступен в виде МРМ-пакета. Установка Чтобы установить Вго^зегзупс, вам сначала нужно установить Мобе.]з и Л РМ. Для получения дополнительной информации см. документацию по уста- новке и запуску ЧоДе.]8 по ссылке ИПрз://г1рШ(опа1.сот/пос1е-)8 или по фК-коду ниже. После того как ваш проект настроен, вы можете установить Вго^зегзупс с по- мощью следующей команды: $ прт ДпзСаН Ьголзег-зупс -О Это установит Вголзегзупс в локальный каталог побе_тоби1ез и сохранит его в ваших зависимостях для разработчиков.
Если вы предпочитаете установить его глобально, используйте флаг -д вме- сто -Б. Пользователи Штдошз Если у вас возникли проблемы с установкой Еголзегзупс на М'шйоууз, вам может потребоваться установить Утзиа! ЗшсПо, чтобы получить доступ к инстру- ментам сборки для установки Вгоизегзупс. Зат ем вам нужно будет указать вер- сию Утзиа! 8Шс11о, которую вы используете, следующим образом: $ прт 1пз1а11 Ьголзег-зупс --тзУ8_уег81оп-2013 -О Эта команда указывает версию Утзиа! ЗШсНо именно 2013 года. Основное использование Чтобы автоматически перезагружать ваш сайт при изменении файла }ауа8спрт в проекте, используйте следующую команду: $ Ьги«зег-8упс зЕагТ --ргоху "турго]ес1 .бе/' --ЕНез "**/*.]$ Замените тур го] ест .с1еу на веб-адрес, который вы используете для доступа к вашему проекту. Вго^зегзупс выдаст альтернативный адрес, который можно использовать для доступа к вашему сайту через прокси. Продвинутое использование Помимо интерфейса командной строки, описанного выше, Вгоизегзупс так же может использоваться с бгопТ. ]з и Си1р. ]з. Сгип1.]8 Для использования с 6гипс. ] з требуется плагин, который можно установить следующим образом: $ прт 1пзта11 дгопт-Ьгоизег-зупс -Э Затем добавьте эту строку в ваш дгоптЕтХе. ]з: дгоп1.1оас1МртТа8кз(' дгопЕ-Ьгоизег-зупс '); Си1р.]8 Вгол'зегзупс работает как модуль СоттопЭЗ, поэтому нет необходимости в плагине для Со1р. ] з. Просто подключите модуль следующим образом: уаг ЬгоизегЗупс = гедотге('Ьго«8ег-зупс’).сгеаСе(); Теперь вы можете использовать АР1 Вголзегзупс для настройки в соответ- ствии с вашими потребностями.
ЛР1 АР1 Вго№ег5упс можно найти здесь Ьпрз^ЪготоегзупслоМосз/ар] или по рК-коду ниже.
Глава 7. Избегайте ада обратных вызовов (саНЬаск Ье11) Примеры Модуль Азупс Исходный код доступен для загрузки с СйНиЬ ио ссылке ИНрз://§й11иЬ.сот/ сао1ап/азупс или по ())Я-коду ниже. Кроме того, вы можете установить его с помощью ИРМ: $ прт 1пз(:аП --зауе азупс ...а также с помощью Воууег: $ Ьоиег 1пз1а11 азупс Мопдоозе уаг азупс = гершге( азупс"); азупс.рага11е1([ <ипсТ1оп(са11Ьаск) { ... }, ТипсНоп) саНЬаск) { . }
], ТипсЫоп(егг, гезиИз) { // необязательная функция обратного вызова }); Еще о модуле Азупс Библиотеки, такие как Лзупс.]з, очень полезны. Азупс добавляет тонкий слой функций поверх вашего кода, что может значительно снизить сложность, избе- гая вложенности функций обратного вызова. В Азупс есть множество вспомога- тельных методов, которые можно использовать в различных ситуациях, таких как зегТез, рага11е1, иасегТаП и другие. Каждая функция имеет свое кон- кретное применение, поэтому уделите время изучению того, какая функция по- может в той или иной ситуации. Как бы ни был хорош Азупс, он не идеален. Очень легко увлечься, комбинируя зегтез, рас а 11е1, *огеуег и другие методы, и в итоге вернуться к исходной точке с неаккуратным кодом. Будьте осторожны и не занимайтесь преждевре- менной оптимизацией. То, что несколько асинхронных задач можно выполнить параллельно, не всегда означает, что это нужно делать. В реальности, посколь- ку Мо(1е.)8 однопоточен, выполнение задач параллельно с использованием Азупс дает незначительное или вообще никакого улучшения производительности. Пример использования Азупс \л/а1ег(а11 уаг Ез = геро1ге('Ез'); уаг азупс = гедо!ге('азупс'); уаг глуПлХе = '/Ттр/ТезГ'; азупс.«асегТа11( [ Типс11оп(са11Ьаск) { Тз. геабЕПеГтуЕПе, ' оТТ8', саПЬаск); }, ГипсНоп^хЕ, саПЬаск) { ТхС = 1хТ + ЛпАррепоеб зотеЫыпд1 ; Гз,«г11:еЕ11е(п1уЕ11е. 1x1, саПЬаск); ) ], ЕипсЫоп (егг гезоП) { 1Т(егг) геТигп сопзо!е.1од(егг); сопзо1е.1од('Аорепбеб 1ех1!'); });
Глава 8. В1иеЫгс1 Ргот!§е§ (промисы) Примеры Преобразование библиотеки подеЬаск в Ргоггнзез сопзТ Ргоп15е = гедь1ге(' ЫиеЬ1гсГ ), Тз = геди!ге('Тз') Ргопнзе.ргот131ТуА11 (Тз) // теперь вы можете использовать методы на основе ргоппзе для 'Тз' с суффиксом Азупс Тз. геас!Е11еАзупс('ТПе.ТхТ '). 1Неп(соп1еп1.з => { сопзоТе. 1од (соп1: епТз) }) ,саТс1т(егг => { сопзоТе.еггог('еггог геас11пд', егг) }) функциональные Ргоггнзез Пример использования тар Ргопнзе.гезо1уе([ 1, 2, 3 ]).тар(е1 => { геТигп Ргопнзе.гезс1ме(е1 * е!) // в реальной ситуации возвращает- ся некоторая асинхронная операция }) Пример использования Е11Лег: Ргопнзе.гезо!ме([ 1, 2, 3 ]).Тт11ег(е1 => { геТигп Ргопнзе.гезо1ме(е1 % 2 === й) // в реальной ситуации возвращается некоторая асинхронная операция }) .ТРеп(сопзо1е.1од)
Пример использования геоисе: Рготхзе. гезо1л'е( [ 1, 2, 3 ]). гебасе((ргеу, сиге) -> { геНигп Рготззе.геео1уе(ргеу + сигг) // в реальной ситуации возвра- щается некоторая асинхронная операция }).1Ьеп(соп8о1е.1од) Корутины (согоихтез) сопат рготхзеРеТигпхпдГипсТхоп = Рготхзе. согоиТхпе (-Гипс-стоп* (ТПс) { сопзТ баСа = ухе!б Гз геабГх1еАзупс(-(:11е) // это возвращает Ргспнзе и разрешается в содержимое файла гегигп баСа.со8сгтпд() .1обррегСазе() }) рготх5еРеСигпхпдЕипст1оп(' ^х1е . СхС ) .ТНег|(со118о1е. 1од) Автоматическое освобождение ресурсов (Ргогшзе из1пд) ЕипсСхоп зоте'(:111пдТ11атКеХитзА015ро8аЫеРезоигсе() { геСигп де-С8оп-.еРеяоигсеАзупс(. . .) .бхзрозег( ге.зоигсе => { гезоигсе.б1зрозе() В } Рготхзе из1пд(8оп’е'СР1пдТЬа'СРе1игпзА018ро5аЫеРезоигсе(), гезоигсе => { // используйте ресурс здесь бтзрсзег автоматически закроет его при выходе из Рготхзе.изхпд }) Последовательное выполнение Рготхзе.гезо17е([1, 2, 3|) ,тар8егхез(е1 => Ргстхзе.гезо1уе(е! * е1)) // в реальном примене- нии используйте асинхронную функцию, возвращающую Рготхзе .1Ьеп(сопзо1е.1од)
Глава 9, Преобразование функций обратного вызова в Ргоггнзез (промисах) Примеры Промисификация функций обратного вызова Использование на основе функций обратного вызова: ЬЬ.попТхсаРхоп ета11 .ЕтпсЦ {зиЬ]ес1:: 'рготхзхТу саПЬаск'}, (еггог, гезиИ) => { 11 (еггог) { сопзо1е.]од(еггог); } // обычный код здесь }); Этот код использует метод рготхзхЕуАП из библиотеки ЫиеЬхгб для пре- образования кода, основанного на функциях обратного вызова, как в приведен- ном выше примере. ЫиеЬт создаст версию с ргоиизе для всех методов в объек- те. и имена этих методов на основе рготхзе бу,тут иметь суффикс Азупс: 1ет етах1 = ЫиеЬхгй.ргоппзх1:уАП(бЬ.по1хГхса1:1ОП.етах1); етаН. Г1пРАзупс(-(зоб^ес! : 'рготхзхТу саПЬаск'}) .гЬеп(гезиИ => { // обычный код здесь }) .сассК(сопзо1е.е'тог); Если необходимо промисифицировагь только определенные методы, исполь- зуйте рготхзхЕу: 1еЕ Тхпс! = ЫиеЬ1гб.эгол11311:у(аЬ.РОГ1Т1са1:1сп .етаН.бДпб); Г1пс1( {ТосаПопИ: 168}) .ТЬеп(гези11 => (
// обычный код здесь }) ,саТсЬ(сопзо1е еггог); Существуют некоторые библиотеки (например Маззке^), которые нельзя нромисифицировать, если объект метода не передан во втором параметре. В та- ком случае просто передайте объект метода, который нужно промисифициро- вать, во втором параметре и заключите его в свойство соптехТ: 1еТ Т1пб = ЫоеЫгб .ргот131Ту(бЬ.поГ1Т1саТ1оп.ета11.Т1пб, { сопТехТ: бЬ.потХТХсаГюп.егпаН }); НпЩ{1осаИопТб: 168}) ЛКеп(гези1т => { // обычный код здесь }) .сассЬ(сопзо!е еггог); Ручная промисификация функции обратного вызова Иногда может потребоваться вручную нромисифицировать функцию обрат- ного вызова. Это может быть необходимо в случае, когда она не следует стан- дартному формату «функция обратного вызова с первым аргументом- ошибкой» (еггог Нге! саНЬаск) или если требуется дополнительная логика для промисифи- капии. Пример с Тз.ех1зТз(ра1Ь, саНЬаск): уаг Тз = геди!ге('Тз’); уаг ехтзТзАзупс = Типс110п(ра1Ь) { геТигп пел Ргоп1зе(Типс1юп(гезо1уе, гедесТ) { Тз.ех1з1з(ра1Ь, Типс(:10п(ех1зТ8) { // ехгзТз - это булево значение 1Т (ех18Тз) { // Успешное разрешение геяо1уе(); } е!зе { // Отклонение с ошибкой ге]'есТ(пей Ег>"ог('раТЬ Ооез по! ехтзТ')); } }}; }); }; // Теперь используйте как ргоппзе ех18ТзАзупс('/раТЬ/То/зоте/ТНе’).ТЬеп(ТипсТ1Оп() {
сопзо1е.1од( Г11е ехгзгз!'); }) .сагсгИТипсЁюгЯегг) { // файл не существует сопзо1е.еггог(егг); }); Промисификация зеГЛтеоиХ ^ипсИоп иа1т(п,з) { ге1итп пей Ргопизе (ТипсИоп (гезо1уе, ге]ес1) { зеГТ1теси1:(гезоКе, гез) }) }
Глава 10. Интеграция с Саззапска Примеры Не11о ^7огИ Для доступа к Саззапйта можно использовать модуль саззапдгэ-йпуег от ВаСаЗГах. Он поддерживает все функции и легко настраивается. Модуль саззапс1га-с1г1Уег доступен на СдШиЬ по ссылке Ьггря://§пЬоЬ.сот/ с1аГазГах/пос1е]8-(1пгет. Также его можно скачать по р К-коду ниже. сопзТ саззапс1га = герь1ге( са5запс1^•а-(^г^Vе^ , ); сопзТ сИепТОрПопз = { сопсасТРоюТз: ["ЬозП", Нозс2 ], кеузрасе: ТезТ' }; сопя! с11епГ = пел саззапс1га С11еп1(с11епТ0рТ1опз); сопя! диегу = 8Е1_ЕСТ РеПо ЕРСМ йог1С ИНЕРЕ пагге = ? ;
с11епТ.ехесиге(диегу, [ _1оНп"], (егг, гезиЗЛз) -> { 1Г (егг) { // Вывод ошибки в консоль гетит сопзо1е.еггог(егг); } // Вывод строк результата в консоль соп5о1е.1од(гези1тз.гоиз); });
Глава 11. Интерфейс командной строки (СИ) Синтаксис • пос!е [орИопз] [ у8 орПопз] [всг1рС ]з | -е ' зспр!"] [агдитепХз] Примеры Опции командной строки -V, --уегзюп Добавлено в \г0.1.3 Вывод версии Мос1е.]8. -В, --Ве1р Добавлено в у0.1 .3 Вывод опций командной строки Мо<1е.]8. Вывод данной опции менее детали- зирован, чем этот документ. -е, --еуа! зсгхрт Добавлено в тО.5.2 Выполняет следующий аргумент как )ауа5спр1. Модули, которые предопреде лены в КГ.РЬ, также могут быть использованы в скрипте. -р, --ргхпТ зсг!р1' Добавлено в уО.6.4 Идентично -е, по выводит результат. -с, --сВеск Добавлено в у5.0,0 Проверяет синтаксис скрипта без выполнения.
- 1, --1птегасТ]>е Добавлено в \ 0.7.7 Открывает ВЕРЬ. даже если зГб ьп не выглядит как терминал. - г, --гедсиге 1госи1е Добавлено в У1.6.0 Предварительная загрузка указанного модуля при запуске. Следует правилам разрешетшя модулей геди!ге(). Модуль может быть либо путем к файлу, либо именем модуля Койе.)8. --по-бергесаИоп Добавлено в у0.8.0 Отключение предупреждений об устаревших (депрецированных) функциях. - -1 гасе-бергесагюп Добавлено в у0.8.0 Вывод трассировок стека для предупреждений об устаревших функциях. - - 111го1«- Оергесатюп Добавлено в у0.11.14 Вызов ошибок для устаревших функций. --по-иагпХпдз Добавлено в уб.0.0 Отключение всех предупреждений обработки (в том числе об устаревших функциях). - -Тгасе-«агп1пдз Добавлено в уб.0.0 Вывод трассировок стека для предупреждений обработки (в том числе об уста- ревших функциях). --1гасе-5упс-1о Добавлено в у2.1.0 Выводит трассировку стека при обнаружении синхронного ввода-вывода по- сле первого выполнения цикла событий. --/его-НП-ЬоНегз Добавлено в уб.0.0 Автоматическое заполнение ну.тями всех вновь выделенных экземпляров ВиГГег и ЗЕоиВиКег.
--ргезег7е-зуш11пкз Добавлено в уб.З.О Указывает загрузчику модулей сохранять символические ссылки при разре- шении и кешировании модулей. По умолчанию, когда Кос1е.]8 загружает модуль из пути, который символиче- ски ссылается на другое местоположение на диске, Кобедз будет разыменовы- вать ссылку и использовать фактический «настоящий путь» модуля па диске как идентификатор и как корневой путь для поиска других зависимых модулей. В большинстве случаев такое поведение по умолчанию является приемлемым. Однако при использовании символически связанных зависимостей, как пока- зано в примере ниже, поведение по умолчанию вызывает исключение, если тобиХеА пытается подключить тобиХеВ как зависимость: {аррОтг} I—арр | |—1пбех.]з | 1—побе_тос1и]е5> | |—тобиХеА -> {аррОа г}/гроОи1еА | 1— тос1и1еВ | |—1пс1ех.]з | 1—раскаде.]3оп 1— то0и1еА |— 1пс1ех. ]8 1— раскаде.]зоп Флаг командной строки --ргезегуе-зутИпкз указывает МойеДн использо- вать путь символической ссылки для модулей вместо реального пути, что позво- ляет найти символически связанные зависимости. Однако использование --ргезегуе-зутХхпкз может иметь побочные эффек- ты. П частности, символически связанные нативные модули могут не загрузить- ся, если они связаны из более чем одною места в дереве зависимостей (Кобе. ]8 воспримет их как два отдельных модуля и попытается загрузить модуль не- сколько раз, что вызовет исключение): --Щаск-Неар-оодесСз Добавлено в У2.4.0 Отслеживание выделений объектов кучи (йеар) для снимков кучи. --ргоТ-ргосезз Добавлено в гб.0.0 Обработка выходных данных профилировщика у8, сгенерированных с ис- пользованием опции у8 - - ргоГ.
--у8-ор41оп$ Добавлено в т 0.1.3 Вывод опций командной строки \т8 Примечание: опции м8 допускают разделение слов как дефисами (-), так и под- черкиваниями (_). Например, --зДаск-тгаое-Иппт эквивалентен --здаск. 4гасе_11т11. --118-с1рЬег-1131=118Г Добавлено в У4.0.0 Указание альтернативного списка шифров ТЬ8 по умолчанию (требует сборки Н обе.]'з с поддержкой криптографии (по умолчанию)). --епаЫе-Тгрз Добавлено в уб.0.0 Включение криптографии, соответствующей стандарту Е1Р8, при запуске (требует сборки Ыо<1е.]8 с ./сопЕтдиге --орепзз1-Г1рз). --Тогсе-Нрз Добавлено в уб.0.0 Принудительное включение криптографии, соответствующей с гандар ту Г1Р8, при запуске (невозможно отключить из скрипта). (Те же требования, что и для --епаЫе-Г 1рз). --1си-баТа-б1г=1:11е Добавлено в дО.11.15 Указание пути загрузки данных 1СП (переопределяет ЬЮГ)Е_1СП_ПАТА). Переменные окружения М00Е_0ЕВ11Б=пюс1и1е[, _] Добавлено в уО.1.32 ‘/-разделенный список основных модулей, которые должны выводить отла дочную информацию. МОРЕ .РАТН=ра1Ь[:_] Добавлено в уО.1.32 ‘/-разделенный список директорий (папок), которые добавляются к пути по иска мо,дулей. Примечание: в Шптскжз это ‘/-разделенный список. М00Е_018АВ1_Е_С01_0Н5=1 Добавлено в уО.З 0 Когда установлено в 1, цвета не будут использоваться в КЕРЬ.
№ОЕ_1Си_ОАТА=Г11е Добавлено в мО.11.15 Путь к данным 1СП (объект 1п(1). Расширяет встроенные данные при компиля- ции с поддержкой малого 1СИ: 1Ч00Е.КЕР1__Н18Т0КУ=Ше Добавлено в мЗ.О.О Путь к файлу, используемом}7 для сохранения истории ЙЕРЬ. Путь по умолча- нию ----/ поае_гео1_И1згогу, который может быть переопределен этой пере- менной. Установка значения в пустую строку ("" или "") отключает постоянную историю ЙЕРЕ.
Глава 12. Взаимодействие «клиент — сервер» Примеры Использование с Ехргезз, )Оиегу апс! иа<1е //с11еп1.]абе // Кнопка размещена внизу; аналогично НТМ1 Ьи^Еоп(1уое= оиГГоп , ю='зепб_Ьу_оиКоп') МобгГу ба!а #тоб1Гу Ьогеп 1рзит Зепбег // Подключение ]0аегу; также можно сделать это из онлайн-источника зсг1р1(згс='./]з/]днегу-2.2.0.Ш1п,]8') // АбАХ-запрос с использованием ]0иегу $сггр1 $(Гипс11оп () { $('#8епб_Ьу_Ьи1:Гоп') .с11ск(ТипсГ1оп (е) { е.ргеуепЮе-Гаи1Г(); // тест, текст в скобках должен появляться при клике на кнопку //1Л1пбо«.а1ег1:('Уои сИскеб оп те. - дОиегу ’) ; // переменная и 6804 инициализированы а коде уаг ргеаес1агеб = КаГатогх"; уаг баИа = { Т1Г1е: "Мапе..8епбегТезГ", Ихск: ргеаес1агеб, Ет.гБ'ЬМате: 7о1Тап", Зигпапе: 'ЗсЬтхб!" }; // АбАХ-запрос с указанными параметрами
$.а]ах({ туре: ‘Р08Т', дата РЗОМ.зТг!пд1Ту(ааГа), сопбепТТуре: 1 аррНсабюп/] зоп', иг1: ' Ьббр: / /1оса1По5Т : 7776/С1ота1п1:ез1', // при успешном выполнении полученные данные ис- пользуются в качестве входных данных функции ' баба зьссезз: Типсбюп (Фага) { л1пбой.а1егб('Аедиезб зепб; са1а гесебуеб.'); уаг дзопзбг = бЗОМ.збппдИу^аба); уаг ]зопоЬ] = 68Э1< рагзе(ззопзбг), // если элемент 68СМ 'М1ск’ не равен предопре- деленной строке (как было инициализировано), то // скрипт Ьаскепб был выполнен, что означает, что связь была установлена 1Е(с1аба Ч1ск != ргес!ес1агей){ боситепб.дебЕ1етепбВу1с1( "тосНТу ) .бппегНТМб = 1680М сМапдей!\п + дзопзбг; }; } }); }); }); уаг ехргезз = гедтге( ехргезз'); уаг гоиТег = ехргезз.Роибег(); // Маршрут Ехргезз, прослушивающий СЕТ-запросы - в данном случае он пуст, а это означает, что ничего не отображается при обращении к '1оса11юзт/с1ота1псезг’ гоибег деб( /’, бипсбюп(гед. гез, пехб) { }); // То же самое для РОЗТ-запр^ссв - обратите внимание, что АЗАХ-запрос выше был опоеделен как Г-05Т гоитег. розХ('/', Типсб1оп( гед, гез) { гез.зебНеаДег('Сопбепб-Туре', 'аррИсаббоп/дзоп'); // сгенериоованное содержимое уаг зогсе_]8оп = { Т1б1е: "Тезб",
1сет: 'Сгаге }; уаг гезиИ = ч)80М.з1.г1пд1Ту(8оте_]8оп); // содержимое, переданное 'с11еп1.]абе’ уаг зепг.йага = гедЬсйу; зеп1_с!а1:а М1ск = "ггопуЗЗ"; ге8.8епд(8еп1_да-(:э); }); тоаиТе.ехрогтз = гоиГег;
Глава 13. Модуль С1и81ег Синтаксис • сопзС с1озТег = гедо!ге( с1оз1:ег") • с1оз1:ег ^огк() • с1оз!ег 1зМаз1ег • с1изГег.1зИогкег • с1оз1ег.8с1теби11пдРо]1су • с1из1ег.зе1ирМаз1ег(зе'(:1:1Г1дз) • с1из1ег.зе(Л1пд8 • сТизСег.иогкег // в люгкег • сТизтег логкегз // в глазтег Примечания Обратите внимание, что сТизТег.^огкО по- рождает дочерний процесс, который начинает выполнение текущего скрипта с начала, в отли- чие от системного вызова Тогк() в языке С, кото- рый клонирует текущий процесс и продолжает выполнение с инструкции после системного вы- зова как в родительском, так и в дочернем про- цессе. Более полное руководство по кластерам мож- но найти в документации Мойедз по ссылке Нирз://пос1с]8.огр'/ар1/с1и8Гег.1Пт1 или по рК-коду справа.
Примеры Не11о №огШ Это вашс1азтег. )з: сопз1 с1из1:ег = геди!ге('с1из1:ег'); сопзТ Ытр = гецыге('ПСТр') ; сопат питСРОв = геди1ге('сз').сриз().1епд1Ь; 1Т (с1изТег.1зМазсег) { // Порождаем рабочие процессы. ^ог (1е"С 1 = 0, 1 < питСРИз; 1++) { с1изТег.Тогк() ; } с1изТег.оп('ех1Г' , (логкег, собе, збдпа!) => { сопзо1е.1од( тегкег ${иогкег.ргосезз.р1б) бхес! ); }); } е1зе { // Рабочие процессы могут использовать любое ТСР-соединение // В данном случае это НТТР-сервер гедо1ге(1./зег7ег.]з')() ; Это ваш основной зегмег.]з: сопя! ЫТр = геди!ге(’КСТр’); ТипсИоп зТагТ5егуег() { сопзТ зегуег = ЬтСр.сгеагеЗегмегЦгед, гез) => { гез.иг11еНеаб(200); гез.епсЦ 'Не11о Н11р ); }); зегуег.11зХсп(3000); 1Г (1 шоби1е.рагепС) { // Запускаем сервер, если файл запущен напрямую вТа г1:8ег ме г (); } е!зе { // Экспортируем сервер, если файл подключается через с1изСег тобиТе ехрэгтз = зТагТЗегуег; В этом примере мы хостим базовый веб-сервер, однако запускаем рабочие (дочерние) процессы с использованием встроешюго модуля с1изтег. Количе- ство порожденных процессов зависит от количества доступных ядер процессо- ра. Это позволяет приложению К'о(1е.]з использовать многопроцессорные систе- мы, поскольку один экземпляр Кобе.)з работает в одном потоке. Приложение
будет использовать порт 8000 одновременно для всех процессов. Нагрузка авто- матически распределяется между рабочими процессами по методу Коипб КоЬт по умолчанию. Пример кластера Один экземпляр Мос1е.)8 работает в одном потоке. Чтобы использовать преи- мущества многопроцессорных систем, приложение может быть запущено в кла- стере процессов Мойедз для обработки натрузки. Модуль с1изТег позволяет легко создавать дочерние процессы, которые все разделяют серверные порты. Следующий пример создает дочерний рабочий процесс в основном процессе, который распределяет нагрузку между несколькими ядрами. Пример сопзС сТизСег = гедит.ге('с]изТег’); сопзб Ыср = гедшге( 'НтСр'); сопзб питСР1)з = гедихге( 'оз') ,сриз().ТепдтЬ; // количество СР1) 1Т (с1из1ег.хзМаз1ег) { // Порождаем рабочие процессы. Тог (уаг 1=0; 1 < пошСРиз’ х++) { с1изТег.богк(); // создание дочернего процесса } // пои завершении оаботы кластера с1избег.оп( еххТ’, (л’огкег, сойе, зхдпа1) => { хТ (з!дпа1) { сопзо1е.1од( тогкег иаз кх11еб Ьу зхдпа1: ${зхдпэ1} ); } е1зе хТ (сосе !== 0) { сопзо1е.1од(‘«огкег еххТеб «хСб еггог сойе: ${собе} ); } е1зе { сопзо1е.1од('тогкег зоссезз!’); } }); } е1зе { // Рабочие процессы могут использовать любое ТСР-соединение // Б данном случае это НТТР-сервер КС1р.сгеаСе8егуег((гед, гез) -> { гез .у/гхСеНеаб( 200) ; гез.епЩ 'Гте11о тог1с!\п’) ; }). 1хзСеп(ЗЭ00); }
Глава 14. Подключение к МопдоОВ Введение Моп^оВВ - это бесплатная кросс- платформенная документно ориентирован ная база данных с открытым исходным кодом. Классифицируемая как база дан- ных Ыо^Ь, МопдоВВ использует документы, похожие на ]8ОК, со схемами. Для получения более подробной информации перейдите на официальный сайт Моп§о1)В по ссылке йПрзэДуите.топйобЬ.сот/ или по (^К-коду ниже. Синтаксис МопдоСИегЛ. . соппес! ('топдсбо: //127.0.0.1 :27017/сгоб’, ТипсПоп (егг, аь) { // действия здесь }); Примеры Простой пример подключения к МопдоОВ из Модема МопдоС11еп1.соппес1:( 'топдсбЬ: //1оса1боз1: :27017/туМе«ОВ', (егг, 6Ь) { ГипсС1оп
1Т (егг) оопзо!е. 1сд('ипаЫе Со соппесС ОВ. Еггог. + егг) е!зе сопзо1е.1сд( 'СоппесСеб То ОБ'); дЬ.с1озе(); }); туМе^ОВ — это имя базы данных. Если она не существует, то будет автомати- чески создана этим вызовом. Простей способ подключения к МопдоОВ с использованием чистого Моде .)5 уаг МопдоСИепС = геди!ге( 'топдосЮ’) .МопдоСИепС; // подключение к МопдоОВ МопдоС11епС .соппесС ("топдос1Ь . //1оса1Ноз С:27017/МуОЬ", ЕипсТзоп (егг, аЬ) { // поовеока соединения 1Г (егг) { сопзо1е. 1од( "соппесТюп Га11ес1.") ; } е!зе { сопзо1е. 1од( 'зиссезз+иПу соппесСес! то (гопдоОЗ.'); } });
Глава 15. Создание библиотеки Ыос1е.]8, поддерживающей как Ргот1зе8| так и функции обратного вызова с первым аргументом-ошибкой Введение Многим нравится работать с синтаксисом ргопизе и/или азупс/аиаП:, но при написании модуля полезно поддерживать также классический стиль ме- тодов с обратными вызовами (саПЬаск). Вместо создания двух модулей или двух наборов функций, либо использования ргопизтТу, ваш модуль может поддер- живать оба способа программирования, используя азСа11Ьаск() из библиотеки В1оеЫ гб или побетТуО из библиогеки 0. Примеры Пример модуля и соответствующей программы с использованием Г 1иеЬ1гс1 таОДз: 'изе зтсГ'; сопзТ: Ргопизе = герь1ге(' ЫиеЫгб'); тоаиТе.ехрогХз = { // пример метода, работающего только с обратными вызовами (саПЬаск) саПЬаскЗогс: Типс1иоп(а, Ь, саПЬаск) { 1Т (ТуреоТ а !== 'потЬег ’) геХигп са11Ьаск(пей Еггог('"а‘ тозт Ье а питЬег')); 1Т (1:уреоТ Ь !== 'питЬег’) ге!ит са11Ьаск(пеи Еггог(' Ь тизГ: Ье а питЬег')); гегигп са11Ьаск(пи11, а + Ь); }.
// пример метода, работающего только с промисами (ргоппзез) рготтзеЗиш: Типс11оп(а, Ь) { геДигп пей Ргопнзе(Типс1:1оп(гезоЬе, гезест) { 1Т (ЬуреоТ а !== 'питЬег') ге1:игп ге]ес!(пей Еггог(" а1 тизД Ье а питЬег’)); 1Т (ТуреоГ Ь !== пипЬег') ге1игп ге)ес1(пей Еггог(1'Ь1 тизг Ье а питЬег’)); гезоКе(а + Ь) ; }); }, // метод, который можно использовать как с промисами (рготгзез), так и с обратными вызовами (саНЬаск) зшп: ?ипс1:1оп(а, Ь, саНЬаск) { геДигп пел Ргопнзе(Типс1юп(гезоКе, ге]ес1) { 1Т (туреоТ а !== 'питЬег') геЬигп ге]есТ(пей Еггог(' а' тиз! Ье а питЬег’)); 1Т (ЬуреоТ Ь !== ‘питЬег’) гебигп ге]еси(пей Еггог("Ь’ тизс Ье а питЬег')); гезо1уе(а + Ь); }) .азСа11Ьгск(са11Ьаск); }, }; шйехдз: 'изе згг1сТ'; сопзТ тасЬ = гери!ге(' ./табЬ’); // классические обратные вызовы (саПЬаскз) та1И,са11Ьаск8ит(1, 3, ТипсЬюп(егг, гезиИ) { 1Т (егг) сопзо1е.1од('Тез! 1: ’ + егг); е1зе сопзо1е.1сд( 'Тез! 1: 11те апзйег 1з + гези1Т); }); таЬН ,са11Ьаск8ит(1, 'сГ, (ипст1оп(егг, гезиН) { 1Г (егг) сопзо1е 1од(‘ТезТ 2: + егг); е1зе сопзо1е.1од('Тез! 2: ЬЬе апзйег 1з ' + гезиН); }); // промисы (ргопнзез) таТП.ргО(тизе8ит(2, 5)
.гЬеп(Гипс11сп(гезиХ(:) { сопзоХе.Ход('Тез! 3: }) .са1сЬ(Хипс1юп(егг) { сопзо1е.Ход('Тезе 3 : }); ХЬе апзлег егг); 13 ' + гезиХХ); лаСИ.ргот1зеЗит( 1) .1Ьеп(1:ипс110п(ге8иХ1) { сопзоХе.Ход('ТезТ 4: 1Ье апзлег 13 гезиХХ); }) ,са1:сЬ(Гипс1:1оп(егг) { сопзоХе.1од('ТезХ 4: }); // метод, использующийся как егг); промис (рготХзе) та1Ь.зит(8, 2) ЛЬеп(ГипсХ1оп(гезиХХ) { сопзоХе.Ход('Тез! 5: 1Ье апзлег 13 ‘ ' + гезиХХ); }) .са1сИ(Хипс1:Хоп(егг) { сопзоХе.Ход('ХезХ 5: }); ' + егг); // метод, использующийся с обратными вызовами (саПЬаск) .лаЮ.8ош(7, 11, ТипсЫоп^гг, гезиХх) { 1Т (егг) сопзо]е.Ход('Тез! 6: ' + егг); с1зе сопзоХе 1од( 'Тез! 6: ЬЬе апзлег 1з ' + гезиХХ); }); // метод, использующийся как промис (ргопизе) с синтаксисом азупс/ат/аП (азупс () => { 1гу { Хет х = алан татЬ зит(6, 3); сопзо!е 1од('Тез1 7а: ' + х); ХеХ у = алахХ та С И зит(4, з'); соп8с1е.1од('Тезе 7Ь: + у); } са1сИ(егг) { сопзо1е.1од(егг.П1еззаде); } })();
Глава 16. Создание АР1 с помощью Мойере Примеры (ЗЕТ АР1 с использованием Ехргезз АР1 на Мобедз можно легко создавать с помощью веб фреймворка Ехргезз. Сле- дующий пример создает простой СЕТ АР1 для вывода списка всех пользователей. Пример уаг ехргезз = геди!ге('ехргезз'); уаг зрр = ехргезз(); уаг озегз = [ { 1с1. 1, пате: ЭоЬп Сое', аде : 23, ета11: ]о1ч"1®бое.сопГ }1; // СЕТ /арЕ/озегз арр.деЕ( '/ар1/озегз ', Еипс1:1оп(гед, гез){ геСогп гез.]зоп(озегз); // вернуть ответ в фермате Э80М }); арр.11зтеп(‘3000’, Еипс*:1оп(){ сопзо!е ,1од('Зегуег Зтзсептпд оп рог! 3000’); }); РОСТ АР1 с использованием Ехргезз Следующий пример создает Р08Т АР1 с использованием Ехргезз. Этот пример аналогичен примеру СЕТ, за исключением использования Ьобу-рэгзег, который разбирает данные РС8Т-запроса и добавляет их в гед. ЬоОу.
Пример уаг ехргезз = геди1ге(' ехргезз ); уаг арр = ехргезз(); // для разбора тела запроса в Р05Т-запрссах уаг ЬобуРагзег = геди!ге( ‘ЬосЗу-рагзег ’); уаг изегз = [{ 1с1: 1, пате- 1 ЗоИп Оое , аде' 23, етз11: "зобп^бое.сст" }]; арр. изе(Ьос1уРагзег иг1епссбеб({ ехЕепбеб ' Та1зе })); арр .изе(Ьос1уРаг$ег. )зоп()); // СЕТ /ар1/изегз арр.де(.('/ар1/изегз , Типсг1оп(гео, гез) { геЕигп гез.]зоп(изегз); // вернуть список пользователей в форма- те 380М }); /* Р08Т /ар1/изегз { "изег : { '16 : 3, 'пате : ' ТезТ: Ьзег , аде : 20. етаН": "ЬезОёчези.соп" } } */ арр.роз1(‘/ар1/изегз’, ГипсГюп(гед, гез) { уаг изег = гед. Ьобу,изег; изегз.ризП(изег); // добавить пользователя в список ге1игп гез.зепс!( 'изег Наз Ьееп айбеб зиссеззТиПу ’); // вернуто со- общение об успешном добавлении }); арр.11з1еп('3000', Гипс11сп() { сопзо1е.1од('Зегуег 1131:еп1пд оп рогг 3000 ); // сообщение о запу- ске сервера на порту 3000 }):
Глава 17. Парсер С8У в 1Чос1е.]$ Введение Чтение данных из С8У может быть выполнено различными способами. Одно из решений — это считать С8У-файл в массив После этого можно работать с мас- сивом. Примеры Использование Е5 для чтения 087 Тз эго ЛРТ файловой системы в Мос1е.]8. Мы можем использовать метод геабРИе на нашей переменной Тз, передав ему файл ОаТа.сзу, формат и функ цию. которые читают и разбивают С8У для дальнейшей обработки. Это предполаг ает наличие файла йата.сзу в той же папке. 'азе зТг1сТ’ сопзг Тз = гери1ге('Тз'); Тз. геабЕ11е('баТа .сзу , 'иТТ8 ТипсТюп (егг, баба) { уаг баТаАггау = ОаТа. зрИТ(/\г?\п/); сопзо!е.1од(баТаАггау); }); Теперь вы можете использовать этот массив как любой другой
Глава 18. Работа с базой данных (МопдоОВ с Мопдоозе) Примерь! Подключение Мопдоозе Убедитесь, что МопдоОВ запущен: топдоО -ОРраТП Раса/. раскаде.)зоп берепбепсхез : { "топдоозе": А4.5.5 } зепгегдз (ЕСМА 6) ХтрогХ топдоозе Ггот 'топдоозе’; топдоозе.соппес!(’топдойР;//ХосаХЬозС:2701 7/зСаскоуегГХои-ехапрХе ); сопзб с!Ь = топдоозе. соппесбюп; бЬ.оп('еггог , сопзоХе. еггог ,Ь1пс1(сопзсХе, 'ОВ соппесТюп еггог!')); // обработка ошибки подключения к БД зеп/ег.]8 (ЕСМА 5.1) уаг топдоозе = гедо1ге('топдоозе’); топдоозе,соппесб(’топдойР ‘//ХосаХЬозб:2701 7/зСаскоуегТ1ои-ехапрХе'); уаг бЬ = топдоозе.соппесГюп; с1Ь оп( еггог’, сопзоХе. еггог ,Р1пб(сопзс1е, ' ОВ соппесХюп ег^ог! ’)) ; // обработка ошибки подключения к БД Модель Определите свою модель (или модели): арр/тос(е18/и8ег.]5 (ЕСМА 6) 1трогХ топдоозе (тот 'топдоозе'; сопзб озегЗсПета = пей топдоозе. ЗсПета ({
пате: 5сг1пд, раззиогб: 8Сппд }); сопзТ Озег = топдоозе тобеЦ'11зег', изегЗсЬета); ехрогТ бе!аи11: Кзег; арр/тойеЕизегдз (ЕСМА 5.1) уаг топдоозе = геди1ге( топдоозе'); уаг изегЗсРета = пей топдоозе .8сГ1ета( { пате: Зтг1пд, раззмогб: 81ппд }); уаг 1)$ег = топдоозе.тобе1('Ьзег', изегЗсКета); тоби1е.ехрог1з = изег; чставка данных ЕСМА 6: сопзС изег = пел 1)зег({ пате: '8Гаск', раззтогб: ОуегНою’ }); изег.зауе((егг) => { 11 (егг) тНгол егг; сэпзо1е.1од('Ьзег зауеб1'); // сообщение о сохранении пользователя }); ЕСМА 5.1: уаг изег = пей 1)зег({ пате: 'Зсаск' раззтогб: 'ОуегНок' }); изег.5ауе(ГипсС1оп (егг) { 11 (егг) ХЬгол егг; сопзо1е.1од('Озег зауеб1 ); }); Чтение данных ЕСМА 6. 1|зег.Т1пб0пе( ( пате: 'зТаск'
}, (егг, изег) => { 1Т (егг) -СЬгол егг; 1Т (!ияег) { сопзо1е.1од('Мс изег лаз ^оипсГ); } е1зе { сопзо1е.1од( изег лаз ГоипсГ); } }); ЕСМА5.1: Озег ,Т1.пс10пе( { пате: 'з1аск' }, ГипсНоп (егг, изег) { 1Т (егг) гол егг; 1Т (! изег) { сопзо1е.1од( Мс изег лаз ГоипсГ ); } е!зе { сопзо1е.1од( изег лаз ГоипсГ ); } });
Глава 19. Отладка Мос1е.]8-приложения Встроенный отладчик Моде.]'з и поде 1пзрес1ог Использование встроенного отладчика \ойе.]ь предоставляет встроенную неграфическую утилиту для отладки. Что- бы запустить встроенный отладчик, запустите приложение с этой командой: побе беЬид ТИепате.дз Рассмотрим следующий простой Мобедз-скрипт. содержащийся ь файле беЬцдОето.]з: 'изе зТгтсТ’; ТипсИоп ас1с1Т«оМитЬег(а, Ь){ // функция возвращает сумму двух чисел беЬиддег ге1игп а + Ь; } Vа^ гезиИ = ас!с1ТууоМитЬег( 5, 9); сопзо1е 1од( гезиИ); Ключевое слово ОеЬиддег остановит выполнение кода в отладчике на этой строке. Команды отгадки 1 Шаги по коду сопЩ с - Продолжить Восполнение пехЩ п - Перейти на следующую строку З1ер, з - Войти в функцию оиТ, о - Выйти из функции
2 . Точки останова 5е1Вгеакро1пт(), зЬ() - Установить точку останова на текущей строке зе^ВгеакроитЦИпе), зЬ(11пе) - Установить точку останова на опреде- ленной строке Чтобы отладить код, выполните следующую команду: поре беРод ПеРодОетю.]з После запуска команды вы увидите следующий вывод. Чтобы выйти из шт- терфейса отладчика, введите р госезз. ехК (). апкигапап<1:~/ыогк5расе/по<1е35/по<1е]$ОеЬи(ц;1пв $ поде деЬив двЬиДОето.3$ < ОеЬчввег ИзтепТпа оп рогх 5858 деЬив > ок Ьсеак 1п деьиеОеяю. ^:3 1 // А Оешо Соде 5пом1пр тпе РааТс сараоИШез о-? гпе поое]5 йеОивдЛпв пкхиДе 2 > 3 'и$е 51г1с1 ; 4 5 ЛжкгТоп аддТыоВишЬег(а, Ь){ деоив> п Бгеак 1п беРи^Оено.35:11 9 } 10 >11 1е1 пе5и1С - аддТноНитоеЩЗ, 9); 12 сол5о1е.к>(Дге5и1г); 13 деЬи^^ с Ьгеак 1п деЬивОето.Зз:7 5 ^ипсНоп аддТиоНиг"Ьег(а, Ь){ б // ТипсйТоп ге*игп5 1Не $ип> оГ сНе Ъю пишоег5 > 7 оеЬиввер 8 гетигп а + Ь; 9 } дебив> с < 14 <1еоив> ргосе55.ех11() апкигапапд:~/ногк5расе/поде35/по<1е350еЬи^1пв $ | Используйте команду иа1сй(ехргезз1оп) для добавления переменной или выражения, за значением которых вы хотите наблюдать. Команда гезСаг! перезапускает приложение и отладку. Используйте команду гер1 для интерактивного ввода кода. Режим гер1 име- ет такой же контекст, как и строка, на которой вы находитесь в процессе отлад- ки. Это позволяет вам исследовать содержимое переменных и тестировать стро- ки кода Нажмите Стг1+С, чтобы выйти из режима гер1.
Использование встроенного инспектора Моде уб.3.0 Вы можете использовать встроенный г8 инспектор ТЧос1е.]8. Плагин побе- бпзрестог больше не нужен. Просто передайте флаг инспектора, и вам будет пре- доставлен ОКТ. для доступа к нему: пойе --шзресС: зегуег ]б Установите поое-юзресСог: прт 1пз1а11 -д побе-1пзрес1ог Запустите ваше приложение с командой побебеЬид: побе-беЬид Т11епате.]з После этого откройте в Сйготе: ККр://1оса1боз1:8080/беЬид?рог1-5858 Иногда порт 80811 может быть недоступен на вашем компьютере. В этом слу- чае можег появиться следующая ошибка: Саппог збагТ: СЬе зег^ег ас 0 0.0 0 8380. Еггог: Изтеп ЕАССЕ8. В этом случае запустите инспектор Ходе на другом порту, используя следую щую команду: $побе-1пзрес1:ог --иеЬ-рогт=6500 Вы увидите что-то подобное: ► о .* .г. о о •СМЗЭС* Чгхчег кгр-ллиэм. чад ямц* ивам ивеи» моагМватвт ивам ылч, «ш*л» иоеммнммк. ИОАТ*ч*о«в) И Св» теаМАЧОМСввцК- ’в 1 «Н Я «вЛМД «!в 10 аоеимд М) и ВвО«Мй ХИ 11 ПМцМД 441 10 внп^ М 15 ТгН •пас Ювг»:С 10:1 4ЖТ414Л0* 1МСП.4 Овв«1 * 1КЖЛ Ечтмл»
Глава 20. Доставка НТМ1- или других типов файлов Синтаксис • гезропзе зепс1Г11е(Т11еКагре, орТюпз 1ипс11оп (егг) {}); Примеры Доставка НТМЬ по указанному пути Рассмотрим, как создать сервер на Ехргезз и обслуживать тпбех. Ьгш1 по умол- чанию (пустой путь/) и оаде1 . по пути /раде). Структура папок рго]есГ гоо! | зегуег.]з |____У1е«з | 1пс1ех.11Гт1 | раде!. 1тСт1 8еп>ег.]5 уаг ехргезз = геди!ге('ехргезз'); уаг ра(± = геди1ге('раСМ'); уаг арр - ехргезз(); // доставка тпбех.Нтт!, если файл не запрашиваемся арр.де!( 7 ”, ЕопсСюп (гедоезГ, гезропзе) { гезропзе зепсЕ11е(ра11т.)о!п(_бхгпате, ухеиз/хпбех.ИгтГ )); }); // доставка рэде1.Ыт1, если запрашивается раде!
аор дет('/раде1 , Типс11оп(гедиезс, гезропзе) { гезропзе.8епс11:11е(рабП.]о1п(__01гпапе, 'утелз’, 'раде1.НТт!’, Типс1:1оп(ег гог) { 1Т (еггог) { // что-то делаем в случае ошибки сопзо1е.1од(егг); гезропзе.епс!(д80М.81г1пд1Ту({еггог: раде по! Тоипб1})); } })); }); арр 11з1еп(8080); Обратите внимание, что зепбЕт1е() просто передает статический файл в ка- честве ответа, не предоставляя возможности ею изменить. Если вы обслуживае- те НТМЬ-файл и хотите включить в него динамические данные, вам нужно будет использовать шаблонизатор (тетргаге спдте), такой как Рид, МизбасПе или Ед8.
Глава 21. Внедрение зависимостей Почему следует использовать внедрение зависимостей Быстрый процесс разработки При использовании внедрения зависимостей разработчики \ойе.)5 могут ускорить процесс разработки, так как после внедрения зависимости становит ся меньше конфликтов кода и проще управлять всеми модулями. Ослабление связей между модулями Модули становятся менее связанными, что упрощает их поддержку. Написание модульных тестов Жестко заданные зависимости можно передать в модуль, что упрощает напи сание модульных тестов для каждого модуля.
Глава 22. Развертывание приложения Мойере без простоя Примеры Развертывание с использованием РМ2 без простоя есо8у5(ет.]8оп { пате": арр-пате", "зсгДрТ : зег'/ег , 'ехес_тос!е ; "сХмзТег", "ДпзСапсез : 0, "иаН-геабу' : Тгие, "ИзСеп.итеоиС": 10000 "кШ.итеоиТ": 5000 } иа11_геабу Вместо ожидания события прослушивания (Иыеп еуеп!) ждет, пока не будет выполнено ргосезз.зепсЦ ' геабу');. 115Геп_1:1теоиГ Время в миллисекундах перед принудительной перезагрузкой, если прило жение не начало слушать. кШ-ИтеоиТ Время в миллисекундах перед отправкой финального сигнала 51СК1И. зегуег.]8 сопзТ Нир = гери!ге('Нир') ; сопзг ехргезз = геди1ге( ехргезз');
сопз! арр = ехргезз(); сопзД зегуег = ЬИр.Зег^ег'арр); соизД рогД = 80 зегуег. 11з1еп(рсгД, Типс1юп() { ргосезз.зепс1( гезс!у'); }); ргосезз.оп( '81С1МТ , ТипсГюп() { зегуег ,с1озе(Топс1:1оп() { ргосез8.ех11(0); }); }); Возможно, вам нужно будет подождать, пока ваше приложение не установит соединения с базами данных, кешами, рабочими процессами и т. д. РМ2 нужно подождать, прежде чем считать ваше приложение онлайн. Для этого вам нуж- но указать иа1Т_геабу: тгое в файле конфигурации процесса. Это заставит РМ2 ждать этого события. В приложении вам нужно будет добавить ргосезз. зепб (' геабу'):, когда вы захотите, чтобы оно считалось готовым. Когда процесс останавливается или перезапускается РМ2, вашему процессу отправляются некоторые системные сигналы в заданном порядке. Сначала от- правляется сшнал 31С1МТ, который можно поймать, чтобы узнать, что ваш про- цесс собирается остановиться. Если ваше приложение не завершится само по себе до 1.6 секунды (кастомизируемо), оно получит сигнал 816КШ, чтобы принуди- тельно завершить процесс. Таким образом, если вашему приложению нужно что- то очистить (состояния или задания), вы можете поймать сигнал 8101 Ыт, чтобы подготовить его к выходу.
Глава 23. Развертывание приложений Ыос1е.]8 в продакшене Примеры Установка МООЕ_ЕМ\/=г,ргос1ис110п' Развертывание в продакшене может значительно варьироваться. но стан- дартной практикой являются определение переменной окружения МООЕ_ЕМУ и установка ее значения на ргобисттоп Флаги выполнения Любой код, выполняемый в вашем приложении (включая внешние модули), может проверять значение переменной МООЕ_ЕМУ: 11 (ргосезз.епу.МООЕ_ЕМУ === ргос!ис11оп') { // Запускаем приложение в продакшене } е1зе { // Запускаем приложение в режиме разработки } Зависимости Когда переменная окружения МСЮЕ_ЕМУ установлена на 'ргос1ис11оп’, все с1еу0ерепс1епс1ез е вашем файле раскаде, ]зоп будут полностью игнорировать- ся при выполнении команды прт 1пзса11. Вы также можете принудительно за- дать это с помощью флага --ргсбосСюп: прт 1пз1а11 -ргобисСюл Методы установки !ЧО1)Е_ЕМУ Метод 1. Установка КОВЕ_ЕЕ!У для всех ВРде./^-приложений А/Утбомгз: зе! №0Е_ЕКУ=ргос1ис1:1оп
Тлпих или другая Птх-подобная система: ехрогД МООЕ_ЕМУ=ргобос1:1оп Это установит МОЭЕ. ЕМУ для текущей ЬазЬ-сессии, так что любые приложения, запущенные после этого, будут иметь МОСЕ.ЕИУ, установленный на "р г обосДт оп". Метод 2. Установка МОПЕ_ЕИУ для текущего приложения МООЕ_ЕМУ=ргоОис1:10п побе арр.]3 Это установит МОЗЕ .ЕМУ только для текущего приложения. Это полезно, когда мы хотим протестировать наши приложения в разных окружениях. Метод 3. Создание файла .епт и его использование Этот метод использует идею, объясненную здесь: ЬПр8://8ТаскоуегПош. со1П/цие8иоп8/22312671/8еШпд-епУ1гоптеп1-уаг1аЫе8-Гог-по(1е-1о-гегг1еуе/ 28821696Я28821696. Ло сути, вы создаете файл . епу и запускаете скрипт Ьазб .для установки пере менных окружения. Чтобы избежать написания Ьазй-скрипта, можно использовать пакет впу- сте! для загрузки переменных окружения, определенных в файле .епу. епу-стб .епу пэое арэ.]з Метод 4. Использование пакета сгозв-ет’ Этот пакет позволяет устанавливать переменные окружения одинаковым способом для всех платформ. После установки с помощью при вы можете просто добавить его в ваш скрипт развертывания в раскаде. ] зоп следующим образом: ЬиПс! :с!ер1оу : "сгозз-епу МЭОЕ_ЕМУ=ргэбис1:1оп иеЬраск
Управление приложением с помощью менеджера процессов Хорошей практикой является управление приложениями (Мобе ,)8 с помощью менеджеров процессов. Менеджер процессов помогает поддерживать работу приложения постоянно, перезапускать его при сбое, перезагружать без простоев и упрощать администрирование. Наиболее мощные из них (например РМ2) име- ют встроенный балансировщик нагрузки. РМ2 также позволяет управлять доти- рованием, мониторингом и кластеризацией приложений. Менеджер процессов РМ2 Установка РМ2 прт апз^аИ рт2 -д Процесс можно запустить в кластерном режиме, используя встроенный ба лансировщик нагрузки для распределения нагрузки между процессами: рт2 зСагС арр ]з -1 0 --пате ар!" (-1 используется для указания количества порождаемых процессов. Если ука зано 0, количество процессов будет основано па количестве ядер СРО.) При наличии нескольких пользователей в продакшене важно иметь единую точку для РМ2. Поэтому' команды рт2 должны быть префиксированы с указани- ем местоположения (для конфигуратши РМ2), иначе для каждого пользователя будет запущен новый процесс РМ2 с конфигурацией в его домашнем каталоге, что приведет к несогласованности. РМ2_Н0МЕ=/еТс/.от2 рт2 зСагт арр ]8 Развертывание с использованием РМ2 РМ2 — это менеджер процессов для Мобе.р-приложений в продакшене, кото- рый позволяет поддерживать их работу постоянно и перезагружать их без про- стоев. РМ2 также позволяет управлять дотированием, мониторинтом и класте- ризацией приложений. Установите РМ2 глобально: прт ЕпзСаП -д ргг2 Затем запустите По6е.]8-т[риложение с использованием РМ2: рт2 зТагС зегуег.]з --пате ту-арр 1
$ рч2 зСагГ арр.]5 --пате ву-арр [Рм2] гезгаггРгосеззЮ ргосезз 16 в 1 1 | Арр паве ' / 1 16 пойе | 1 | 1 1 р!6 | ЗГаГиЗ 1 1 гезГагС | ирсхве вевог, I I I » 1 | маХсЫпв | 1 пу-арР 1 1 1 е [ Гогк | । 1 64029 | опИпе | 1 1 Г 1 1 | 05 | 17.816 МВ 1 1 | (НзаЫей | । । Озе СПе р»? $Ьои <16|пате> соввапб Со в₽г аоге 6еСа11з аЬоиС ап арр. Полезные команды при работе с РМ2 Список всех запущенных процессов рт2 1131: Остановить приложение: рт2 зЮр ту-арр Перезапустить приложение: рт? гезТагГ: ту-арр Посмотреть подробную информацию о приложении: рт2 збои шу-арр Удалить приложение из реестра РМ2: рт2 бе1е1е ту-арр Еогеуег Гэгеуег — это инструмент командной строки, обеспечивающий непре- рывную работу заданного скрипта. Простота интерфейса ^огеуег делает его иде- альным для развертывания небольших приложений и скриптов на Ыос1е.]5. Гогеуег отслеживает ваш процесс и перезапускает его в случае сбоя. Установка богеуег глобально: прт 1П31а11 -д 1огеуег Запуск приложения: Согеуег зтагт зегуег.зз Это запустит сервер и присвоит ему идентификатор (начиная с 0). Перезапуск приложения: Гогеуег гезТагС 0
Здесь 0 — это идентификатор сервера. Остановка приложения: Гоге'/ег з1оо 0 Аналогично перезапуску 0 — это идентификатор сервера. Вы также можете указать идентификатор процесса или имя скрипта вместо идентификатора, при- своенного ^:о^еVе^. Для получения дополнительных команд перейдите по ссылке или фК-коду ниже йир5://ил7млпрт)5.сот/раска&е.'Тоге\'ег. Использование разных свойств/конфигураций для разных окружений, таких как деу, па, з1адтд и т. д. Крупномасштабные приложения часто требуют разных свойств при работе в разных окружениях. Мы можем достичь этого, передавая аргументы приложе- нию ^ойс.]8 и используя те же аргументы в процессе Мойе для загрузки конкрет- ного файла свойств окружения. Предположим, у нас есть два файла свойств для разных окружений: с1е7.]зоп { "РОЙТ": 3000, ЪВ : { НозГ: "1оса1КозТ", 'изег : 'ЬоЬ", раззлогб : "12345 } } да.]зоп { РОЙТ'. 3001 "ОВ : { ‘НозХ": иПеге_с!Ь_1з_11оз1:еО",
"изег ЬоЬ", раззжогд": 54321' } } Следующий код в приложении экспортирует соответствующий файл свойств, который мы хотим использовать. ргосезз.агду.ГогЕас^бипстюп (уа1) { уаг агд = уа1.зр11С("="); 1Т (агд. 1епдТ1т > 0) { 1Т (агд[0] === епу’) { уаг епу = геди1ге('./’ + агд[1] + '.]зоп'); ехрогбз.ргср = епу; } } }); Мы передаем аргументы приложению следующим образом: пос1е аор .]з епу=беу Если мы используем менеджер процессов, такой как Тогеуег, то это делается так же просто: Тогеуег зтагт арр.]з епу=с!еу Использование преимуществ кластеров Один экземпляр Ыог1е.]8 работает в одном потоке. Чтобы воспользоваться пре- имуществами многоядерных систем, по.тьзователь инотда захочет запустить кластер процессов К’ойедз для обработки нагрузки. уаг сТизДег = геаит.ге( 'сТизбег'); уаг питСРСз = гедитге('оз’).сриз(). 1епдТ;Ь; 1Г (с1изГег.1&МазГег) { // В реальном применении, веооятно, вы бы использовали больше чем двэ рабочих пооцесса, // и, возможно, не размещали бы мастер и рабочие процессы в одном файле. // // Вы также конечно, можете усложнить легирование // и реализовать любую необходимую логику для поедотвращения // ОоЗ-атак и других вредоносных действий. И
// Смотрите опции в документации по кластеру. // // Еажно то, что мастер выполняет очень мало. // увеличивая устойчивость приложения к неожиданным ошибкам. сопзо1е.1од('уоиг зегуег 1з «огкшд оп ' + пипСРОз + ' согез'); Тог (уаг 1 = 0; 1 < питСРиз; 1++) { с1из1ег.ГоикО ; с1изСег ,оп(1 с11зсоппес1', 1'ипсС1оп(й,огкег) { сопзо1е.еггог('бтзсогпесС!’); //с1еагТ1теоиС(11теои1:); сХиз^ег.'РогкО ; }); } е1зе { гедитге('./арр.]8 );
Глава 24. ЕСМА5спр1 2015 (Е36) с Ыос1е.|8 Примеры Объявления соп8(/1е1 В отличие от уаг, сопз1:/1е1 привязаны к лексической области видимости, а не к области видимости функции. { уаг х = 1 // выйдет за пределы области видимости 1еГ у = 2 // привязан к лексической области видимости сопзТ 2 = 3// привязан к лексической области видимости, являет- ся константой } сопзо1е.1од(х) // 1 сспзо1е.1од(у) // РеГегепсеЕггог у 1з поС с!еТ1пес1 сопзо1е.1од(2) // ВеГегепсеЕггог: г хз по! беПпеб Стрелочные функции Стрелочные функции автоматически привязываются к лексической области видимости Хб 1з окружающего кода. регЕогт8оп1е1:Ыпд(гезаП: => { 1613. зопеУа паЫе = гезиИ: }) вместо: регЕсгт8оте1:61пд(Гипс1:1оп(ге8и11) { С613. зотеУагхаЫе - гези11: }. Ыпб(Тб1з))
Пример стрелочной функции Рассмотрим пример, который выводит квадраты чисел 3, 5 и 7: 1е1 питз = [3, 5, 7] 1ет здиагез = питз.тар^ипсЫоп (п) { гесигп п * п }) сопзо1е.1од('здиагез) Функцию, переданную в .тар. также можно записать как стрелочную функ- цию, убрав ключевое слово ^ипспоп и добавив стрелку =>: 1е1: питз - [3, 5 7] ЗеТ здиэгез = питз.тар((п) => { геСигп п * п }) сопзо1е.1од(здиагез) Однако это можно записать еще более кратко. Если тело функции состоит только из одного выражения, и это выражение вычисляет возвращаемое значе- ние. фигурные скобки, оборачивающие тело функции, можно убрать, как и клю- чевое слово геТигп. 1е1: питз = [3, 5, 7] 1еЗ здиагез - питз.тар(п => п * п) сопзо1е.1од(здиагез) Деструктуризация 1е1 [х,у, ...питз] = [0, 1, 2, 3, 4, 5, 6]; сопзоЗе.1од(х, у, питз); 1еЕ За, Ь, ...ргорз) = {а:1, Ь:2, с:3, б:{е:4}} сопзоЕе.1од(а, о ргорз); 1е1 бод = {пате: Ттбо , аде: 3}; 1е1 {пате:п, аде} = бод; сопзо1е.1од(п, аде);
Нот /* @-Г1о\л/ */ ТипсНоп ргос1ист(а пишЬег, Ь: питЬег){ ге1игп а * Ь; } сопат Ь = 3; 1еГ с = [1,2,3.,{}]; 1еГ й = 3 ; 1трог1 гериезГ 'Ггот ' гериез! ’ ; гериез!(' НИ р : / / беV . тагк11:опс1етапа . сот/МОСАрхз/Ар1 /у2/0ио!е/ ]8Оп?8уп’Ьо1=ААР1_', (егг, гез, рау1оас!) => { рау1оаР = 380М.рагзе(рау1оаР); 1е1 {1_а8ГРг1се} = рау1оас1; соп8с1е.1ор(1_э8'СРг1се); }); Класс Е86 с1а88 Матта1 { сопе1:гис1ог(1едз) { 1±1з.1едз = 1ед8; } еас(){ соп8о1е 1од('еа1:1пд } з'ЕаПс соипГ(){ сопзо1е.1од(1 зИаПс соиггС... ’); } } с1аз8 Эод ехГепйз Матта1{ сопз! гис1:ог(пате, 1едз){ 8ирег(1едз); ХЫз пате = пате; } з!еер(){ зирег.еа1();
сопьо1е.1од('Е1еео1пд'); } } 1е1 а = лея Оод('Т1с1о , 4) ; с1.з1еер(); с!. еа1(); сопзо!е. 1од('с1', с1);
Глава 25. Окружение Примеры Доступ к переменным окружения Свойство ргосезз.епу возвращает объект, содержащий пользовательское окружение. Этот объект выглядит следующим образом: { ТЕРМ 'хсегт-256со1ог', 8НЕИ: '/озг/1оса1/Ртп/Ьазб', ОЗЕР: 'таете]', РАТН: '~/ Ьтп/./озг/Ып:/бтп:/изг/зЬтп:/зЬтп:/озг/1оса1/Ып', РЮ: ‘/11$егз/тасте]', ЕО1ТОР: 'у1т', 8Н1_У1_: Г, НОМЕ: ' /Кзегз/тасте]', IОбИАМЕ: 'таете] _: '/изг/1оса1/Ып/побе' } ргосезз.епу.НОМЕ // /бзегз/тасте] Если установить переменную окружения Е00 в значение ГооЬа г, то она будет доступна следующим образом: ргосезз.епу.ЕОЭ // тооЬаг Аргументы командной строки ргосеез.агду ргосезз.агду — это массив, содержащий аргументы командной строки. Первый элемент будет поре, второй элемент будет с именем |ауа8спр(-файла. Следующие элементы будут любыми дополнительными аргументами команд- ной строки.
Пример кода Вывод суммы всех аргументов командной строки: шбех. ]з уаг зит = 0; Гог (1=2; 1 < ргосезз агду 1епдтИ; 1++) { зит += МитЬег(ргосезз.агду[1]); } сопзо1е.1од(зит); Пример использования побе юбех ]з 2 5 6 7 Вывод будет равен 20 Краткое объяснение кода Здесь в цикле Го г (1 = 2; 1 < ргосезз. агду. ]епд1И; 1++) цикл начина- ется с 2, потому что первые два элемента в массиве ргосезз .агду всегда такие: [ раСК/Ю/побе.ехе', ' ра1:Ь/То/} е/Т11е', . ] Преобразование в число МишЬегГргосезз .а<ду[1]), потому что элементы в мас- сиве ргосезз .агду всегда являются строками. Использование различных свойств/конфигураций для разных окружений, таких как деу ца, зГадтд и т д Крупномасштабные приложения часто требуют различных свойств при запу- ске в разных окружениях. Этого можно достичь путем передачи аргумента в при- ложение Ыобедз и использования этого аргумента для загрузки определенного файла свойств окружения. Предположим, у нас есть два файла свойств для разных окружений: • беу.]зол { РОРТ : 3000, ОВ : { Коз! : "1оса11зо51“, изег : Ьоо', раззуюгс! : "12345" } } • да.]зоп { РОРТ : 3001,
Исполозование различных свойств/конфиг>раций^ля разных окружений ... 129 СБ : { Поз! : "иЬеге_бь_18_Псз1:еО . изег : "ЬоЬ , раззиого : 54321 } } Следующий код в приложении экспортирует соответствующий файл свойств, который мы хотим использовать. Предположим, чсо код находится в епухгоптеп!. ]з: ргосезз агду ГогЕасЬ(ТипсТ1оп (уа1, тпбех, аггау) { уаг агд = уа1.зр111(; 1Г (агд.Хейден > 0) { 1Е (агд[0] === ‘епу’) { уаг епу = геди1ге('+ агд[з] + '.]зоп'); тобиХе.ехрсгХз = епу; } } }); Мы передаем аргументы в приложение следующим образом: побе арр.]з епу=оеу Если мы используем менеджер процессов, такой как Тогеуег, то это так же просто, как: Еогеуег зГагС арр.]з епу=беу Как использовать конфигурационный файл уаг епу = геди!ге("епутгоптепУ.]з ); Загрузка свойств окружения из «файла свойств» • Установите ргорегттез - геабег: прт гпзтаН ргорег^гез-геабег -зауе • Создайте директорию епу для хранения ваших файлов свойств ткс11г епу • СоздайтеепутгоптепХз.]з: ргосезз.агду.ГэгЕасЦ^ипсГюп (уа1 юбех, а^гау) { уаг агд = уа1.зр11т('="); 1Т (агд.ХепдТП > 0) {
1Т (агд[0] === 'епу') { уаг епу = геди!ге('./епу/’ + агд[1] + ' .ргорегЕюз'); пюаи1е.ехрогЕз = епу; } } }); • Пример файла свойств ОеуеЕортепГ. р горе г! тез: # Оеу ргорегИез [таю] # Порт приложения для запуска сервера пойе арр. рэг1:=8е80 |даГаЬазе] # Подключение к базе данных тузд! тузц1.1гоз1:=1оса1Ко5Г тузд!.рогг-2500 • Пример использования загруженных свойств уаг епутгоптеп!: = гедо!ге(1 ./епухгоптепЕз'): уаг РгсрегПезРеадег = геди1ге('огорегСюз-геабег'); уаг ргоретез = пел Ргорег1:1е5Пеас1ег(епУ1гоптеп1:); уаг зотеУа! = ргорегПез деС('таги. арр.роге; • Запуск сервера Ехргезз: прт згагг епу=оеуе1ортеп1: или прт зГаг! епу=ргобис11оп
Глава 26. Источники событий Примечания Когда событие «срабатывает» (что означает то же самое, что и «публикация события» или «генерация события»), каждый слушатель будет вызван синхрон- но вместе с любыми данными, переданными в етИО, независимо от того, сколь- ко аргументов вы передадите: ггуОод.оп( Ьагк’, (Ьои1.оис1, ЬоиЬопд, Ьои1п1епзе) => { // обработка события }) п’уОод.еппЦ'Ьагк', ' 1оос11у , 5 зесопбз 1опд', 'Г1егсе1у') На источник можно перейти по ссылке: 1тр8://г,ойе}8.ог^/й18Т,/1а1:е81-Уб.х/(1ос8/ ар1/еуеп(8.1пт1#еуеп(8_а8упс1тгопои8_У8_8упс1тгопои8 или по рН коду ниже. Слушатели будут вызваны в том порядке, в котором они были зарегистри- рованы: туОод.оп( 'огтпаСе', () => сопзо1е.1эд( Му ТтгзТ: СНоидЫ лаз "ОЬ-по"')) тубод оп('иппаге’, () => сопзо1е.1од('Му зесопс! тЬоидЫ: маз Мо1 пу 1айп :)"')) ту0од.ет1С('игтпаСе')
// Эти сопзо1е.1од будут выполнены в правильном порядке, так как они были зарегистрированы в этом порядке Но если вам нужно, чтобы слушатель сработал первым, перед всеми осталь- ными слушателями, которые уже были добавлены, вы можете использовать ргерепбИзЕепегО следующим образом: туОод ргерепбЕ1зЕепег( игтаЕе', () => сопзо1е.1од('тп±з Ьаррепз ЬеТоге ту Тьгзт апб зесопо тЬоидПЕз, еуеп ЕПоидЬ 11 иаз гедэзЕегес! аТтег ЕИет’)) Если вам нужно прослушивать событие, но вы хотите, чтобы оно сра- батывало только один раз, вы можете использовать опсе вместо оп, или огерепсЮпсеИзтепег вместо ргерепаЕгзЕепег. После того как собы- тие сработает и слушатель будет вызван, слушатель автоматически удалится и не будет вызываться снова при следующем срабатывании события. Наконец, если вы хотите удалить всех слушателей и начать с чистого листа, вы можете сделать это гак. тубод. гетоуеА11Е1зЕепегз() Примеры Аналитика НТТР через источник событий В коде НТТР-сервера (например, зегуег. ] з): сопзЕ ЕмепЕЕппЩег = гедо1ге( еуепЕз') сопз! зегуегЕуепсз = пей ЕуептЕт1ЕЕег() // Настройка НТТР сервера сопзЕ НЕЕр = гедо1ге('НЕЕр') сопзЕ КирЭегуег - ЬЕЕр.с,'еаЕе8егуег((гедиезЕ, гезропзе) => { // Обработка запроса... // Затем генерируем событие о том, что произошло зегуегЕуептз.его1Е( гедиезЕ' гедиезЕ.теНюб, гедоезЕ. иг1) }); // Экспортируем генератор событий тобиХе.ехрегтз = зегуегЕуептз В коде надзора (например зирегуюог. ]з): сопзЕ зегуег = гедз1ге('./зегуег.]з') // Поскольку сервер экспортировал генератор событий, мы можем слушать его изменения:
зегуег ,оп(' гедиезг', (тетЬсс!, иг1) -> { сопзо1е.1од( Со1 а гедиезТ: ${те1Ьос1} ${иг1}’) }) Каждый раз, когда сервер получает запрос, он генерирует событие, называе- мое гедоезт, которое будет прослушиваться надзором, и затем надзор может от- реагировать на событие Основы Источники событий встроены в Хойе и используются для реализации паттер- на риЬ-зиЬ, при котором издатель генерирует события, на которые подписчики могут реагировать. В т ерминологии Хойе издатели называются источниками со- бытий (Емеп! ЕгоыДегз), и они генерируют события, тогда как подписчики на- зываются слушателями (Изтепегз), и они реагируют на события. // Подключаем модуль событий для начала работы с ними сопзТ Еуеп'ЬЕтзДТег = геди1ге( емепТз').ЕуегНЕтПДег; // У собак есть события для публикации или генеоации с1азз Под ехТепРз ЕуепГЕтПЛег {}; с1азз Еооб {}; 1е1 тубод = пел бод(); // Когда тубод жует, выполните следующую функцию тубод ,оп(' сбей', (Нет) => { 1Г (Нет юзТапсеоТ Еооб) { сопзо1е.1од('Сооб бод'); } е1зе { сопзо1е.1од( Ттгае 1о Роу апо1:бег ${1Ует} ) ; } }); тубод .ет11:( 'сбей/', збое'); // Выведет в консоль: 'Т1те го Ьиу апоГбег збое’ сопзС оасоп = пси Еооб(); тубод.ет1Т('сбей', Ьэсоп); // Выведет в консоль’ 'Бооб бод' В приведенном выше примере собака является издателем/источником собы- тий, в го время как функция, проверяющая предмет, яв.гяется подписчиком/слу- шателем. Вы также можете создать больше слушателей: тубод.оп('Ьагк’, () => { сопзо1е.1од('ЙН0\'5 АГ ТНЕ 600Р? ); // Паника });
Также может быт ь несколько слушателей для одного события, и можно даже удалить слушателей: туОсд.оп( 'сбей', -ГакеАОееэВгеагбе); туОсд.оп( 'сКе« , са1т0ол'п); // Отменяем предыдущую строку следующей: туОод.гетоуе11з1епег('сбей', са1п0сип); Если вы хотите прослушивать событие только один раз, вы можете исполь- зовать: туРод опсе('сбел', реС); ...которое автоматически удалит слушателя без условий гонки (гасе сошййоп). Получение имен событий, на которые подписаны Функция Еуеп1:Ет11.1:ег.еуеп1:Матез() вернет массив, содержащий имена со- бытий, на кот орые в данный момент подписаны. сопзС ЕуегйЕтбПег = геди±ге( еуепсз ); с1азз МуЕппЩег ехСепсз ЕуептЕппЩег!} уаг ешйГег = пей/ МуЕт1Иег(); етЫЛег .оп("теззаде "ГипсМоп(){ // слушаем событие теззаде сэпзо1е.1од("а теззаде иаз етпСеб!"); }) оп('теззаде , ЕипсГ1оп(){ // слушаем событие теззаде сопзо1е.1од( "1:613 1з пос 1бе г1дбт теззаде ); }) ,оп("баСа", Гипс1:1оп() { // слушаем событие баСа сопзо1е.1од("а бага ]изг оссигеб!!"), }); соп8о1е.1од(ет11:1:ег.еуепСМатез()); //=> [ 'теззаде","оаСа'] етисег.гетоуеАНИзГепегзС'баГа"); //=> удаляем всех слушателей со- бытия баСа сопзо1е.1од(ет1С1:ег.еуеп1Мап1ез()); //=> ["теззаде ] Получение количества слушателей, зарегистрированных для определенного события Функция ЕтИСег. ИзСепегСоипЦеуепТЛате) вернет количество слушате- лей, которые в данный момент прослушивают событие, переданное в качестве аргумента.
Получение количества слушателей, зарегистрированных для определенного события 135 сопзХ Еуеп1ЕпиПег = геди1ге( "е7епХз"); с1азз МуЕгиХХег ехХепбз Е'/епХЕшНег{} уаг етбНег = пей МуЕтКег(); етхНег .оп(”ба1а , ()=>{// добавляем слушателя для события ба(.а солзс1е.1од( бага еуепт етХХХег"); }); сопзоХе.1од(ет1С1ег.11з1епегСоипГ( баТа")) // => 1 сопзоХе. Ход(ет1Х1ег.Х1з1:епегСоип1:( теззаде")) // => й еппсхег,оп(’теззаде , ТипсСюп т1_1з1епег(){ // добавляем слушателя для события теззаде сопзоХе.Ход( ’ теззаде еуепХ епиПеб ); }); сопзоХе. 1од(ет1ттег.11з1:епегСоап1:("бага")) // => 1 сопзоХе. 1од(етХтХег ХтзХепегСоип-Ц'теззаде")) // => 1 ет1Х1ег,опсе( баХа(зХи-ЕТ) => { // добавляем еще одного слушателя для события баХа сопзо1е.1од( Ге11 те ту ${з1иХТ}’); }); сопзоХе. 1од(ет1х1:ег.11зтепегСоип1:( бата')) // => 2 сопзоХе.Ход(ет1СТег.Х13ТепегСоипТ( теззаде")) // => 1
Глава 27. Еуел11оор (цикл событий) Введение В этой главе рассматривается, как возникла концепция цикла событий и как она может использоваться для высокопроизводительных серверов и собы- тийно-ориентированных приложений, таких как СШ. Примеры Рассмотрим, как развивалась концепция цикла событий. Еуеп11оор на псевдокоде ЕсепТ 1оор — это цикл, который ожидает событий, а затем реагирует на них: у/ГтПе Тгие: ожидать, пока не произойдет что-то реагировать на произошедшее Пример однопоточного НТТР-сервера без еуегй 1оор «И11е Тгие: сокет = ожидать следующего ТСР-соединения прочитать НТТР-за^оловки запоэса из (сокета) содеожимое. файла = получить запрашиваемый файл с диска записать НТТР-заголовки ответа е (сокет) записать (содержимое.файла) в (сокет) закро1ть (сокет) Вог простой пример НТТР-сервера, который яв.тяется однопоточным, но без еуепГ 1оор. Проблема здесь заключается в том, что сервер ждет, пока каж-
дый запрос не будет завершен, прежде чем начать обработку следующего. Если требуется некоторое время для чтения заголовков НТТР-запроса или для получе- ния файла с диска, мы должны иметь возможность начать обработку следующе- го запроса, пока ожидаем завершения предыдущего. Наиболее распространенное решение — сделать программу многопоточной. Пример многопоточногл НТТР-сервера без еуегй 1оор функция обработа'гь_соединение(сокет): прочитать НТТР-заголовки запроса из (сскета) содержимсе.файла = получить запрашиваемый файл с диска записать НТТР-заголовки ответа в (сокет) записать (ссдержимое.файла) в (сокет) закрыть (сокет) »П11е Тгое: сокет = ожидать следующего ТСР-соединения запустить новый поток, выполняющий обработку соединения(зоке!) Теперь мы сделали наш небольшой НТТР-сервер многопоточным. Таким обра- зом, мы можем сразу же приступить к следующему запросу, так как текущий за- прос выполняется в фоновом потоке. Многие серверы, включая Арасйе, исполь- зуют этот подход. Но он не идеален. Одним из ограничений является то, что вы можете создать только определенное количество потоков. Для рабочих нагрузок, где имеет- ся огромное количество соединений, но каждое соединение требует внимания лишь изредка, многопоточная модель не будет работать эффективно. Решением в таких случаях является использование еVеЩ 1оор. Пример НТТР-сервера с еуегй 1оор у/И11е Тгое: событие = ожидать следующего события 1Т (событиелип == НОВОЕ_ТСР_СОЕДИНЕНИЕ): соединение = новое соединение соединение.сокет = событие.сокет начать чтение НТТР-заголсвков запроса из (соединение.сокет) с пользовательскими данными = (соединение) е1зе 1Г (событие.тип == ЗАВЕРШЕНО_ЧГЕНИЕ_ИЗ_СОКЕ!А) : соединение = событие.пользовательские.данные начать получение запрашиваемого файла с диска с пользователь- скими данными = (соединение) е!зе И (событие тип == ЗАВЕРШЕН0_ЧТЕНИЕ_С_ДИСКА): соединение = событие.пользовательские.данные
соединение.содержимое_файла = данные, которые мы получили с диска соединение.текущее.состояние = запись заголовков начать запись НТТР-заголовков ответа в (соединение.сокет) с пользовательскими данными = (соединение) е!$е 1Т (событие.тип == ЗаВЕРШЕнО_ЗаПИСь_В_СОКЕТ): соединение = событие пользовательские_данные 1Е (соединение.текущее.состояние == 'запись заголовков'): соединение.гекущее.сосгояние = запись содержимого файла начать запись (соединение.содержимое_файла) в (соедине- ние, сокет) с пользовательскими данными = (соединение) е1зе 1Е (соединение текущее_состояние == запись содержимого файла'1): закрыть (соединение.сокет) Думаем, этот псевдокод понятен Вот что происходит: мы ждем, пока что-то случится. Всякий раз, когда создается новое соединение или существующее сое динение требует нашего внимания, мы обрабатываем его, затем возвращаемся к ожиданию. Таким образом, мы эффективно работаем, когда имеется много сое- динений, и каждое из них требует внимания лишь изредка. В реальном приложении (не в псевдокоде), работающем на Ьшпх. часть «ожи- дать следующее о событиях была бы реализована с помощью системного вызова ро1.1() или еро11(). Части «начать чтение НТтр-заголовков запроса из (со- единение .сокет)» были бы реализованы с помощью системных вызовов гес7() или зелб() в неблокирующем режиме. Ссылка: Статья «Как работает цикл событий?» доступна по ссылке 1Шрз:/Ллгту.циога. сот/Номг-боез-ап-еуепМоорлуо! к или по рн-коду ниже.
Глава 28. Обработка исключений Примеры Обработка исключений в Моде)8 В М<существует три основных способа обработки исключений/ошибок: 1. блок ггу-сатсЬ 2. передача ошибки в качестве первого аргумента в саПОаск 3. генерация события ошибки с использованием еуепЬЕтИСег 1 гу-саСсЬ используется для перехвата исключений, возникающих в синхрон- ном коде. Если вызывающий код (или код, который его вызывает) использует Т гу-саТсЬ,то они могут поймать ошибку. Если ни один из вызовов не использует Ьгу-саСсЬ, программа завершится с ошибкой. Если использовать Тгу-саСсЬ для асинхронной операции и исключение воз- никнет в саПЬаск асинхронного метода, то оно не будет перехвачено Т г у - саСсИ. Чтобы перехватить исключение из саПЬаск асинхронной операции, предпоч- тительно использовать ргоппзе. Пример для лучшего понимания // ** Пример - 1 ** ТипсПоп 0о8оте5упсбгопоиз0рега1;1оп(гер, гез) { 1Е(гер.Ьсбу.изеглате === ''){ СЬгои пел ЕггоЦ'Рзег Мате саппо1: Ье етрДу'); } геЬигп Сгие; } // вызов метода выше Сгу { // синхронный код боЗоте5упсЬгопоизЭрегаНоп( гео, гез)
} саТсЬ(е) { // исключение обрабатывается здесь сопзо1е.1од(е.теззаде) ; } // ** Пример - 2 ** ТипсГюп бо8отеАзупсЬгопоизСрегаТ1сп(гед гез, сЬ) { // имитация асинхронной операции гетигп зетТ1П’еои1:(Типс1:10п(){ сЬ(поП, []); }, 1000); } 1гу { // асинхронный код с1о8отеАзупс1тгопоиз0регаП1оп(гед, гез, ГипсТ1оп(егг, гз){ ТЬгои пей Еггог("азупс орегаПоп ехсерПоп"); }) } саТсЬ(е) { // исключение не будет обработано здесь сопзо1е.1од(е.теззаде); } //Исключение не обработано, и поэтому приложение завершится с ошибкой. В основном в Мо(1е.)8 используются обратные вызовы, так как они передают событие асинхронно. Пользователь передает вам функцию (саПЬаск), и вы вы зываеге ее позже, когда асинхронная операция завершится. Обычно саПЬаск вызывается как са11Ьаск(егг, гезиИ), где только одно из значений егг и гезиИ не равно пиП, в зависимости от того, завершилась операция успешно или нет. ТопсПоп бо8о1леАзупсЬгопоиз0рега'С1оп(гед, гез, саПЬаск) { зе1Т1теон1 (ТипсПоп() { геТигп са11Ьаск(пеу/ Еггог( 'бзег Иате сапно): Ье етрТу’)); }, 1000); геГигп Тгое; } бо5стеАзупсЬгопоиз0регаПоп( гед. гез, Гипс(:1сп(егг, гезиИ) { И (егг) { // исключение обрабатывается здесь сопзо1е.1сд(егг.теззаде); } // выполнение дальнейших действий с действительными данными });
Генерация событий В более сложных случаях вместо использования саНЬаск функция сама может возвращать объект ЕуепГЕппЛтег, и от вызывающего кода ожидается, что он будет отслеживать события ошибок на эмиттере ссозТ ЕуепТЕтПЛег = геди1ге('еуегтсз’); ГипсТюп Со8отеА5упсбгопоиз0рега1:1оп(гер. гез) { 1еТ туЕуепЬ = пей ЕуепТЕпг.1Шег() ; // выполняется асинхронно зеГТ1теоиТ('ГипсТ1оп() { туЕуепТ.етН( 'еггог', пей Еггог('11зег Мате саппо! Ье етрТу’)); }, 1000); геТигп туЕуепЬ; } // Вызов функции 1еГ еуепГ = РоЗоп1еА5упсИгопоизОрега1:1оп(гед. гез); еуепЬ оп('еггог', ГипсЫоп(егг) { сопзо1е.1од(егг); }); еуепТ ,оп(' боле', Гипс1:1оп( гезиИ) { сопзо1е.1од(гези11:); // Ьгие }); Управление необработанными исключениями Так как Мобедз работает в одном потоке, необработанные исключения могут стать проблемой, о которой стоит помнить при разработке приложений. Тихая обработка исключений Многие разработчики позволяют серверу Мобедз незаметно -проглатывать» ошибки. // Тихая обработка исключений ргосезз.оп( 'опсаадЫЕхсерГтоп', ГипсЫоп (егг) { сопзо1е.1од(егг); }); Это работает, но • Первопричина останется неизвестной, а значит, данный способ не поможет в решении проблемы, вызвавшей исключение (ошибку).
• В случае если по какой-либо причине соединение с базой данных (роо!) закрыто, это приведет к постоянной передаче ошибок, а это означает, что сервер будет работать, но не переподключится к базе данных Возврат к начальному состоянию В случае ипсаидбТЕхсерТюп желательно перезапустить сервер и вернуть его в начальное состояние, при котором он точно будет работать. Исключение запи- сывается в лог, приложение завершает работу, но поскольку оно будет работать в контейнере, который следит за тем, чтобы сервер продолжал работать, мы до бьемся перезапуска сервера (возврата к начальному рабочему состоянию). • Установка утилиты Тогеуег (или другого СЫ-инструмента, чтобы сервер 1Мос1е.]8 работал непрерывно): прт 1пзТа11 Тогеуег -д • Запуск сервера с То геее г: Тогеуег зТагТ арр.)з Причина, по которой сервер запускается с Тогеуег, заключается в том, что по- сле завершения работы сервера процесс ^огеуег снова запустит сервер. • Перезапуск сервера: ргосезз.оп( ‘ ипсаодпгЕхсерТТоп', ТипстТоп (егг) { сопзо1е 1од(егг); // механизм легирования // .... ргосезз.ех!1(1 ); // завершает процесс }); Заметим, что ранее также существовал способ обработки исключений с помо- щью кластеров и доменов. Доменный модуль был признан устаревшим, подроб- нее об этом можно узнать здесь: Ьирк//по<1е)8.ог(’/ар1/(1отат.1ит1 или по рК-коду ниже.
Ошибки и Ргоггпзез (промисы) Ргоппзез обрабатывают ошибки иначе, чем синхронный код или код на ос- нове саИРаск. сопзС р = пей Рготх8е(ГипсТхоп (гезо1уе, ге]ес!) { ге]есг(пеи Еггог('Оорз1)); }); // все, что отклонено внутри ргоппзе, будет доступно через саТсН // когда рготхзе отклонен, .ХИеп не будет вызван Р ЛГгепЦ) => { сопзо1е.]од( иол'т Ре саПесГ) ; }) ,са1:сР(е => { сопзо1е.1од(е.теззаде); // вывод: Эорз }) // после перехвата ошибки выполнение продолжается .СИеп(() => { сопзо1е 1од( 1те11о!'); // вывод: РеПо! }); В настоящее время ошибки, вызванные в рготхзе и не перехваченные, при- водят к тому, что ошибка «проглатывается», а эю может затруднить отлад- ку. данную проблему можно решить, используя инструменты линтинга, такие как ез1хп1. или путем обеспечения того, чтобы у вас всегда был блок сатсП. Такое поведение устарело в Мобе.р 8 в пользу завершения процесса Мобедз.
Глава 29. Выполнение файлов или команд с помощью дочерних процессов Синтаксис • сЬ11б .ргосезз ехес(ссттапб[, ор11оп8][, саПЬаск]) • сЬ11с_ргосез8.ехесЕ11е(1:11е[, агдз][, срТ1опз][, саПЬаск]) • сНПс.ргосезз.Тогк(чтоби1еРагк||, агдз][, орТтопз]) • сЬ11с!_ргосе58.зра«уп(соттапс1!, агдз][, ор11опе]) • сЬ11б_ргосезз ехесР11е8упс('(:з1е[, агдз] [, орПопз]) • сЫ1Ь.ргосезз.ехесЗупс(сотггапб[, орттопз]) • сИ11Ь_ ргосезз. 8раи/п8упс(соттапс1[, агдз][, орПопз]) Замечания При работе с дочерними процессами все асинхронные методы будут возвра- щать экземпляр СЬ11ЬРгосезз. в то время как все синхронные версии будут воз- вращать результат выполнения. Как и другие синхронные операции в Мог1е.]8, если возникает ошибка, опа будет выброшена. Примеры Создание нового процесса для выполнения команды Чтобы создать новый процесс, если вам нужен небуферизированный вывод (например, для долго работающих процессов, которые могут выводить данные на протяжении определенного времени, а не сразу после завершения), исполь- зуйте сЫ1с1_ргосезз зраип().
Этот метод создает новый процесс с помощью заданной команды и массива аргументов. Возвращаемое значение — это экземпляр СИНбРгосезз, который, в свою очередь, предоставляет свойства зСбоит и зСоегг. Оба этих потока явля- ются экземплярами зСгеап Реабаэ1е Следующий код эквивалентен команде 1з -Нт /изг сопзС зрая/п = гедитге(' с(111б_ргосезз') . зрэкп; сопзС 1з = зрэ«п('1з', ['-Нт', '/изг']); 1з.зтбоиС,оп( баСа , (баса) => { сопзо1е. 1од( зсбоиС: ${баСа}'); }); 1з.81бегг.оп(’баСа', (баСа) => { сопзо!е.1од( зСбегг: ${баСа}‘); }): 1з.оп('с1озе', (собе) => { сопзс1е,1од( сбт1б ргосезз ехИеб и1Нт собе ${собе}'); }); /(ругой пример команды: пр -0уг агсбтуе' ./ттаде.рпд ...может быть записан как: зраип(‘г±р', ['-0уг' агсптуе’, './Стаде.рпд ]); Создание оболочки для выполнения команды Для выполнения команды в оболочке, где требуется буферизированный вы: вод (то есть он не является потоком), используйте сМ1б_ргосез8 .ехес. Напри- мер, если вам нужно выполнить команду саС *.]б Г11е | нс -1 без дополни- тельных опций, это будет выглядеть так: сопзС ехес = геди!ге(' сбИб.ргосезз') .ехес; ехес(’саС *.]3 Г11е | «с -1', (егг, зСбоиС, зСбегг) => { (егг) { сопзо!е.еггог( ехес еггог: ${егг}’); геСигп; } сопзо1е.1од( зСбоиС: ${зСбоиС} ) ; сопзс1е.1од( зсбегг: ${згбегг) ’); }); Функция принимает до трех параметров
сЬ11а_ргосезз ехес(со™апб[, орЫопз][, саПЬаск]); Параметр солтагс! является строкой и обязателен, а объект орТюпз и саПЬаск — необязательными. Если объект орЫопз не указан, то ехес будет ис- пользовать следующие значения по умолчанию: { епсобтпд: 'иШ', ЫтеоиТ: 0. тахВиНег: 200*1024, кШ81дпа1 '816ГЕКМ , см): пиП, епу: пиП } Обьект орЬ1->пз также под держивает параметр зЬе11, кот орый по умолчанию равен /Ьхп/зЬ на СМХ и сшб. ехе на Мпскжз, параметр шб для задания иденти- фикатора пользователя процесса и параметр д 16 для задания группы. СаПЬаск, который вызывает ся после завершения выполнения команды, при- нимает три аргумента (егг. зТбоиГ, зТбегг). Если команда выполнена успешно, егг будет равен пиП, иначе это будет экземпляр Еггог, где егг .собе — это код завершения процесса, а е г г.зтдпа! - сигнал, который был отправлен для его за- вершения. Аргументы зТбоиТ и зтоегг представляют собой вывод команды. Он декоди- руется с помощью кодировки, указанной в объекте ортХопз (по умолчанию: стро- ка), по также может быть возвращен как объект типа ВоГТег. Существует также синхронная версия ехес. которая называется ехесЗупс. Син- хронная версия не принимает саПЬаск и возвращает зТбоо С вместо экземпляра СЬтХоРгосезз. Если синхронная версия сталкивается с ошибкой, она выбросит исключение и остановит выполнение программы Пример использования. сопзТ ехесБупс = гедо1ге( сЬ11с1_ргосезз').ехесЗупс; сопзТ зТбоиТ = ехес8упс('саТ *.]3 П1е | кс -1’); сопзоХе Ход( зибоиТ: ${з1:6оит} ‘; Создание процесса для запуска исполняемого файла Если вы хотите запустить файл, такой как исполняемый файл, исполь- зуйте сННсСргосезз.ехесЕПе. Вместо создания оболочки, как это делает сИПа_ргосезз .ехес, он напрямую создает новый процесс, что немного эффек- тивнее для выполнения команды. Функция может быть использована следую- щим образом; сопзт ехесЕНе = гедо1ге( ' сЬНсСргссезз') .ехесЕПе; сопзТ сИПс! = ехесЕ11е(' побе ’, ['--уегзХоп ], (егг, зТбоиг, зТбегг) => {
1Г (егг) { ТИго« егг; } сопзо1е.1од(81с1оа1); }): В отличие от сЬ11б_ргосез5 ехес эта функция принимает до четырех пара- метров, где второй параметр — массив аргументов, которые вы хотите передать исполняемому файлу: сЬ11б_огосе83. ехесЕ11е(ТПе [, агдз] [, орсюпз](, саПЬаск]); Формат орПопз и саПЬаск в остальном идентичен сИт 1с1_ргосея8.ехес. То же самое относится и к синхронной версии функции: согзГ ехесЕНеЗупс = геаи!ге('с1и1с1_ргосе8з') .ехесЕНеЗупс: сопзТ 81с1оиГ > ехесЕ11еЗупс(‘поЗе , ['--уегз1оп ]); сопзо1е.1од(зТс1си1);
Глава 30. Экспорт и использование модулей Примечания Хотя почти все в Мос1е.]8 выполняется асинхронно, функция героДгеО яв- ляется исключением. Поскольку модули па практике нужно загружать толь- ко один раз, это является блокирующей операцией, и ее следует использовать правильно. Модули кешируются после первой загрузки. Если вы редактируете модуль в процессе разработки, вам нужно удалить его из кеша модулей, чтобы исполь- зовать новые изменения. Тем не менее, даже если модуль очищен из кеша, сам модуль не будет освобожден сборщиком мусора, поэтому в производственных средах нужно быть осторожным. Примеры Загрузка и использование модуля Модуль можно «импортировать» или «подключить» с помощью функции герохгеО. Например, чтобы загрузить модуль Гр, который поставляется с Мобе. ]8, можно использовать следующий код: сопзЬ ИКр = г ери 1 ге (' ') ; Помимо модулей, поставляемых вместе с Мобе.]8, вы также можете подклю- чать модули, установленные через прт, например. Если вы уже установили Ехргезз на свою систему через прт хпзТаИ ехргезз, можно просто написать: сопз! ехргезз = герихге('ехргезз'); Вы также можете включить модули, написанные вами, как часть вашего при- ложения. В этом случае, чтобы подключить файл с именем 1хЬ. ] з, находящийся в той же директорше, что и текущий файл, сделайте следующее: сопзЕ ту!хЬ = гедохге('./1хЬ );
Обратите внимание, что расширение файла можно опустить, и будет подразу- меваться .]«. Как только модуль загрузится, переменная будет содержать объект, который включает методы и свойства, опубликованные из подключаемого фай- ла. Полный пример: сопзЕ ИМр = геяо1ге('ббтр1); // Модуль ИбГо содержит свойство 8ТДТ1)8_С00Е8 сопзо1е.1од(1тЩ:р.8ТАТ1)8_СООЕ8[404]); // выводит Ио! Роопб' // Также содержит метод сгеате8егуег() 1тс1:р.сгеа1:е8егуег(Гипс11оп(гед, гез) { гез ,«Г11:еНеаа(200. {'СопТетТ-Туре': ЧехЕ/Ыт! }); гез,иг11е(' <Ыт1><Ьобу>Моби1е Тезт</ЬэОух/НТт!* '); гез .епб(); }).ТтзРеп(80;: Создание модуля 1те11о шоНсЦз Мобе предоставляет интерфейс тоби!е ехрогТз для экспорта функций и пе- ременных в другие файлы. Самый простой способ сделать это — экспортиро вать только один объект (функцию или переменную), как показано в первом примере. КеПо-жтгГб. ;з тсс1и1е.ехрогСз = Гипс1::оп(зи0]ес1:) { сопзо1е.1од('Не11о ‘ + зиЬ]есС); }; Если вы не хотите, чтобы весь экспорт представлял собой один объект, можно экспортировать функции и переменные как свойства объекта ехрогТз. Три сле- дующих примера демонстрируют это немното по-разному: • КеПо-уепиз.)з: определение функции выполнено отдельно, а затем добавлено как свойство объекта тобо1е. ехрогЕз. • 1ге11о-]ир1Тег. ]з. определения функций напрямую помещены в значения свойств объекта тоби1е. ехрогСз. • ЬеПо-тагз. ]з: определение функции напрямую указано как свойство объекта ехрогтз, что является короткой версией использования тобиТе. ехрогтз. Ье11о-уепиз.]з ГипсИоп Пе11о(зиЬзест) { сопзо1е.1од( 'Уег.из зауз Не11о + зибдесС); }
тоби1е.ехрог1з = { Ье11о: Ье11о }; Ъе11о щрйегдз тойи1е.ехрогГз = { Ье11о Типс11оп(зио]ес1) { сопьо1е. 1од('Эирх^ег зауз Ье11о ‘ + зир]ес1:); }, Ьуе: ТипсИогЦзи^есг) { сопзо1е. 1од('Эириет зауз доос)Ьуе ' + 8иЬ]ес1:); } }; Ье11о-таг8.)з ехрогГз.ЬеНо = ТопсГ1оп(зиЬ]есГ) { сопзо1е ,1од('Магз зауз Не11о ' + зио]ес1); }; Загрузка модуля по имени директории V нас есть директория с именем Г1е 11 о. которая содержит следующие файлы: 1П(1ех.]з // Ке11о/1пСех.]3 пюби]е.ехрог1з = Типс11оп(){ сопзо1е 1од('Не]'); }; татдз // ИеПо/тахп.]з // Мы можем включить другие файлы, которые мы определили, с помощью метода геди1те() уаг 1т,- = геаи1те('./Не11 о-лог1с1.]'з ), Нт = геои1те(' ./ЬеПо-шагз. ]3 ’), Ну = геаи1ге('./ЬеПо-мепиз. ]з ), Ь] = геаи!ге('./Ье11о ]ир!гег.]з’), Ни = геои!ге('./1пбех.]з ); // Поскольку мы назначили нашу функцию всему объекту тссШе.ехрогСз , // мы можем использовать ее напрямую ’Иог1с1! '); // выводит "НеПо ИотЮ1 // В этом случае мы назначили нашу функцию свойству ЬеПо объекта ехрогтз', // поэтому нужно использовать это свойство здесь тоже
1тп.Ке11о( ' 5о1аг Зузтет!’); // выводит ' Магз зауз Не11с 5о1аг Зузгеп1!" // Результат назначения тобо1е ехрогТз в 11е11о-иог1б.]з такой же, как и в Пе1Ъ:-ууог1б. ]з Ьу.Ье11о('М11ку йау!’).' // выводит Уепиз зауз Не11о МПку Лау!" К] .Ье11о( 'Ьптуегзе1 '); // выводит _1ир11:ег зауз Ье11о бптуегзе1 11].Ьуе( Пшуегзе! ’); // выводит "ЭирзЛег зауз доойЬуе бшуегзе1 Ьи(); // выводит 'Ье] ’ Признание недействительным кеша модуля В процессе разработки вы можете заметить, что использование геди!ге() для одного и того же модуля несколько раз всегда возвращает один и тот же мо- дуль, даже если вы внесли изменения в данный файл. Это происходит потому, что модули кешируются при первой загрузке, и последующие загрузки модуля будут происходить из кеша. Чтобы обойти эту проблему, нужно удалить запись в кеше. Например, если вы загрузили модуль: уаг а = геаи1ге('./а'); ...затем можно удалить запись в кеше: уаг граТ1з = гедоДге.гезо1уе(‘./а.]з'); Ье1е1е г едид. ге. сасНе [гратй]; ...после чего снова загрузить модуль: уаг а = гедо1ге(' ./а'); Учтите, что это не рекомендуется в производственной среде, поскольку СеЗеСе удаляет только ссылку на загруженный модуль, но не сами загруженные данные. Модуль не будет собран сборщиком мусора, поэтому неправильное ис- пользование этой функции может привести к утечке памяти. Создание собственных модулей Вы также можете использовать объект для публичною экспорта и последова- тельно добавлять методы к этому объекту: сопзт аоДй = тоаи1е.ехрогтз = {} сопзС сопТлд = геди!ге('../сопГзд’) сопзС гедоезЬ = геди!ге('гедоезС’) аиГй.етаН = ТипсСюо (баГа, саНЬаск) { // Аутентификация с использованием етаН } аиТб.-расеЬоок = ГипсЫоп (ОаТа, саНЬаск) {
// Аутентификация с использованием аккаунта ГасеЬоок } аи1ЬЛиШег = Гипс1:1оп (Рата, саПЬаск) { // Аутентификация с использованием аккаунта ТиИГег } аи1И.51аск = ТипсТюп (РаТа, саПЬаск) { // Аутентификация с использованием аккаунта 31аск } аотЬ.зЬаск.оуегПой = ГипсНоп (аа1а, саПЬаск) { // Аутентификация с использованием аккаунта 81аск ОуегНо^ } Чтобы использовать любой из этих методов, просто подключите модуль, как обычно: сопз! ао1Ь = геци1ге(',/аи1ГГ) тос1и1е.ехроПз = ГипсПоп (гед, гез, пех!) { аитб -ГасеЬоок(гец.робу, ГопсТюп (егг, изег) { И (егг) гегигп пехД(егг) гед.изег = изег пех!() }) } Каждый модуль загружается только один раз Мо(1е.)8 выполняет модуль только при первом подключении Любые после- дующие вызовы геоитге будут использовать тот же объект, таким образом, код в модуле не будет выполняться повторно. Также Мойе кеширует модули при пер вой загрузке с использованием гещпге. Это снижает количество операций чте- ния файлов и помогает ускорить работу приложения. туМойи1е.)8 сопзо1е.1эд(123); ехрегез.уаг! = 4; тйехдз уаг а = геди!ге('./туМобиТе'); // Вывод: 123 уаг Ь = геди1ге('./туМоби1е'); // Вывода нет сопзо1е.1од(а.уаг1); // Вывод: 4 сопзо!е.1од(Ь.уаг1); // Вывод: 4 а.уаг2 = 5; сопзо!е.1од(Ь.уаг2); // Вывод: 5
Загрузка модуля из пос1е_то(1и1е8 Модули могут быть подключены без использования относительных путей, если они находятся в специальной директории пос1е_пюби1ез. Например, чтобы подключить модуль с именем Гоо из файла хпбех. ] з, мож- но использовать следующую структуру директорий: 1пОех.]з \- пос1е_тоаи1ез \- Гео |- Гоо.]з \- раскаде.]$оп Модули должны быть помещены в отдельную директорию вместе с файлом раскэде. ] зоп. Поле таю в файле раскаде. ] зоп должно указывать на точку вхо- да для вашего модуля — это файл, который будет импортирован, когда пользова- тели используют геди1ге(' уоиг-тобоХе'). Если таю не указано, по умолчанию будет использоваться юбех.] з. Кроме того, вы можете ссылаться на файлы отно- сительно вашего модуля, просто добавив относительный путь к вызову гедихге: гедихгеСуоиг- тобиХе/ра1б/1о/Гх]е'). Модули также могул быть загружены из директорий побе_тобиХез, располо- женных выше в иерархии файловой системы. Если у нас есть следующая струк- тура директорий: шу-рго]ес! \- побе_тос!иХез |- Тоо // модуль Гоо \- ... \- баг // модуль баг \- побе_тобиХез \- баг // модуль баг ...мы сможем подключить модуль Гоо из любого файла в баг с использовани- ем геди! ге('Гоо'). Обратите внимание, что Мобе будет загружать только тот модуль, который на- ходится ближе всего к файлу в иерархии файловой системы, начиная с директо- рии (текущая директория файла/побе_тобиХез). Мойе будет искать директории таким образом вплоть до корня файловой системы. Вы можете либо установить новые модули из прш-репозитория или других прт-репозпториев, либо создать свои собственные. Папка (директория) как модуль Модули могут быть разделены на несколько .р-файлов в одной папке. Пример в папке ту_тобиХе:
ГипсИоп опе.]8 тоби1е.ехрог1з = Типсгюп() { гегигп 1; } ГипсНоп Гиодз пюбиЗе.ехрсгДз = -ГипсИопО { геНигп 2; } тбехдз ехрсгГз Г_опе = геди1ге(' . /ТипсПоп.опе. ; ехроггз. = геди!ге('./ТипсМоп_1ио.); Такой модуль используется со ссылкой на него по имени папки: уаг зр11-(:_1пос1и1е = геаи1ге(' . /ту_то0о1е'); Учтите, что если вы подключаете модуль, опуская ./ или любое указание на путь к папке в аргументе функции г ери! г е, Хойе попытается загрузить мо дуль из папки побе_п1обо1е5. В качестве альтернативы вы можете создать в той же папке файл раскаде. ] зоп со следующим содержимым: { пате": ту..тоби1е , 'таю"; ./уоиг_та1п_епсгу_рс>1пг.]8'' } Таким образом, вам не обязательно называть основной файл модуля тгбех.
Глава 31. Экспорт и импорт модулей в (Модеме Примеры Использование простого модуля в №де.)з Что такое модуль в Хобе.]8? Модуль инкапсулирует связанный код в единое целое. При создании модуля это можно интерпретировать как перенос всех связанных функций в один файл. Ссылка на статью: ЬПр8://мтлто.8Йерот(.сот/ип(1ег8(аш1тй-п1ос1и1е-ехрог18- ехроП8-пос1е-]8/. Теперь давайте рассмотрим пример. Представьте, что все файлы находятся в одной директории: Файл: рпп(ег.]8 озе зСгхсТ'; ехрэгГ8.рг1псне11ойог1г| = Типсгьоп (){ соозс1е.1од( "Не11о Шог1с1!!!"); }
Другой способ использования модулей: Файл. апппак.р изо зГгтсТ'; тоби]е.ехрог1з = { Поп: ТипсШогД) { сопзо1е.1од("Й0ААРИ!! !") ; ) }; Файл: арр.]з Запустите этот файл, перейдя в свою директорию и набрав посе арр. ] з "изе 81Г1С1:'; //геои1ге(' ./ра'Г1'1/Ю/тос1и1е. ]з') указывает поОе, какой модуль загру- зить уаг ргТпТег = геро1ге( ./рппТег'); уаг ап1та1з = геди!ге('./ап1та1з’); рг1п1:ег.рг1п1НеПоИог1с1() ; // выводит НеПо Иог1бН| ап1та1з.11оп(); // выводит РОААЧР11!" Использование 1трог(8 в Е86 Мобе.]8 построен на современных версиях У8. Обновляясь до последних вер сий этого движка, мы обеспечиваем своевременное внедрение новых функций из спецификации }ауа8спрт ЕСМА-262 для разработчиков ТхГойецз, а также продол- жаем улучшать производительность и стабильность. Все функции ЕСМАЗспрт 2013 (Е86) разделены на три группы: отправляемые, подготовленные и находящиеся в разработке. Все отправляемые функции, которые У8 считает стабильными, включены по умолчанию в Мойефз и НЕ требуют никаких флагов времени выполнения. Под- готовленные функции, которые почти завершены, но не считаются стабильны- ми командой У8, требуют флага времени выполнения: --Кагтопу. Функции, на- ходящиеся в разработке, могут1 быть активированы индивидуально с помощью соответствующих флагов Кагтопу, хотя это крайне не рекомендуется, если толь ко для тестирования. Обратите внимание: эти флаги предоставляются У8 и могут изменяться без уведомления. В настоящее время Е86 поддерживает операторы импорта нативно. Итак, если у нас есть файл под названием -Гоп 1 з ехрсгт беГаиИ Гипссюл зау(ибаг){ сопзо1е.1од(и/ба1:); } ехрсг! Гипс-Поп зауЕоиЩиНосТ) {
$ау(йИооЕ.ГоиррегСазе()); } ...и если существует другой файл с именем арр. ]з. в который мы хотим им портировать ранее определенные функции, есть три способа сделать это. Импорт ио умолчанию ппрогС зау (тот './Рип'; зау('Не!1о ЗТаск ОуегГХол! ! ’); // Вывод: Не11о ЗТаск ОуегТЛол! Импортирует функцию зауО, потому что она помечена как экспорт по умол- чанию в исходном файле (ехро г! де^аиХг ...). Именованный импорт ГтрогС { зауЬоиб } Г^от './Тип', зауЬоиб('ЭЗ тобиЗез аге алезоте.’); // Вывод: ЭЗ М0Э1ЛЕ8 АРЕ АИЬЗОМЕ. Именованный импорт позволяет нам импортировать только те части модуля, которые нам действительно нужны. Мы делаем это, явно называя их, в нашем случае указывая зауЕоиб в фигурных скобках в операторе импорта. Групповой импорт ТтрогТ * аз 1 Тгот './Тип'; 1 зау( й'ИаТ?'); // Вывод: йИаТ? 1.зау1_оис1('МзооГ! '); // Вывод: ИНООТ! Если мы хотим иметь все экспорты, это лучший способ. Используя синтаксис * аз 1, оператор импорта предоставляет нам объект 1, который содержит все экс порты нашего модуля Тип как свойства с соответствующими именами. Пути Имейте в виду, что вам нужно явно указывать пути импорта как относитель- ные, даже если файл для импорта находится в той же директории, что и файл, в ко- торый вы импорт ируете с помощью./. Например, импорты из путей без префиксов 1трэгТ ехргезз Тгот 'ехргезз' ...будут искаться в локальных и глобальных папках (директориях) побе. тоаи1ез и вызовут ошибку, если соответствующие модули не будут найдены. Экспорт с использованием синтаксиса Е56 Рассмотрим другой эквивалентный пример, но с использованием Е56: ехрог! ТипсДХоп рг!п1:Не11с1Уог1б() { сопзоХе.1од("Не!1о Йог1б!!!"); }
Глава 32. Загрузка файлов Примеры Загрузка одного файла с использованием гпиИег Не забудьте: • создать папку (директорию) для загрузки (в примере - вр1оас1з); • установить ши1Тег: прт 1 -8 тиИег. 8ег*ег.]8: уаг ехргезз = геди!ге( ехргезз"); уаг тиИег = геди!ге( 'тиИег'); уаг арр = ехргезз(); уаг Тз = геаи!ге('Тз’); арр де!(, Гипс1юп(гед, гез) { гез.зепс!Е11е(_бхглате + 1 /хпбех.ИЬтГ ); }); уаг зтогаде = тиИег.д1зк81огаде({ безНпаНоп: ГипсНоп (гед Н1е, саНЬаск) { Гз,ткс!1г(' ./ир1оэЬз', ГипсЫоп(егг) { 1Г(егг) { сопзо1е.1од(егг зЬаск); } е1зе { са11Ьаск(пиН, './ир1оаЬз'); ) }); }, Шепате: Гопссюп (гед, ГНе, саНЬаск) { са11Ьаск(пи11, ГНе Г]е1апате + + Расе.поуу( )); } });
арр.розХ('/арХ/ГзХе', ТипеПоп(гед, гез) { уаг ирЧоаб = ти11ег({ зХогэде- зТогаде }) .зХпд1е( 'изегЕхХе'); ир1оаС(гед, гез, Типс1:1оп(егг) { ХТ(егг) { гетигп гез.епс1( Еггог ир1оас11пд НХе."); } гез.епЩ Е11е 13 ирХэабесГ); }); }); арр.Х131еп(30&0 ГипсНопО { сопзоХе.Ход( Йогкхпд сп рог! 3000"); }); 1пйех.Ь1ш1; <Гогт 1 с1-"ир 1оас1Гогт епс1уре-"ти1Нраг1:/Гогт-с1а1:а ас1Хоп= /арХ/ГХХе" теГНос1= розг. "> <1приХ Хуре="НХе" гате-"изегЕХ1е' /> <1приг Хуре= зиЬпиХ уаХие='СрХоао Е1Хе" пате="зиЬпнг"> </'Еогт> Примечание: чтобы загрузить файл с сохранением расширения, можно ис- пользовать встроенную библиотеку Мос1е.)з - раТб. Для этого подключите ра::П в файл зегуег.]з: уаг раТМ = геди1ге( раТб'); и измените: са11Ьаск(пи11, Т11е.ИеХдпате + + ОаХе пои()); ...добавив расширение файла следующим образом: саХХЬаск(пиХХ, ТНе.ТХеХсХпате + + ОаХе.пои() + раСК.ех1пате(ТХХе. огхдхпаХпате)); Как фильтровать загрузку по расширению В этом примере показано, как загружать файлы, разрешая только определен- ные расширения. Например, только изображения. Просто добавьте к уаг ирХоаб = тиХ1ег({ зеогаде: зтогэде }) .зХпдХе('изегГ1Хе’);условиеТХХеЕ1Хтег. уаг ирХоэС = тиХСег({ зХогаде: зХогаде, ТтХеЕХХТег: ТопсСгоп (гед, Т1Хе, саХХЬаск) { уаг ех! = ра1б.ех1пате(Т1Хе.огХд1паХпап1е);
1Т(ехг !== .рпд && ехС !== '.дрд' && ехг !«= ' .д!Т' && ехС !== ' .]ред') { гебигп са11Ьаск(пел Еггог(’0п1у нпэдез аге аПолесГ)); } са11оаск(па11, Сгие); } }) . з1пд1е( 'изегЕНе'); Теперь можно загружать только изображения с расширениями рп$, ]р^, дН или ]ре$с Использование модуля То'тпИаЫе Установите модуль и прочтите документацию: прт 1 ГогтюаЫе^ХаТезС Ссылка на документацию. Нкрз://2кНиЬ.сот/по(1е-Гогпш1эЫе/Еогт1с1аЬ1е. Пример сервера на порту 8080: уаг СогтдбаЫе = гедид ге( '^сгтдРаЫе ’), НПр = гедидге( ’ШГр'), иШ = геди!ге( 1Н1Г); Негр.сгеаСеЗегуецТипсИогЯгед, гез) { 1Г (гед.иг! == '/ир!сасГ && гед.теСНос!.СоколегСазе() == 'роз!') { // парсинг загрузки Файла уаг Гогт = пел богткбаЫе ,1псот1пдГогт(); Согт.рагзе( гед, Гипс1лоп(егг, СдеХНз, ТНез) { 1Т (егг) бо-зтСН; // обработка ошибки // Копирование файла из временного места // уаг Тз = гедигге(‘Сз');
// Тз.гепате('(:11е.ра1:11| <сагдетРагК> Типсгюп (егг) {...}); // Отправка результата клиенту гез.лг11еНеа<1(200. {'сопТепт-Туре' : 'ТехТ/р]а1п'}); гез.иг1Те( ‘ гесеТуес! ир1оаб:\п\п’), гез.епс1(иТ11.1пзрес1:({Т1е1с1з: Т1е1<1з, Т11ез: Т11ез})); }); геТигп, } // отображение формы для загрузки файла гез. 1Л'г1теНеас1 (200, { сопТепт-Хуре : 'ТехХ/Ьтт! }); гез .епЩ <Тогт асТ1оп="/ир1саР епсТуре="ти111раг-с/Тогт-с1а1г те!11ос1="роз1"> ’ + '<1при1 1уре="1ехТ пате= МТ1е"><Ьг>' + '<1при1 Гуре="Т11е папе=' ир1оа<1 ти1Х1р1е=''ти111р1е ' ><Ьг>' + '<1при1 Туре="зиЬ'П1Т" уа1ие="0р±сасГ>’ + ' </Тоггг> ’ ); }).1131еп(80&0);
Глава 33. Файловый ввод/вывод (ЕПезузгет 1/0) Примечания В Ыос1е.]8 ресурсоемкие операции, такие как ввод/вывод, выполняются асин- хронно, но имеют синхронный аналог (например, существует 65. геайРтДе и его аналог— Гз. геас1Е11е8упс). Поскольку Пойе.]з однопоточен, следует быть осто- рожным при использовании синхронных операций, так как они блокируют весь процесс. Если процесс блокируется синхронной операцией, весь цикл выполнения (включая цикл событий) останавливается. Это означает, что другой асинхрон- ный код, включая события и обработчики событий, не будет выполняться, и ваша программа продолжит ждать завершения единственной блокирующей операции. Существуют подходящие случаи для использования как синхронных, так и асинхронных операций, но нужно внимательно следить за тем, чтобы они ис- пользовались правильно. Примеры Запись в файл с использованием уугйеГНе или «уп1еЯ1е8упс уаг Ез = гери1ге('Тз'); // Сохраните строку "Не11о когЮ!" в файле КеИо.СхС // в каталоге "/бтр" с использованием кодировки по умолчанию (иТ"Е8). // Эта операция будет выполнена в фоновом режиме, и // обратный вызов будет вызван, когда она будет завершена или завер- шится ошибкой. Тз.йг!1еЕ11е('/±ггр/Ье11о . Тхт1, 'Не11о *ог1б! ’, Еипсбюп(егг) { // Если произвола ошибка, покажите ее и завершите выполнение 1Т(егг) гетит сопзо1е.егтг(егг); // Успешно записано в файл!
}): // Сохраните бинарные данные в файле с именем ’Ьюагу .тхт" // в текущем каталоге. Э’а операция также будет выполнена в фоновом режиме. уаг ЬиГТег = пел' ВиГГег([ 0x48, 0x65, 0x6с, 0хбс, ОхбС ]); Тб.ууг 11еГИе( Ьтпагу.СхС’ , ЬиСТег, ТипсС1оп(егг) { // Если произошла ошибка покажите ее и завершите выполнение 1Г(егг) геСигп сопзо1е.еггог(егг); // Бинарное содеожимое успешно записано в файл! }); Гз .йг11еЕ11е8упс ведет себя аналогично Тз.йгНеЕНе, но не принимает об- ратный вызов, так как выполняется синхронно и поэтому блокирует основной поток. Большинство разработчиков .Чобецз предпочитают асинхронные вариан- ты, которые практически не вызывают задержек в выполнении протраммы. Примечание: блокировка основною потока считается плохой практикой в Мойе.)8. Синхронные функции должны использоваться только при отладке или когда нет других вариантов. // Записать строку в другой файл и установить режим доступа к файлу на 0755 тгу { +8.и/г1ТеГ11е8упс( ’зупсЛхС’, 'аппт', { пюбс: 0о755 )); } сагсЩегг) { // Произошла ошибка гоояоГе.еггог(егг) ; } Асинхронное чтение из файлов Для всех файловых операций используйте модуль файловой системы: сопзС Тз = геди!ге('Тз'); С использованием кодировки В этом примере читается файл 1те11э. ТхС из каталога /Стр. Эта операция бу- дет выполнена в фоновом режиме, а обратный вызов будет вызван по заверше- нии или при ошибке: Сз. геабЕ11е('/1тр/1те11с СхС’ { епсобтгд: 'иСТб }, (егг, сопТепС) => { // Если произошла ошибка, выведите ее и завершите выполнение 1С(егг) гебигп сопзо1е.еггог(егг); // Ошибки не произошло, сопбепТ - это строка сог1зо1е.1од(соп1:еп1:); });
Без использования кодировки Считайте бинарный файл Ьюагу. СхС из текущего каталога асинхронно в фо- новом режиме. Обратите внимание, что мы не указываем опцию 'епсосНпд' — это предотвращает декодирование содержимою в строку в Ыойедз: Тз. геаОЕ11е(' Ьюзгу1, (егг, ОитагуСопТепС) => { // Если произошла ошибка, выведите ее и завершите выполнение 1Т(егг) геЮгп сопзоТе ,еггог(егг); // Ошибки не произошло, сопТепТ - это ВоТТег, выводим его //в шестнадцатеричном формате. сопзо1е.1од(сопСепТ.-1:оЗтг1пд(1 Мех’)); }); Относительные пути Имейте в виду, что ваш скрипт может быть запущен с произвольным теку- щим рабочим каталогом. Чтобы обратиться к файлу относительно текущего скрипта, используйте_бтгпате или_Т1]епате: Тз.геабЕ!1е(ратб.гезо!уе(___сНгпате. 'зотеЕ11е’), (егг, оТпэгуСоптепТ) => { }); // Остальная часть функции Список содержимого каталога с использованием теайгйт или геадсйгЗупс сопзТ Тз = геци1ге('Тз’); // Чтение содержимого каталога /изг/1оса1/Ып асинхронно. // Обратный вызов будет вызван, когда операция завершится // либо успешно, либо с ошибкой. Тз. геа<1с!1г('/изг/1оса1/Ь1п ’, (егг, ТНез) => { // В случае ошибки покажите ее и завершите выполнение тТ(егг) геЮгп сопзо1е.еггог(егг); // ТНез - это массив, содержащий имена всех записей // в каталоге за исключением (сам каталог) //и ..' (родительский каталог). // Отобоажение содержимого каталога сопзоТе 1од(Т11ез.;огп(' )); }); Синхронный вариант доступен как геаоб1г8упс, который блокирует основ- ной поток и, следовательно, предотвращает выполнение асинхронною кода в то же время. Большинство разработчиков избегают синхронных функций вво- да/вывода, чтобы улучшить производительность.
1е! Г11ез; Ггу { ТПез = Гз. геас!с11г8упс('/уагАтр ) ; } сагсЬ(ег г) { // Произошла ошибка сопзс1е.еггог(егг) ; } Использование генератора сопзТ: Гз = гедтге('Гз'); // Итерация по всем элементам, полученным через // выражения у!е1сГ // Обратный вызов передается функции-генератору, потому что // это требуется методом ' геаи<Лг' ГипсИоп гип(деп) { уаг Пег = деп((егг, ФаГа) => { 1Т (егг) { Пег .Итгои(егг); } гсхигп 11ег.пехТ(с1ага); }); 11ег пех1:(); } сопзг ЛгРа^Н = '/изг/1оса1/Ь1п'; // Выполнение функции-генератора гипАипсНоп* (гезите) { // Эмитирует список файлов в каталоге из генератора уаг сопгептз = уте1б Тз. геас!с11 г (с!1 гРагН, гезите); сопзо1е.1од(соп1епТз); }); Синхронное чтение из файла Для любых файловых операций вам понадобится модуль файловой системы: сопз!: Гз = геци1ге( 'Тз'); Чтение строки Тз. геабЕНеЗупс ведет себя аналогично I з. геабЕИе. но не принимает функ цию обратного вызова, так как выполняется синхронно и, следовательно, блоки- рует основной поток. Большинство разработчиков Хоскф предпочитают асин- хронные варианты, которые практически не вызывают задержек в выполнении программы. Если указан параметр кодировки, будет возвращена строка, в противном слу- чае будет возвращен ВоЕЕег.
// Чтение строки из другого файла синхронно 1еР сопРепР; Ргу { сопРепР = Тз. геас1Р11е8упс( 'зупс.РхР', { епсоскпу: 'иРТ8' }); } саРсЬ(егг) { // Произошла ошибка сопзо1е.еггог(егг); } Удаление файла с использованием ипНпк или ипНпкЗупс Удаление файла асинхронно. уаг Тз = геаи!ге('Тз'); Тз.ип11пк('/раРП/Ро/Г11е.РхР , ТипсРюп(егг) { 1Г (егг) РНгол егг; соП8о1е.1од(’ТПе ФеХеРес! ); }); Можно также удалить файл синхронно1: уаг Тз = геди!ге('Тз’); Гз.ип11пк8упс( /раГИ/Ро/ТНе РхР'); сопзо1е.1од('Т11е де1еРес! ); Чтение файла в ВиТТе г с использованием потоков Хотя чтение содержимого из файла уже является асинхронным при исполь зовании метода Тз. геас1РИе(), иногда мы хотим получать данные в виде пото- ка, а не просто в функции обратного вызова. Это позволяет передавать данные в другие места или обрабатывать их по мере поступления, а не все сразу в конце: сопзР Тз = геди!ге(' Тз ’); // Массив для хранения частей дачных файла 1ет сКипкз = []: // Эта переменная может использоваться для хранения окончательных дан- ных 1еР ТПеЗиТТег; // Чтение файла в зРгеат.ЧсаоаЫе 1еР ТИеЗРгеэт = Тз ,сгеаРеЧеас18Ргеат(' РехР .РхР ’); // Произошла ошибка с потоком 1 Избегайте синхронных методов, так как они блокируют весь процесс до завершения выполнения программы.
Т11е8Тгеап.оосе('еггог', (егг) => { // Обязательно обработайте это правильно1 соп5о1е.еггсг(егг); }); // Файл завершен чтением Т11е81геап.опсе( епб', () => { // создание окончательных данных ВиТТег из частей данных; Т11еВиТТег = ВиТТег.сспсаТ(сЬипкз); // конечно, бы можете сделать здесь все что вам нужно, например, сгенерировать событие1 }); // Данные передаются из ТПеЗСгеаш частями, // эта функция обратного вызова будет выполняться для каждой части Т11е81геа1г.оп('баТа', (сбипк) -> { сТшпкз.ризЩсЬипк); // добавление части данных в массив // Мы можем выполнять действия с частичными данными, которые у нас есть на данный момент! }); Проверка прав доступа к файлу или директории Тс. ассеззО определяет, существует ли путь и какие разрешения у пользова- теля есть для файла или директории по указанному пути. Тз. ассезз не возвра- щает результат; если ошибка не возвращается, путь существует и у пользователя есть необходимые права Режимы разрешений доступны как свойства объект а Тз, Тз. сопзТапТз: * Тз сопзТапТз.Е.ОК —Имеет права на чтение/запись,'выполнение (если режим не указан, это значение используется по умолчанию). • Тз. сопзТагПз. Я _0К — Имеет права на чтение. • Тз.сопзсаптз.Й-ОК — Имеет права на запись. • Тз.сопзТапТз.Х.ОК — Имеет права на выполнение (работает так же, как Тз .соп51ап1з.Г_0К на Шппйжз). Асинхронно уаг Тз = гецо1ге('Тз'); уаг раТб = '/раИт/То/сбеск’; // проверка прав на выполнение Тз .ассезз(раТ1т, Тз.сопзСапТз.Х_ОК, (егг) => { 1Т (егг) {
сопзо1е.1од("%з боезп'Е ех1з(: 1, рагб); } е!зе { сопзо1е,1сд('сап ехесиДе %з', раГЬ); ) }); // Проверка прав на чтение/записо // При указании нескольких режимов разрешений // каждый режим разделяется с помощью символа ’ | ' Гз.ассезз(ра1Ь. Гз.сопзтапТз й_ОК | Тз.сопз1ап1з.И_0К, (егг) => { 1Т (егг) { сопзо1е.1од( "%з боезп’1 ехДзР", раСН); } е1зе ( сопзо1е. 1од( 'сап геаб/лгие °4з’, раГН); } }); Синхронно (з.ассезз также имеет синхронную версию Гз.ассеззЕупс. При использо- вании Тз .ассеззЗупс необходимо заключить вызов функции в блок Егу/саЕсЬ. // Проверка права на запись 1гу { Г8.ассезз8упс(ра1б, Тз.сопзТапЕз.И_ОК); сопзо1е.1од('сап «Ш:е %з', раСб); } саТсб (егг) ( сопзо1е.1од("%з боезп'Т ех1зС , ра1Ь); } Избегание состояния гонки (гасе сопсййоп) при создании или использовании существующего каталога Из-за асинхронной природы Мойедз создание или использование директо- рии, сначала: • проверяя ее существование с помощью Тз .з!аг(), затем • создавая или используя ее в зависимости от результатов проверки существования, может привести к состоянию тонки, если панка (директория) создается между моментом проверки и моментом создания. Метод ниже оборачивает ( з. пкс!1г() и Гз ,ткб1г8упс() в обработчики ошибок, которые позволяют исключению про- ходить, если его код — ЕЕХ15Т (уже существует). Если ошибка другая, например. ЕРЕКМ (отказано в доступе), выбросите или передайте ошибку, как это делают нативные функции.
Асинхронная версия с Тз. ткскг () уаг Тз = геди1ге( Тз’); ТопсИоп ткбтг (ЛгРаТМ, саПЬаск) { Тз.ггксЛг(сИгРаТЬ, (егг) => { са11Ьаск(егг && егг собе !== 'ЕЕХ18Т* ? егг : пиП); }); } ткС1г(’./ех1зТ1пдО1г’, (егг) => { 1Т (егг) геТигп сопзо1е.еггог(егг.сос1е); // Здесь можно сделать что тс с ' ./ехюПпдОТг }): Синхронная версия с Тз .пкб1г8упс() ТипсПоп шкд1г8упс (ЬхгРаТЬ) { Сгу { Тз.ткй1г8упс(с11гРа1И); } саТсИ(е) { хТ (е.ссое !== ‘ЕЕХ18Т’) ТПгоуу е; } } ткахг8упс( ’. /еххзТхгд-бхг’); // Здесь можно что-то сделать с ' ./еххзТхпд-бзг Проверка, существует ли файл или директория Асинхронно уаг Тз = гедихге( Тз’); Тз.зСат( ’расЬ/То/ТтТе’, ТипсТхоп(егг) { хТ (!егг) { сопзо1е.1од(’Т11е ог сНгесСогу еххзТз’); } е1зе 1Т (егг.сос1е === ЕЫОЕМТ’) { сопзо1е.1од( ’ТПе ог ахгесСогу Ьоез по! еххзС’); } }); Синхронно Здесь следует обернуть вызов функции в блок Тгу/саТсИ для обработки ошибок: уаг Тз = геди!ге(’Тз’); Тгу { Тз.зСаТ8упс('раТЬ/Со/ТПе’);
сопзо1е 1од('ТПе ог дьгесХогу ехтзсз'); } саСсЬ (егг) { 1Т (егг.соде === 'ЕМОЕЫТ') { сопзо1е. 1сд(' ТНе эг дтгесСогу доез пот ех1з1'); ) } Клонирование файла с использованием потоков Эта программа иллюстрирует. как можно скопировать файл с использо- ванием потоков чтения и записи с помощью функций сгеа1:еРеад81:геат() и сгеаСеИг1СеЗ'1геат(), предоставленных модулем файловой системы. // Подключаем модуль файловой системы уаг Тз = геди!ге('Гз'); /* Создаем поток чтения для файла в текущей директории („сНгпате) с име- нем 'поде.1x1' Используем кодировку и1Т8 Читаем данные кусками по 16 килобайт */ уаг геаоаЫе = Гз.сгеа1еПеад8(:геат(___дтгпате + '/поде.1ХТ', { епсодгпд: 'и1Т8', ГидПИаСегМагк: 16 * 1024 }); // создаем поток записи уаг игИаЫе = Тз.сгеаГеИг1Ле81:геап1(___дтгпате + '/пооеСору.1x1'); // Записываем каждый кусок данных в поток записи геадаЫе.оп( 'дата', Типс11оп(с1типк) { ипГаЫе.игтЛе^Иипк) ; }); Копирование файлов с использованием соединения потоков Эта программа копирует файл с использованием потока чтения и записи с по- мощью функции ртре(), предоставленной классом потока. // Подключаем модуль файловой системы уаг -Гз = гедо!ге(' Тз ’); /* Создаем поток чтения для файла в текущей директории с именем 'поде. 1x1'
Используем кодировку ис18 Читаем данные кусками по 16 килобайт */ /аг геаРаЫе = 1з.сгеа1еЧеаР81геат(__сИгпате + /поре 1x1’, { епсобхпд: '0118', ГндИИаСегМагк: 16 * 1024 }); // создаем поток записи уаг игИаЫе = 1з.сгеаГейг11е8Ггеат(____(Игнате + 1 /побеРТре.Гх!'); // используем ргре для копирования из потока чтения в поток записи геабаЫе.р1ре(иг11аЫе) ; Изменение содержимого текстового файла Моп^оозе заменяем слово етаИ на пате в текстовом файле 1пбех.1х1 с ис- пользованием простого регулярного выражения тер1асе(/етаП/дтт, 'пате ): уаг 1з = геро1ге(’1з’) ; 1з.геабЕТ1е(’1пг1ех.1х1', ’о11-8’, 1ипс1юп(егг, ба!а) { 11 (егг) 111 гои егг; уаг пелУаТое = ба!а. гер1асе(/ета11/д1т, пате’); 1з иг11еР11е('1пбех.1хг , пелУаТие, '011-8 , 1ипс1юп(егг, ба!а) { 11 (егг) 1Кгои егг; сопзо!е.Тод(‘Оопе!’); }); }); Определение количества строк в текстовом файле арр.]5 сопз! геайИпе = гедз1ге( ’ геас111пе ); сопз! 1з = гедо1ге(’1з’); уаг 111е = ’ра1Е|.1о.1Т1е'; уаг ИнезСоип! = 0: уаг г1 = геаб11пе.сгеа1е1п1ег1гсе({ 1при1: 1з.сгеа1еЧеао81геат(111е), ои!ри1: ргосезз.зСбои!, 1егт1па1: 1а1зе }); г1.оп(’Ипе’, 1ипс11оп (Нпе) { ]1пезСоип1++; // при каждом разрыве строки добавляем +1 к ’ТтпезСоипГ' });
г1.оп('с1озе', ТипсбТол () { соп5о1е.1од(11гезСоип1:); // выводим результат при вызове события ‘с1озе’ }); Использование: побе арр Чтение файла построчно арр.]5 сопзб геабИпе = геди!ге(' геабИпе ); сопзб Тз = гери1ге('Тз’); уаг Т11е = оатН.То.ТИе ; уаг г1 = геабИпе,сгеа1:е1пСегТасе({ Тприс: Гз ,сгеа1еРеаб51геап1(Т11е), оибриТ: ргосезз.зТбоиТ, Тегпйпа!: Та1зе }); г1.оп(' 11пе ' , ТипсПоп (1хпе) { соп8о1е.1од(Ипе); // вывод содержимого строки при каждом разры- ве строки }); Использование: побе арр
Глава 34. Начало работы с профилированием Иос1е.]8 Введение Цель этой главы — познакомит ься с профилированием приложения на Хойе.] 5 и научит ься анализировать результаты для обнаружения ошибок или утечек па мяти. Запущенное приложение на \ос1е,]8 — это процесс движка У8, который во многих аспектах схож с веб-сайтом, работающим в браузере Мы можем полу- чить все метрики, связанные с процессом веб-сайта, и для приложения Хойе.]я. Инструмент — Сйготе ЦеуТоок или Сйготе 1пзрестог в сочетании с побе- тпзресДог Замечания Иногда побейпзресюг не удается прикрепиться к процессу отладки ТЧойсцз, в результате чего вы не сможете установить точку останова в ЦеуТоок. Попро- буйте несколько раз обновить вкладку ЦеуТоок и подождите несколько секунд, чтобы убедиться, что она находится в режиме отладки. Если это не поможет, пе- резапустите побе-1п$рес1ог из командной строки. Примеры Профилирование простого приложения на Мос1е.]8 Шаг 1. Установите пакет побе-тпзресТюг глобально на вашем компьютере с помощью при: $ прт бпзСаП -д побе-1пзрес1:ог Шаг 2. Запустите сервер побе-тпзресюг: $ побе-тпзресТог
Шаг 3. Начните отладку вашего Хо(1е.]8-приложения: $ побе --йеЬид-Ьгк уоиг/збогт/поое/зсгю]: . ]5 Шаг 4. Откройте Ы_1:р://127 Э Э.1’8О80/?рог1:-5858 в браузере СЬтоше. Вы увидите интерфейс СЬготе ВеУГоок с исходным кодом вашего приложения на Ноде.]5 в левой панели. Так как мы использовали опцию себод Ьгеак при от- ладке приложения, выполнение кода остановится на первой строке. • • р нолчижли ягда С 127.0.0.1:В0807?»я-)27.0.0.1:в080а(Ю(|-585в О. имп |*0<пм. »оли> Сопим Х= * ) $00^» «<««"• ю- Зтрмн (0 *оо )<1 'Ж94 адр |> Ы * кого тосЮКм • О Пй II ’ □имг5/*1|«я/Рго1ога/ыоо/по^ ► О пойе_пкх1иК1 ► О гои<«1 ► СКегмсм — «₽!« ! 0 о ► *крЬ Ьрг«И10П> + С ▼ Саи $иск Азупе 1 Пигспое («доп*. гсяихпе, •оаИа, _Шс*>аги, __ 2 • П1е I *©₽]» 3 • Ревсприол I Ва«к слргсм адеиоиаг. Мо4и!< _соп1р«й м<хЫ« |1 43$ • «аг '«ндев • г«4.»г«(',/гвшц»/хл1ея'1: « !• уяг *ор - «яргекО] 11 11 // *л»1л« вс1ир 13 *©р.К1( ‘«1М'Ь )01Л(_в1ГГ*»е'. 14 *ор.1е»('«1«н еЛС1пе’, 'Г)!'); 15 арр.иве(емргем.наг 1с(рмг.)о1л(_вхгпвче, 'риЫИ’Н): 1* 17 арр.ивеС/', гои(ев): 1В !• // смс* 4М г о гм» го ю еггог калоиг 7» арр.ы«еИи»сс1оп(гео. ге», гем Я { 21 *«Г егг • 1ИЛ» Еггог('Чо( Р№1Л<Г I: О 11пе 5. Со1итл 1 тойи1« |1 442 М{х1и1« _ех{<л1Ю«и 0 мосМеЮар Мойик _кмо мосыешпьим и*ЮпТпп«оцс 5сор» УалаЫ<» иос*1 __Й1гг*ге: • __Нлгам: а«р1 ипа«»1л*в •> с>рогц; ОЫесс трйи1»И 356 тобиЙ ц 311 тойи1«.|г467 ,]1 92 ивегмаисОР. Шаг 5. Это самая простая часть — переключитесь на вкладку профилирова- ния и начните профилирование приложения. Если вы хотите получить профиль для конкретного метода или потока, убедитесь, что выполнение кода приоста- новлено непосредственно перед выполнением этого участка кода. (?) Мое* «гарасаег П»7/Д м 0 й 127.0.0.1 8080/?уг5-127.0.0Л:8080&РОП-5858 • ® ггоЛю Спп>0« $е!ест рго(|||пд 1уре >3 ₽ 3. СоИ«с« _)а*4$сг1р1 СРО РгоГНе СР1) ргаПйа *Ъо**Ьеге Же ежесиНоп Нт» I» &репг 1п уоиг рад*'* ]а*а5сг1р| (илсНопа Т»ке Неар $л«р|Ьо! Неар вларвЬо: ргоПкв «Ном те тогу бЫНЬиНоп атопд уоиг радеЧ ]<уа$сг1р1 оЬ]еси алй «М1м1 ООМ гтоде! Я»сог<1 Неар АНосаНолз Яесог<1 )ау*5спр! оЬ)«1 аПосаНоп» а*ег Нте. 0«е 1М* ргоШе гуре ю ВЫ«не тетогу 1мк». шаа Шаг 6. После того как вы записали ваш профиль СРП или снимок/снимок кучи, шли выделение памяти кучи, вы можете просмотреть результаты в том же окне или сохранить их на локальный диск для дальнейшего анализа или срав- нения с другими профилями.
Вы можете воспользоваться следующими статьями, чтобы узнать, как читать профили: Кеайтц СРП РгоШез: кпр8://соттап|Шпе1:апа[1С.сот/сй1-Ып/зЬо\уагг1с1е. с#1?агНс]е=апО37. СНготе СРЧ ргоШег апс! Неар ргоШег: Шцэ8://йсур1орег сШоте.сот/с1ос<;/ беу1оо18?Ы=ги.
Глава 35. Хороший стиль кодирования Примечания Мы рекомендуем начинающим разработчикам использовать хороший стиль кодирования. И если кто то может предложить лучший способ, будем рады лю бым предложениям. Заранее спасибо. Примеры Базовая программа для регистрации На этом примере мы рассмотрим, как разделить код Мойе.]5 на разные моду- ли/папки для лучшего понимания Следование этой технике облегчает другим разработчикам понимание кода, так как они могут сразу обратиться к соответ- ствующему файлу вместо того, чтобы просматривать весь код. Основное преи- мущество данного подхода проявляется, когда вы работаете в команде, и новый разработчик присоединяется на более позднем этапе — ему будет проще разо- браться с кодом. тйех.)8 — этот файл управляет подключением сервера. // Импорт библиотек ^аг ехргезз = гедихте( 'ехргезз'), зеззюп = герс11ге( ехргезз-зеззхоп'), топдоозе = гедохге('топдоозе’), гедиезС = гедитге('гедиезС'); // Импорт пользовательских модулей уаг озегРооТез = гедих'-е( ‘ . /арр/гэитез/озегРои-Сез'); уаг соп-Гхд = гедихте('./арр/соп^хд/соп^хд’); // Подключение к МопдоЭВ топдоозе .соппесНсопТхд. деТ0В31гхпд());
// Создание нового приложения Ехргезз и его настройка уаг арр = ехргезз(); // Настройка маршрутов арр,изе(сопС1д.Ар1_РАТН, изегРоиСез()); // Запуск сервера арр.11з1:еп(сспТ1д.Р0РТ); сопзо!е.1од('Вегуег зСагСес! ас - + сопТтд.КРк + + сопТтд.РОРТ); сопЩ>.)8 — этот файл управляет всеми параметрами конфигурации, которые останутся неизменными на протяжении всего проекта. уаг сопГтд = { УЕР810М: 1, В1ЛЮ: 1 ОРЬ: 'ЫСр://127.0.0.1', АР1_РАТН ’/арт РОРТ : ргосезз елу.РОРТ || 8080, ОВ { // Конфигурация МопдоОВ НОЗТ : '1оса1ЬозГ.', РОРТ . '27017', 0АТАВА5Е : 'сП)' }, /* * Получить строку подключения к базе данных МопдоОВ */ деЮВЗУппд . ТипсПоп(){ геСигл топдос!Ь://' + тЫз.ОВ НОЗТ + + сЬтз.0В.РОРТ + '/' + Шз.ОВ.ОАТАВАЗЕ; }, /* * Получить НКр 1)Р1_ */ деСНТТРОг! : Сипс1:1оп(){ геСигп 'ЫСр://' + С1т1з.11Р0 + + СГиз.РОРТ; } } тобиТе.ехрогСз = согИд; изег.)з — модельный файл, в котором определена схема. уаг топдоозе = геди!ге( топдоозе’); уаг ЗсПета = топдоозе.ЗсЬета;
// Схема для пользователя уаг КзегЗсНета = пел 8с11ета({ пате: { Гуре: 8Гг1пд, // гедиггрс): Ггие }, ета11: { Гуре: 8Гг1пд }. раззлого: { Гуре: ЗГппд, // гедихгес!. Ггие }, доЬ: { Гуре: ОаГе, // гедиХгей: Ггие }. депс!ег: { Гуре: 8Гг1пд, // Ма1е/Еета1е // гедихгес!' Ггие } }); // Определение модели для пользователя уаг Пзег; 1Т(топдоозе тоае1з.изег) Озег = топдоозе.тобе!('Ьзег') ; е!зе Озег = топдоозе.тойеЦ'Ьзег', изегЗсЬета); // Экспорт модели Озег тос1и]е.ехрогГз = Озег; изегСопггоПег — этот файл содержит функцию для регистрации пользова- теля. уаг Озег = геди!ге('../тойеХз/изег'); уаг сгурГо = геди!ге('сгурГо ); // Контроллер для пользователя уаг ЦзегСопГгоНег = { // Создание пользователя сгеаГе: ТипсГ1оп(гед, гез){ уаг геразз^ого = гед Гюау.гераезиогсГ уаг раззиогс! = гео.ЬоРу.разз'логО;
уаг изегЕтаи! = гед.Ьоау,ета11; // Проверка существует ли уже адрес электронной почты 11зег Л 1по({ ’етаП": изегЕтаа.!}, Гипс11оп(егг, изг){ 1Т(изг 1епд1Г1 > 0){ // Электронная почта уже существует гез.]зоп(’Ета11 а1геабу еххзСз'); гетигп: } е1зе { // Новый Ета11 // Проверка на совпадение паролей 1Прэззиогб != гераззногс!){ гез.]зоп('Раззл’ОгРз бо по! таТсЬ'); геТигп; } // Генерация хеша пароля на основе з1па1 уаг зЬазит = сгурЮ.сгеаСеНазМ зЬа1'); зЬазит.ирба1е(гед.Ьобу.разовогб); уаг раззйогбНаз1п = зЬазит б1дез1('Ьех'); // Создание пользователя уаг изег = пел 11зег() ; изег.пате = геа Ьобу.папе; изег.етаИ = гед.Ьобу.етаа1; изег. раззто.-б = раззлогбНазЬ ; изег.боЬ = 9аСе.рагзе(гед.Ьобу.боЬ) || изег.депбег = гед.Ьобу.депбег; // Валидация пользователя изег. уа11ба1:е( Гипс1Лоп( егг) { 1^(егг){ гез.]зоп(егг); геТигп; }е1зе{ II Наконец, сохранение пользователя изег ,зауе( Гипс1:1оп(егг) { 1Т(егг) { гез.ззоп(егг); ге(:игп;
// Удаление пароля перед отправкой данных пользователя изег.раззлогб = ипбеТтпеа; гез.]зоп(изег); гегигп; }); } }); } }); } } тойиЗе.ехроггз = КзегСоШгоИег; изегВои1ез.)8 — это маршрут для изетСоШтоПег. уаг ехргезз = герыге( ехргезз’); уаг ПзегСопГгоНег = герихге( ’../сопТгоИегз/изегСопТгоИег’); // Маршруты для пользователя уаг ОзегРоиДез = Типсгюп(арр) { уаг гоиТег = ехргезз.РоиСег(); гоиХег гоите(’/изегз’) .роз1(изегСоп-Гго11ег .сгеаСе); геТигп гоиСег; } тюбиЕе. ехрсгДз = ПзегРоиСез; 11риведенный выше прим ер может показаться большим, ио если начиттающий в \обе.]з с небольшими знаниями Ехргезз подробно разберется в нем, он найдет его простым и действительно полезным.
Глава 36. Корректное завершение Примеры Корректное завершение — 81СТЕРМ Используя зегуег .с!озе() и ргосезз ех11(), мы можем перехватить ис ключение сервера и выполнить его корректное завершение. уаг Гн Со = геритге('пССр'): уаг зегуег = ПКр.сгеэТеЗегуег^ипсИоп (гед, гез) { зе1Ти11еоиТ(Гипс11О11 () { // симуляция долгого запроса гез.уугИеНеас!(?Я0, {'СопТепТ-Туре': ЧехТ/рХазп'}).’ гез.епс!('Не11о Мог1с1\п'); }, 4000); }) .11зСеп(9090, ГипсПоп (егг) { сопзо1е. 1од(' 115сеп1пд НКр://1оса11тоз1:9090 /'); сопзо1е.1од( рте! 1з ' + ргосезз.ртд); }); ргосезз.оп('816ТЕРМ', ^ипстюп () { зегуег .с1озе(1Гипс1:1оп () { ргосезз .ехиСО) ; }); });
Глава 37. 6гип1 Примечания Дополнительные ресурсы: Руководство 1пь1а11тд Сгип1 (1зйр8://§гип(]5.сот/ш8(а11т8-8гип0 содержи! под- робную информацию об установке конкретных версий Сгпп! и ягиШ-сИ для ис- пользования в продакшене или в процессе разработки. Руководство СопН^пппй Та.зкз (М{р8://(Цшп!)8.сот/сопГ1§ипп§-!а8к8) предостав- ляет детальное объяснение того, как настраивать задачи, цели, опции и файлы в СгипСШе, а также объясняет шаблоны, шаблоны с глобальными паттернами и импорт внешних данных.
Руководство Сгеапп^ Тахкз (кПрз:.78гиЩ)8.сот/сгеа11п§-тазк8) описывает раз- личия между типами задач в Сгипг и показывает примеры задач и конфигура- ций. Примеры С'ведение в Сгип1.]8 СгиШ — это }ауа$спр! Тазк Киппег, используемый для автоматизации повто- ряющихся задач, таких как минификация, компиляция, модульное тестирова- ние, проверка кода и т. д. Для начала работы вам нужно установить интерфейс командной строки (СЫ) Сгипг глобально. прт 1пеГэ11 -д дгипД-сИ Подготовка нового проекта Сгипг типичная настройка включает добавление двух файлов в ваш проект: раскаде.]зоп и ОгипННе. оаскаде. ] зоп: этот файл используется прт для хранения метаданных о проек- тах. опубликованных как модули прт. В этом файле вы перечислите Сгипг и необ- ходимые для вашего проекта плагины СгипГ как аеV^ерепс^ет^с1ез. 6гип1:Т11е: этот файл называется С г иптТ Не. ]з и используется для настрой- ки или определения задач и загрузки плагинов Сгипг. Пример раскадедзоп. { "пате : ту-рго]ес1-пате , "уегз1оп": "0.1.0", "беуОерепбепстез . { дгипГ": '-0.4.5 , "дгипТ-соп^гю-ззбтпТ": "-0.10.0 , "дгип1:-сопг:г1Ь-пос1еипИ': "-0.4.11 , "дгипС-сопСгтЬ-идНТу": "-0.5.0 } }
Пример СгипНИе: тоби!е.ехрог1з = Типс11оп(дгип1:) { // Настройка проекта. дгипт. 1п1сСопТ1д({ ркд . дгипС Т11е. геас!380Гм( 'раскаде ]зоп'), ид!1Ту: { орПопз: { Ьалпег: '/*! <%= ркд.пате %> <%= дгипГЛетрТаТе Юбау( "уууу-тт-с1сГ) %> */\п' }, риг1с1: { зге: 'згс/<%= ркд.пате %> ]з', Сез1: Ьи 11с1 /<%= ркд.пате %>.т1п.]з' } } }); // Загрузка плагина, который предоставляет задачу идИ Ту" дгип!.1оасМртТазкз(' дгипТ-сопТгдЬ-идНТу ’); // Задача по умолчанию. дгипт.гед1з1егТазк( бе^аиП:’, ['ид11Ту']); }; Установка плагинов 6гип1 Добавление зависимости Чтобы использовать плагин СгипТ, сначала нужно добавить его как зависи- мость к вашему проекту. Возьмем в качестве примера плагин ] збхпт. прт тпзСаП дгипТ-сопТгЦ?- ззМпт: --зауе-беу Опция --зауе беу используется для добавления плагина в раскаде. ] зоп. что- бы он всегда устанавливался после команды прт 1пз1а 11. Загрузка плагина Вы можете загрузить вага пл а гин в файле С г и п г Т11 е с помощью 1оасМртТазкз. дгопТ .1оасМршТазкз( дгипС-сопХпЬ д зНхпТ ’); Настройка задачи Вы настраиваете задачу в ЗгиптТ11е. добавляя свойство ]зЫпт в объект, пе- редаваемый д гипГ.тптгСопТ гд. дгип1.1п1ТСопТ1д({
]5П1пс: { а!1: [ Сгип1:Г11е.]5’, 11Ь,'**/*.дз', без!:/**/* . ]3 ’ ] } }); Не забывайте, что вы можете добавлять другие свойства для других плагинов, которые используете. Запуск задачи Чтобы запустить задачу с плагином, вы можете использовать командную строку: дгипС ]зК1п1 ...или вы можете добавит}, ] зК 1п1 к другой задаче: дгипС. гедтзСегТазЦ ’ беГаиИ ’ [ ]з№пб ]); Задача по умолчанию запускается с помощью команды дгипХ в терминале без каких-либо дополнительных опций.
Глава 38. Совет по упрощению работы Добавление новых расширений в гедшге() Вы можете добавить новые расширения в геоитгеО, расширяя гериТге. ехтепзюпз. Пример для ХМЬ: // Добаепяем ,хт1 для гери1ге() герихге.ехТепзюпз[ ' .хт! ] = (тоРи1е, ТПепате) => { сопзТ Тз = герлге( 'Тз') сопзТ хт1?]з - гери!ге(' хгп12) з ’) пос1и1е.ехро1-(:5 = (саПЬаск) => { // Читаем требуемый файл. Тз геабЕ11е(ТПег.ап1е, 'иТТ8 , (егг, баТа) => { 1Т (егг) { са]1Ьэск(егг) гетигп } // Парсим его. хт12]з.рагзе8Тг1пд(6а1а, (егг, гезиИ) => { са11Ьаск(пи11, гезиИ) }) }) } } Если содержимое файла ЬеПо. хт1 следующее: с^хт! уег51оп="1.0 60006109='ОТЕ-8 '’> <Тоо> <Ьаг>Ьаг</Ьаг> «щих /> </Тоо>
...вы можете прочитать и распарсить ею через гери!ге(): гери1ге('./Ье11о')((егг, хш1) => { 1Г (егг) ТЬгои егг; соп5о1е.1од(егг); }) Это выведет{ 1оо; { Ьаг: [ Ьаг' ], рих; ['']}}.
Глава 39. Обработка РОЗТ-запросов в Замечания Ыобе.)8 использует потоки для обработки входящих данных. Цитата из документации: Поток (ыгеат) — это абстрактный интерфейс для работы с потоковыми данными в Мос1е.]8. Модуль зггеап предоставляет базовый А.Р1. который облегчает создание объектов, реализующих интерфейс потока. Источник- 11цр8://по(1е]8.ог§/ар1/81:геат.йГ1п1#8Сгеат_8(геап1 Для обработки тела запроса РО8Г используйте объект запроса, который явля- ется читаемым потоком. Потоки данных передаются в виде событий баТа на объ- екте запроса. героезД.оп('баДа', сбопк => { ЬоНег += сКипк; }); гериезД.оп( епб’, () => { // Тело Р08Т-запрооа теперь доступно как оиТТег });
Просто создайте пустую строку буфера и добавляйте в нее данные буфера по мере их получения через события баса. ПРИМЕЧАНИЕ 1. Данные буфера, полученные при событиях ба1а. имеют тип ВоГГег. 2. Создавайте новую строку буфера для сбора буферизованных данных из событий баСа для каждого запроса, то есть создавайте строку буфера внутри обработчика запроса. Примеры Пример сервера на Хойе.]8, который обрабатывает только РО8Т-запросы: 'иве зСгхсС’; сопзС 1ПДр = гери1ге( ‘ ЫТр'); сопзС РОРТ = 8080; сопз! зегиег = Негр.сгеаСеВегуегД (гедиезС, гезропзе) => { 1ет би'Иег = ' ’; гедиезС.оп(’баТа’, сбипк => { ЬиТГег += сбипк; }); гедиез'С.оп( 'епб , () => { сопз! гезрогзеЗТгхпд = Ресехуео зСппд ${ЬиТ-рег) ; сопзо1е 1од( Резрспбхпд «ПК: ${гезропзе81гхпд} ); гезропзе.игх!еНеаб(200, СопТепх-Туре: ХехХ/рЗахп"); гезропзе,епб(гезрспзеЗТгхпд); }); }) .11з(:еп(РСАТ, () => { сопзс!е.1од('ктзсепхпд оп ${РОРТ}‘); });
Глава 40. Как загружаются модули Примеры Режим глобальной установки Если вы установили Хойе с использованием стандартного каталога, при ра- боте в глобальном режиме ХРМ устанавливает пакеты в /изг/1оса1/11Ь/пойе_ тойиЗез. Если вы введете в оболочке следующую команду, ХРМ будет искать, за гружать и устанавливать последнюю версию пакета с именем зах в каталоге /из г/1оса1/11Ь/пойе_тойи1ез/ ехргезз: $ прт 1пзГа11 -д ехргезз Убедитесь, что у вас есть права доступа к этой папке. Данные модули будут доступны для всех процессов Хойе, которые будут выполняться на конкретной машине. При установке в локальном режиме ХРМ загрузит и установит модули в теку- щем рабочем каталоге, создав новую папку с именем пойе..тойи1ез. Например, если вы находитесь в каталоге /1юте/изег/аррз/п1у_арр, то будет создана новая папка /11оте/изег/арр8/п1у_арр/пойе_<т1ос1и1ез, если она еще не существует. Загрузка модулей Когда мы ссылаемся на модуль в коде, Хойе сначала ищет папку пойе_тоби1е внутри папки, указанной в инструкции гедоХге. Если имя модуля не является относительным и не относится к основным модулям, Хойе попробует найти его внутри папки пойе_шойи1ез в текущем каталоге. Например, если вы выполните следующее. Хойе попытается найти файл ./пойе_тойо]ез/туМойи1е. ]з: уаг туМойоХе = гедлге('туМсйи1е.]з'); Если Хойе не удается найти файл, он будет искать его в родительской пап- ке ../пойе_тойи1ез/п1уРойи1е ]з. Если поиск снова не удастся, он продолжит поиск в родительских папках, пока не достигнет корня или не найдет требу- емый модуль.
Вы также можете опустить расширение ,]5, в этом случае Мобе добавит расши- рение .] а и будет искать файл. Загрузка модуля из папки (директории) Вы можете использовать путь к папке для загрузки модуля следующим об- разом: уаг туМоби1е = геди!ге(‘./туМоои1е01г'); Если вы это сделаете, Мойе будет искать внутри этой папки. М обе будет счи- тать, что эта папка является пакетом, и попытается найти определение паке- та. Это определение пакета должно быть файлом с именем раскаде . ]зоп. Если в этой папке нет файла определения пакета с именем раскаде. ]зоп. точка вхо- да пакета будет считаться по умолчанию 1пбех.]з, и Мобе будет искать файл по пути /туМобс1е01г/1пбсх.]з. Последним вариантом, если модуль не найден ни в одной из папок, будет гло- бальная папка установки модулей.
Глава 41 НТТР Примеры НТТР-сервер Приведем простой пример НТТР-сервера. Напишите следующий код в файл (тЩр.зегуег. ]з: уаг Кедр = геди1ге(' Икр'); уаг НССрРогС = 89 ИС Пр .сгеаСе8егуег(Иапс1ег) .11зСеп(ЬССрРогС, зСагС.саПЬаск); ТипсИоп Ьапс11ег( гед, гез) { уаг с11епт1Р = гед.соппесСюп. гетоСеАйОгезз, уаг соппесСОзшд = гея соппесСТоп.епсгурСей ? 881’ : 'НИР', сопзо1е.1од( РедиезС гесеСуей: ' + сопоестизьпд + ' ‘ + гед.теСКой + ' ' + гея иг1); сопзо1е.1од('СИепС 1Р: ' + с11епС1р); гез.«г1СеНеай(20Ч, ОК", {'СопСепС-Туре': 'сехС/р1а1п'}); гез.иг1Се(' ОК"); гез.епй(); геСигп; } СипсИоп зСагС_са11Ьаск(){ сопзо1е.1од(’ЗСагС НТТР оп рог1 + ИССрРогС) } Затем из расположения вашего файла ИЩр_зегуег. ]з выполните команду: пойе Нтгр_зегуег.]з Вы должны увцдеть следующий результат: > ЗСагС НТТР оп рог! 8Э
Теперь вам нужно протестировать сервер, открыв интернет-браузер и перей- дя по следующему Ъ’КЕ: 1тЩр://127.0.0.1 80 Если ваша машина работает под управлением Ьших-сервера, ьы можете про- тестировать его следующим образом: сиг1 127.0.0,1:80 Вы должны увидеть следующий результат: ок В вашей консоли, где запущено приложение, вы увидите такие результаты: > РериезТ гесетуеб, НТТР СЕТ / > С11еп-С 1Р: : :ТШ:127.0.0.1 НТТР-клиент Простой пример НТГР-клиента: Напишите следующий код в файл КПр.сИеп!. ] з уаг ЫСр = геаи1ге( 'Ытр'); уаг орХХопз = { ЬозТпате: '127.0.0.1’, рог!: 80, рано: '/', теНтоо: 'СЕТ' }; уаг гер = Негр. гедиез1:(ор11оп5, Еипс1:1оп( гез) { сопзоХе. 1од('8ТАТ118: ' + гез.зХаХизСобе); сопзоХе.1од('НЕАРЕР8: ' + . зСг1пд1Ту( гез ,1теас1егз)); гез зеТЕпсобтпдХ'иИТ8'); гезоп('баХа1, ТипсХюп (сЬипк) ( сопзоХе.1од( Резропзе: ' + сбипк); }); гез.оп( 'епсГ , ЕилсСтоп (сКипк) { сопзоХе.1од( Резропзе ЕМОЕО'); }); }); гед.оп('еггог’, ГопсСюп(е) { сопзоХе.1од(ргоо1еш улСН гедиезТ : ' + е.теззаде); }); гед .епб();
Затем из расположения вашего файла Ьтх р_с11епт. ] 5 выполните команду: поде ГпЛр_сХХепг. ]5 Вы должны увидеть следующий результат: > ЗТАТС8: 200 > НЕА0ЕР8: { сопгепг-1уре : ХехТ/рХаю', дате' : ТКи, 21 ЗиХ 2016 11 27:17 6МТ", соппесХХоп":"сХозе , Хгапз'Гег-епсоаХпд :'сЬипкед } > Резропзе; ОК > Резропзе ЕМОЕЭ Примечание: этот пример зависит от 11ТТР-сервера.
Глава 42. Установка Моде.]з Примеры Установка Моде )з на 11Ьип1и Использование пакетного менеджера ар1 Зидо арГ-деГ ирдаГе зидо арГ-дсТ дпзДаИ подсдз зидо ар^-дет тпзГаП прт зидо 1п -з /изг/Ып/подезз /изг/Ып/поде # версии поде и прт в ар1 устарели. Вот как можно их обновить: зидо прт 1пзта11 -д прт зидо прт 1пзга11 -д п зидо п зГаЫе # (или Из, или конкретную версию) Использование последней или конкретной версии (напри мер 1Т8 6.x) непосредственно из пойезоигсе сиг! -з1_ ГтС1:р5://'деЬ.подезоигсе.сот/8е1ир 6.x | зидо -Е Ьаз!т - арТ-деС 1пзГа11 -у поде]з Также для правильной установки глобальных модулей прт настройте лич- ный каталог для них (это устраняет необходимость в зидо и исключает ошибки ЕАССЕ8): ткдТг ~/.прт-д1сЬа1 есЕо ехрогт РАТН=~/,прт-д1оРа1/Ып:$РАТН' >> ~ зсигсе ~/ .ргоГИе прт сопГтд зе! ргеНх '~/.прт-д1оба1 / .ргоЕтТе
Установка Ыос1е.]8 на \Л/1пс1о\У8 Стандартная установка Вее бинарные файлы, установщики и исходные файлы ТМойеда можно скачать здесь: 1Щр5://пойе]8.ог§/еп/йоууп1оаб/раска§е-тапа§ег. Вы можете загрузить только исполняемый файл побе.ехе или использовать установщик для Мпботе (.те 1), который также установит прп, рекомендуемый пакетный менеджер для Мобе.]8, и настроит пути. Установка с помощью пакетного менеджера Вы также можете установить Ыо<1е.)8 с помощью пакетного менеджера СЬосо1а1еу (система автоматизации управления ПО). # сИосо 1П51а11 пос1е]з. 1п5Та11 Более подробную информацию о текущей версии можно найти в репозитории сЬосо здесь: 1щр8://соттиппу.скосо1агеу.ог^.;раска^е8/побе]‘8.1П81а11. Использование Мобе Уегзюп Мападег (пут) Мобе Уегыоп Мападег, или пут, — это ЬазЬ-скрипт, который упрощает управ- ление несколькими версиями Мобе.]8.
Для установки пут используйте предоставленный установочный скрипт: $ сиг1 -о- КИрз^/гаж.дНЬиЬизегсопРепг.сав/сгеаНопхх/пут/уВ.З! .3/ тпзсаП.зб | Ьаз1з Для ХМшйоууз существует пакет пугмчщДоууз с установщиком. На этой страни- це СПНиЬ (ЬПр8://§П11иЬ.сот/согеуЬийег/пут-м/т(1о№) вы найдете подробности об установке и использовании пакета пут-уДпбоууз. После установки пут выполните команду' «пут оп» из командной строки. Это позволит пут управлять версиями Иойе. Примечание: возможно, вам потребуется перезапустить терминал, чтобы он распознал только что установленную команду пут. Затем установите последнюю версию Побе: $ пут тпзТаИ посе Вы также можете установить конкретную версию Хойе, указав основные, вто- ростепенные и;или патч версии: $ пуш тпзтаИ 6 $ пут тпзТаИ 4.2 Чтобы просмотреть список доступных для установки версий: $ пут 1з-гето1е Вы можете переключаться между версиями, указывая версию так же, как и при установке: $ пут озе 5 Вы можете установить конкретную версию Мос1е, которая будет использо- ваться по умолчанию, введя: $ пут а11аз ОеГаиТТ 4.2
Чт обы отобразить список версий Мобе, установленных на вашей машине, введите: $ ПуШ 15 Чтобы использовать версии Мобе, специфичные для проекта, вы можете со- хранить версию в файле .пушгс. Таким образом, после начала работы над другим проектом будет меньше ошибок после его получения из репозитория. $ есНо 4.2 > .пупгс $ пут изе Вывод: Еоипа '/раТН/1 о/ргозес 1:/.путгс’ уегзтоп <4.2> Иол изгспд побе у4.2 (прт у3.7.3) Когда Мобе установлен через пут. вам не нужно использовать зибо для установ- ки глобальных пакетов, так как они устанавливаются в домашнюю папку. Таким образом, прт 1 -д Негр-зегуег работает без каких-либо ошибок разрешения. Установка Модеме из исходных кодов с помощью пакетного менеджера АРТ Необходимые компоненты: зибо ар!-деб 1п81а11 ЬиПб-еззепМа! зобе арр-дес 1П81а]1 ру1боп [ор1т опа!] зобе ар1-деТ тпзТаИ д11 Получение исходного кеда и сборка: сб ~ дП с!опе бНрз : //дгСбиЬ.сот/поие] з/побе.дгГ ИЛИ для последней версии ЬТ5 Мобедз 6.10.2: сб ~ йдет 1тс1:рз://побе]з.огд/бтзт/уб 3.0/побе-уб.10.2.1аг.дг 1 а г -хгуТ побе-Уб 10.2.Таг.дг Перейдите в каталог с исходными файлами, например: сб ~/побе-уб.10.2 Выполните:
. /согтГ1диге паке зибо таке тпзТаП Установка Мобе.щ на Мас с помощью пакетного менеджера Нопи'Ьгем' Вы можете установить Ыобе.]8 с помощью пакетного менеджера НотеЬгел. Начните с обновления Ьге«: Ьге'л ирбаСе Возможно, вам потребуется изменить разрешения или пути. Лучше выпол- нить это перед продолжением: Ьгел босСог Далее вы можете установить Мо<1е.]з, запустив Ьге<л тпзТаП поде После установки Нобе.)з вы можете проверить установленную версию, за- пустив побе -V Масроп.8 Вы также можете установить победа через МасрогСз. Сначала обновите МасрогСз. чтобы убедиться, что используются последние версии пакета: зибо рог! зе1Сираа-!:е Затем установите побе] з и прт: зибо рогС 1пзТа11 побе]з прт Теперь вы можете запускать пойе через командную строку, просто вводя побе. Также можно проверить текущую версию побе с помощью: побе -V
Установка с помощью Мас08 X 1п8(а11ег Вы можете найти установочные пакеты па странице загрузки Мос1е.]8 (ЬПрз:// 1Ю<1е)8.ог2/еп/с1ом-п1оас1/раска8е-тапайег). Обычно Мойе.)5 рекомендует две версии — ЬТ5 (долгосрочная поддержка) и те- кущую версию (последний релиз). Если вы новичок в Мойе, выберите Ы'8 и на- жмите кнопку «МастЮзЬ ТпЯаПег», чтобы скачать пакет. Если вы хотите найти другие версии М’ойе.]8, перейдите по этой ссылке: ИНрз:// пойе)з.ог#/еп/аЬоШ/ргеу1ои8-ге1еа8е8. Выберите нужный релиз и нажмите «Скачать». На странице загрузки найдите файл с расширением .рк#. После того как вы скачали файл (с расширением .рк^. конечно), дважды щел- кните по нему, чтобы установить. Установщик включает в себя Мойе.)з и прт, по умолчанию пакет установит оба, но вы можете настроить, что именно уста- новить, нажав кнопку «Сизютйе» на шаге «1пзТа11аиоп Туре». В остальном сле- дуйте инструкциям по установке, они довольно просты. Проверка установки Ъ'оДе Откройте терминал (если вы не знаете, как его открыть, посмотрите эту ста- тью на вдкЖомг: ййр8://мпуу/.иг1к1йоуу.сот/СеМо-(йе<оттапй-Ыпе-оп-а-Мас).
В терминале введите поде --уегзюп и нажмите Ешег. Если Ходе установлен, ваш терминал будет выглядеть следующим образом: $ поде --(/егзюп У7.2.1 У7.2.1 — это версия вашего Ходе.]з. Если вместо этого вы получите сообщение «сошшапд по1 Гоипд: поде», значит, возник.та проблема с установкой. Установка Моде.щ на КазрЬеггу Р1 Чтобы установить версию уб.х, обновите пакеты: сиг1 -з1_ 11Щрз://деЬ.посеяоигсе.сот/зесир_6 х | зидо -Е Ьазй - Использование пакетного менеджера ар(: зидо эрТ-деТ ТпяГаИ -у поде]з Установка с помощью Мейе Уегзюп Мападег в ЯзЬ 8Ье11 с ОН Му ЯзН Ходе Уегзюп Мападег (пут) значительно упрощает управление версиями Ыоде.]з, их установку и устраняет необходимость в использовании зидо при ра- боте с пакетами (например, прт тпзГаИ ...). Р18Й ЗЕтсИ (Г1з11) — это «умная и удобная командная оболочка для 08 X, Ыпих и других систем», которая популярна среди программистов как альтернатива ооычным оболочкам, таким как ЬазЬ. Наконец, Ой Му Етзй (опН) позволяет настраивать и устанавливать пакеты в оболочке Е1зй Этот раздел предполагает, что вы уже используете Нзк в качестве оболочки. Установите пути: сиг1 -о- (тЩрз://гак.дтТПиЬизегсопЕепТ.сот/сгеа11оп1х/пут/у0.31.4/ 1пз1;а11.з1т | Ьаз1г
Установите Ой Му Пей: С11г1 -|_ ИМрз: //дтЛИоб . сот/оИ-ту-Т1811/оГ|-ту-Т18б/гаи/та8тег/Ып/ 1П8Га11 | "Г 13 |Л (Примечание: вам будет предложено перезапустить терминал на данном эта- пе. Сделайте это). Установите плагин пип для Ой Му Ней Мы установим плагин пут через Ой Му Пай. чтобы использовать возможно- сти пут в оболочке Пай: опгГ йпзТаП пут Установка йюйе.]8 с помощью Хойе Уепйоп Мапа^ег Теперь вы готовы использовать пут. Вы можете установить и использовать любую версию Мойе.)8 по вашему выбору. Примеры: • Установить последнюю версию Мос1е: пут тпзСаП пойе • Установить конкретную версию, например 6.3.Г пут 1П81а11 6.3.1 • Показать список установленных версий: пет 1з • Переключиться на ранее установленную версию, например 4.3.1: пут озе 4.3.1 Заключительные примечания Помните, что при использовании этого метода больше не нужно задейство- вать зийо при работе с Хойе.]з! Версии Хойе, пакеты и прочее устанавливаются в вашем домашнем каталоге. Установка Мойе)з из исходников на СепЮЗ, РНЕЬ и Рейога Необходимые компоненты: • ёй • с!ап§ и с!ап§++ 3.4Л или §сс и + 4.8Л
• РуПтоп 2.6 или 2.7 • СМС Маке 3.81Л Получение исходного кода: Мойедз у6.х Ы$: д!1 с1опе -Ь уб.х НКрз://дИКиЬ.согт/поде]з/поде .дз! 1ЧоНе.]8 у7.х: дИ с1опе -Ь у7.х Гпгрз ://дибиЬ. сот/поде;; з/пэде.д11 Сборка: сс1 поде . /сопМдоге таке -]Х зи -с таке 1пз1а11 X — количество ядер процессора, что значительно ускоряет сборку. Очистка [но желанию]: сс! гт -гС поде Установка Мос1е.рз с помощью п Для начала есть удобный скрипт для настройки п на вашей системе. Просто выполните: сиг1 -Ь пгррз: //д!г. ю/п-1пз1а11 | ЬазЬ ...чтобы установить п. Затем установите бинарные файлы различными спосо- бами' Последняя версия: п 1а1ез1 Стабильная версия: п зСаЫе ЬТ8-версия: П 113
Любая друг ая версия: п <уег8юп> Например: п 4.4.7 Если эта версия уже установлена, данная команда активирует эту версию. Переключение версий п сам по себе отобразит список установленных бинарных файлов. Используй- те клавиши «вверх» и «вниз», чтобы найти нужный, и нажмите ЕгНег, чтобы ак- тивировать его.
Глава 43. Взаимодействие с консолью Синтаксис • соп8о1е.1од( [с!а1а] [, ...]) • сопзо1е.еггог([ба!а] [, ...]) • сопзо1е.Т1те(1аЬе1) • сопьо1е.'С1шеЕлс1(1аЬе1) Примеры Легирование Модуль Соп8о1е Подобно среде браузера ]ауа8спр(, Ыос1е.)8 предоставляет модуль сопзо1е, ко- торый обеспечивает простые возможности для логирования и отладки. Самыми важными методами, предоставляемыми модулем сопзо1е. являются сопзо1е.1од, сопзоТе. еггог и сопзоХе. Пте. Но также существуют и другие, та- кие как сопзо1е.ДпГо. соп8о1е.1о$ Параметры будут выведены на стандартный вывод (8(йои1) с новой строки. соп8о1е. 1од(1 Не11о йог!сГ); > соп5о1е.1о§( 'Не11о Ыог1сГ) Не11о Ыог1<1 еоп8о1е.еггог Параметры будут выведены на стандартный лоток ошибок (зтбегг) с новой строки.
сопзо1е.еггог(' 01т, зоггу, Итеге хз ап еггог.’); > сопзо1е.еггог("0Ь, зоггу, еггог"); ОН, зоггу, еггог соп5о1е.Пте, соп$о!еЛйпеЕп(1 сопзо1е.Схте запускает таймер с уникальной меткой, который можно ис- пользовать для вычисления продолжительности операции. Когда вы вызываете сопзо1е.1:х1пеЕпс1 с той же меткой, таймер останавлива- ется и выводит время выполнения в миллисекундах в зДбоиД. сопзоТе Схте(’1аЬе1’); // код, который нужно измерить сопзоТе.ДхтеЕпЩ ' 1аЬеГ ), > соп5о1е.1тте("1аЬе1"); ипдеЛпес! > сопзоТеЛдтеЕпНС'ТаЬе!"); 1аЬе1: 9297.320тз Модуль Ргосезз Можно использовать модуль ргосезз для прямой записи в стандартный вы- вод консоли. Для это!о существует метод ргосезз зюоит .лгхТе. В отличие от сопзо1е.1од, этот метод не добавляет новую строку перед ва- шим выводом. Таким образом, в следующем примере метод вызывается два раза, но новая строка не добавляется между их выводами. ргосезз.51дои!.«гт1е("123");ргосезз.зТдои!.мгтТеГ"456"); 12345611 не ргосезз.зббоиб.лг1бе('ЕхгзД рагТ оГ 1Пе теззаде’); ргосезз.зТбоиТ.лгх!е(’ сопИпиез у/НГюи! а пел Ипе.'); Форматирование Можно использовать управляющие коды терминала (сспТ го1 ссбез) для вы- полнения определенных команд, таких как изменение цвета или позициониро- вание курсора. |> соп5о1е."од("\033[31тТЬтз кт 11 Ье гед");
Общее Эффект Код Сброс \033[0т Высокая яркость \033[1т Подчеркивание \033[4т Инверсия \033[7т Цвет шрифта Эффект Код I Черный \033|30т Красный \0зЗ[31т Зеленый \033[32т Желтый \ОЗЗ[ЗЗт Синий \033[34т Мадегйа 1 Фиолетовый) \033[35т Суап (Голубой) \033[36т Белый \033|37т Цвет фона Эффект Код Черный \033[40т Красный \033[41т Зеленый \033[42т Желтый \033[43т Синий \033[44т Ма§еп(а (Фиолетовый) \033[45т Суап (Голубой) \033[46т Белый \033[47т
Глава 44. Постоянное выполнение 1Чос1е.]5-приложения Примеры Использование РМ2 в качестве менеджера процессов РМ2 позволяет запускать ваши скрипты Моск? ,)8 бесконечно. В случае сбоя ва- шего приложения РМ2 автоматически перезапустит его. Установите РМ2 глобально для управления вашими экземплярами Мойедя: прт тпзТаП рт2 -д Перейдите в директорию, в которой находится вага скрипт Мос1е.]8, и выпол- ните следующую команду каждый раз, когда вы хотите запустить экземпляр Мобе.]8, который будет отслеживаться РМ2: рт2 зсаг1: зегуег.]'з --пате 'арр1 ' Полезные команды для мониторинга процессов 1. Список всех экземпляров Мос1е.]8, управляемых РМ2: ргп2 1131 2. Остановка конкретного экземпляра Мойе.]8: рт2 зЮр <1пз1апсе пате> 3. Удаление конкретного экземпляра Мойедз: рт2 ое1еСе <1пз1апсе пате> 4. Перезапуск конкретного экземпляра Мойе.]8: рт2 гезТагТ сДпзТапсе пате> 5. Монигориш всех экземпляров Мо(1е.]8: рт2 топИ
6. Остановка РМ2: рш2 к111 7. В отличие от гезТагТ, который останавливает и перезапускает процесс, ге1оаб обеспечивает перезагрузку без простоя: рт2 ге1оас1 <1пз1:апсе папе> 8. Просмотр логов рт2 1одз <1П51апсе_пате> Запуск и остановка Даетоп З'огесег Чтобы запустить процесс: Тогеуег зтагт 1поех.]з «агп: --т1п!1р11те по! зеС. ОеТаиИТпд 1с: 1000лпз «агп: --зр1о81еерТ1те поС зеТ, Уоог зсгТрТ «111 ех11 1Т Ц боез по! зсау ир Тог аг 1еазТ 1000тз тпТо: Рогесег ргосеззхпд ТПе: 1паех.]з Список запущенных экземпляров Еогеуег: $ Тогеуег Из! 1пТо: Гогеуег ргосеззез гипгыпд |баса: | юбех | ию | соттапб | зспрТ | Тогеуег р10110 | 1од*11е | ирГгте | ।------।-------।-----।------------------1-------------।------------|__ — I----------------------।--------------1 |0а1:а: | [0] |Т4К1 | /изг/Ып/гю0е]3 | згс/1пбех.де|2131 |214б|/гоо1/. Тогеуег/ТДКГ.1од | 0:0:0:11.485 | Остановка первого процесса: Тогеуег зтор 0 Тогеуег зЮр 2Кб Тогеуег зЮр --итё Т4КГ Тогеуег з!ор --ргОШе 2131 Непрерывная работа с помощью поЬир Альтернативой Гогеуег на Ыпих является пойир.
Чтобы запустить экземпляр пойир: 1 Перейдите в папку, где находится арр.]5, или в папку уисг;. 2 . Выполните команду: побор побе]з арр.]з & Чтобы завершить процесс: 1. Выполните: рз -е!3 | дгер победе 2. Завершите процесс: кд11 -9 <1бе ргосезз питЬег> Управление процессами с помощью Еогеуег Установка прт 1пз1а11 'Гогеуег -д сб /побе/ргозес1/б1гес(:огу Использование 1"огеуег зТагг арр.]з
Глава 45. Фреймворк Коа м2 Примеры Пример Не11о \Л/ог1с1 ссп51 Коа = гец1нге('коа') сопаТ: арр = пе« Коа() арр.иае(ааупс с!х => { с!х. Ьос1у = 'Не11о Лог1с1’ }) арр.115±еп(8080) Обработка ошибок с использованием гтдсИемгаге (промежуточного ПО) арр.иае(азупс (сТх, пех!) => { ггу { аиаК пех1() // попытка вызвать следующий ткШеиаге } са1с1п (егг) { Рапс!1еЕггог(егг, с1х) // определите свою собственную функцию обработки ошибок } })
Глава 46. кодазЬ Введение ЬойазИ — это удобная {ауаЗспрГбиблиотека утилит. Примеры Фильтрация коллекции Ниже приведен пример различных способов фильтрации массива объектов с использованием 1ос1ачИ. 1е1 1обазб = геро1ге('1обазЬ ); уаг соипегтез = [ {"кеу': ОЕ пате : 0еитзс1з1апб", 'асттуе ': ^а!зе}, {"кеу": 2А папе": ЗоиТК АТгХса", асИуе ; Тгое} уаг ТИТегебВуЕипсТюп = 1обазЬЛ1]-1ег(соип1Г1е$, Топстюп (соипХгу) { геТигп соипТгу.кеу === ОЕ"; }); // => [{'кеу : ОЕ", 'пате : СеихзсМапд }]; ^аг ТШегебВуОЬзесТРгорег'Стез = 1обазЬ.Г111'ег(соип'(:г1е8. { "кеу": 'ОЕ" }); // => [{'кеу : "ОЕ , 'пате : СеисзсЫапб }]; уаг ^тИегесВуРгорегИез = 1оааз1з.Т11Гег(соип'Сг1ез, ["кеу1, "2А ]); // => [{'кеу : 2А , "пате": "Зсисб АТгтса }]; уаг ШЛегейВуРгорегГу = ХибазИ.ТШег (соипТгтез, "асТ1уе'); И => [{"кеу . 7А , "пате": ЗоиТЬ АГгтса }1;
Глава 47. ЬоорЬаск — КЕЗТ-соединитель Введение В этой главе мы рассмотрим, что такое КЕ8Т-соединители и как с ними рабо- тать. Мы знаем, что ЬоорЬаск не обеспечивает комфорта при работе с КЕ8Т сое- динениями. Примеры Добавление веб соединителя //Этот пример получает ответ от 1Типез { "гезт": { 'паше : гез!", ’ соппесЮг": "гез! , ВеЬид": Тгие, "орИопз" : { изеОиегузТгХпд : !гие, "Итеои! 10000, Ьеаоегз : { ассерТз : аррИса!1оп/]зоп , "согТепт-Хуре' : аррИсаПоп/тзоп } }, орегаТюпз : [ { тетрХате": { теСЬсб : СЕТ", иг! : И1!рз://1!ипез.аор1е сот/зеагсб", диегу : { Тегт": ’ {Кеуу/огО}",
"соипТгу": "{соип*гу-1М} , "пеРха : '{х1етТуре=п1изхс}', "1хт11": "{111411=10}", "ехр11с11": "Га1зе } }, ТипсПопз : { "зеагсЬ : [ "кеуиогР", "роигИгу", "хГетТуре "11тх1" }, { '1етр1а1е": { "те1Ьос1 "БЕТ", "иг1": ПГТрз://Нипез.арр1е.сот/1эокир , "аиегу : { "1сГ : "{1с1} } }, "ТипсИопз : { "Т^^1с^ВуIс^, : [ "10 ]
Глава 48. те1а18ГП1(Н Примеры Создание простого блога Предполагая, что у вас установлены пойе и прт, создайте папку (директорию) проекта с действительным файлом раскаде.]зоп. Установите необходимые за висимости: прт гпзсаХХ --зауе-оеу техаХзттб тега1зт11Ь-1п-р1асе ЬапсПеЬагз Создайте файл под названием ЬиХХб. ] з в корне папки вашего проекта, содер- жащий следующий код: уаг гпеСаХзтХХП = гедоХге( 'теХэХзтХСП') ; уаг НапсПеЬагз = геди1ге('ЬапсИеЬагз'); уаг ХпР]асе = гедоХге('теСа1зт1СЬ-1п-р1асе'), МеТа1зт11:Н(_сПгпате) .изе(ХпР1асе( ЬазсПеЬагз')) .ЬиХХс1(Типс1:1оп(егг) { 1Т (егг) сНгои егг; сопзо!е. 1од('ВиХ1с1 ТютзЬес!1 '); }); Создайте папку (директорию) зге в корне папки вашего проекта. Создайте Хпбех.ИгтХ в папке зге, содержащий следующий код: СХСХе: Му аюезоте Ыод
<Н1>{{ Ш1е }}</Г>1> Запуск побе ЬиПа. ] з теперь создаст все файлы в папке з гс. После выполнения этой команды у вас будет гпбех. Ыт1 в вашей папке Ьи11б со следующим содержимым: <Ы>Му аиезоте Ыод</Н1>
Глава 49. Интеграция с МопдоСВ Синтаксис • с1Ь.со11есг1оп.1пзег'(:Спе(с1оситепГ| ор11опз(й, иНтеои!, ], зегХаНгеЕипсНопз, ТогсеЗегуегОЬзесПЬ, ЬураззОоситеп'ЬУаИЬаНоп), са] 1Ьаск; • РЬ.со]1ес1:1Оп.1Пзег1:Мапу( МсситепГз], орГ1опз(и, и11теои1, ], зегтаИгеЕипсХюпз, ГогсеЗег7егОЬ)ес11с1, Ьуразз0оситеп1:Уа11с1а1:1оп), саНЬаск) • ЬЬ.со11ес1:1оп.Т1пс1(аиегу) • ЬЬ.соПесХтоп.ирйаХеОпеЩИег, ирс1а1е, оргюпз(ирзегг, и, «ЫтеоиЬ, ], Ьуразз0оситеп1:УаНс1а1.1оп), саНЬаск) • ЬЬ.со11есЫоп.ираа+еМапу(Т1Н'ег, ирс1а1е. орЬ1опз(ирзег1, и, у/ЫтеоиХ, ]), саНоаск) * ЬЬ.соНесНоп.ЬеТеСеОпе^НИег, ср1:1ог1з(арзеН, л, «тхтеоиЬ. ]), саНЬаск) • ЬЬ.со11ес1:1ог1.с1е1е1:еМапу(Г1Иег; орх1опз(ир8егЬ, к, 'лИтеоИ, ]), саНоаск) Параметры Параметр Описание с1оситет )ауа5спрьобъек1, представляющий документ йоситеп(5 Массив документов циегу Объект, определяющий поисковый запрос
ПНег Объект, определяющий поисковый запрос саПЬаск Функция, вызываемая по завершении операции орйопз (опционально) Опциональные настройки (по умолчанию: пи11) VI (опциона-тьно) ЗДгпе Сопсегп иТлпеоШ ) (опционально) Тайм-аут для Шгйе Сопсегп (по умолчашпо: по11) (опционально) Определяет требования журнала (по умолчанию: Гаке) прзег( (опционально) Обновление или вставка, если запись не найдена (по умолчанию Гаке) гпиИ) (опционально) Обновление одного/всех документов (по умолчанию: Гаке) кепаНхеГипсйопз (опционально) Сериализация функций на любом объ- екте (по умолчанию: Гаке) ГогсеьегсргОЬ] ес(И (опционально) Принуждение сервера назначать значения _)с1 вместо драйвера (по умолча- нию: Гаке) ЬуразьВоситепЛ’аППаиоп (опционально) Позволяет драйверу обходить валидацию схемы в Моп§оЕ)В 3.2 или выше (по умолчанию: Гаке) Примеры Подключение к МопдоОВ Подключитесь к МопдоЛВ, выведите «СоппесСесИ» и закройте соединение. сопзГ МопдоСИепТ = геди!ге( 'гсопдэсй?’) . МопдоСИепС ; уаг цг1 = 'топдосПэ: // 1оса1Гтоз1::27Э17/1:ез1:' ; МопдоС11егт1 ,соппесЦиг1, ТипсИог^егг, бЬ) { // метод МопдоСПтегй ' соппесС 1Г (егг) Пт гол пел Еггог(егг); сопео1е.1од( Соппестео! ); бЬ.с1озе(); // Не забудьте закрыть соединение, когда закончите В;
Метод СоппесЦ) для МопдоСЬеШ МогдоСПепТ.соппест(иг1. срТюпз, саПЬаск) Аргумент Тип Описание иг1 строка Строка, определяющая 1Р/Ьо&1лате сервера, порт и базу данных орнопз объект Опциональные настройки (по умолчанию: пиП) саПЬаск функция Функция, вызываемая по завершении попытки подключения Функция обратно! о вызова принимает два ар!умента: • егг: ошибка — если возникает ошибка, аргумент егг будет определен • с! Ь . объект — экземп.1яр Моп§оБВ Добавление документа Добавьте документ под названием туПгзШоситеп! и установите два свой- ства, дгееТ1пдз и ГагелеП: соиз! МопдоСПепС = '•еди1ге( 'топдобь') .МопдоСПепТ; сопз1: иг] = 'топдобЬ://1оса11аозг :27017/гез1 ’ ; МопдоСИепт.соппестСиг!, ТипсТюп (егг, бб) { 1Т (егг) Тбгол пе\ч Еггог(егг); бЬ со11ес!:1оп('шуСоИесгюп ) ,1пзег10пе( { // Метод вставши ' ТпзегЮпе ' шуЕтгзЮоситепТ": { 'дгееЫпдз : "НеПи", ТагежеП": 1 Вуе } }, ТипсПоп (егг, гезиИ) { 1Т (егг) ТИгой пел Еггог(етг); сопзо1е.1од( "Тпзегтеб а босшпепт 1пТо ТГте пуСоИесПоп соИесТюп!") ; бЬ.с1озе(); // Не забудьте закрыть соединение, когда закончите }); }); Метод коллекции 1пзег10пе() бЬ.со11есТ1оп(со11ес1:1оп) . 1пзег1:0пе(босип1еп1:, орПопз, саПЬаск)
Аргумент Тип Описание соПесбоп строка Строка, указывающая коллекцию босшпеп! объект Документ, который будет вставлен в коллекцию орйопз объект (опционально) Опциональные настройки (по умол- чанию: пи11) саНЬаск функция Функция, вызываемая по завершении операции вставки Функция обратного вызова принимает два аргумента: • егг: ошибка — если возникает ошибка, аргумент егг будет определен • гезиП: : объект — Объект, содержащий детали о выполненной операции вставки Чтение коллекции Получите все документы в коллекции ‘туСоИесйоп’ и выведите их в консоль. сопзТ МолдоСИепГ = гедитге(' топдэбь'). МопдоСИепТ ; сопзТ ог1 = 'топдсбЬ://1оса1ИозТ:27б17/ТезТ' ; МопдоСИепТ,соппесТ(иг1, ЕипсТюп (егг, бЬ) { тГ (егг) Хбгои пей Еггог(егг); уаг сигзог = бЬ.со11ес11оп( 'туСоПесТлоп') Е1пб(); // Метод чте- ния ' Т1пс1 ’ сигзог.еасН(Типс1юп (егг, бос) { (егг) Сбгой пем Еггог(егг); 1Т (бос != пи11) { сопзо1е.1од(бос); // Вывод всех документов } е1зе { бЬ.с1озе(); // Не забудьте закрыть соединение, когда за- кончите } }); }); Метод коллекции Нпб() бЬ.со11есТ1оп(со11есТ1оп) ,1:1пб()
Аргумент Тип Описание соПесбоп строка Строка, указывающая коллекцию Обновление документа Найдите документ со свойством { дгееДдпдз. 'Не11и' } и измените его на { дгееПпдз: У/ЬиС?' }. сопзС МопдоС11еп1 = геци1ге( 1топдобь ) . МопдоСПепС; сопзС иг! = 'топдойЬ://1оса11тозТ.27017/ТезТ' ; МопдоС11еп1.соппес1(иг], ТипсПоп (егг, 6Ь) { 1Т (егг) ГЬгол пел Еггог(егг); ЬЬ. со11ес1:1оп( ‘туСоПесСюп’) ,ирба1е0пе({ // Метод обновления 'ирба^еОпе' дгееСтпдз: Не11и' }, { ЗзеС: { дгееДтпдз: "ИЬи1?" }}, ТипсСюп (егг, гези1г) { 1Г (егг) Сбгол пел Еггог(егг); 0Ь.с1озе(); // Не забудьте закрыть соединение, когда за кончите }); }); Метод коллекции ирба1еОпе() с!Ь соПесПоп^оПесНоп) .ирбаСеОпе^ЦЛег, ироаСе, орсюпз, саПЬаск) Параметр Тип Описание йкег объект Определяет критерии выбора ирйаГе объект Определяет модификации, которые будут применены орйопз объект (опционально) Опциональные настройки (по умолчанию: пиП) сакЬаск функция Функция, вызываемая по завершении операции Функция обратного вызова принимает два аргумента: • егг: ошибка если возникает ошибка, аргумент егг будет определен • ОЬ объект — экземпляр МопдоОВ
Удаление документа Удаление документа со свойством {дгеейп^з: 'УУйш?’} сопз! МопдоСПепЬ = геди1ге( ’ топдобь ’). МопдоСПепГ ; сопз1: иг1 = 'топдсс!Ь: // 1оса1Ьоз1::27Й17/1 езТ ’ ; МопдоСНеп!.соппесГ(иг1, ТипсИоп (егг, ЬЬ) { 1Т (егг) ТПгол пей Ег-ог(егг); оЬ со11ес(:1оп( 'туСоПесгюп'). ое1етеЭпе(// Метод удаления с1е1е1е0пе' { дгееПпдз. 'ЛЬиТ7' }, ГипсИоп (егг, гези1т) { (егг) ТПготу пел Еггог(егг); ЬЬ.с1озе(); // Не забудьте закрыть соединение, когда за- кончите } ); }); Метод коллекции с!е1е1еОпе() бЬ.со11ес11оп(со11есТ1оп) . бе1е!:е0пе(Т111:ег, срЕюпз, саПЬаск) Параметр Тип Описание (Шег объект Документ, определяющий критерии выбора. орПопз объект (Необязательно) Опциональные настройки (по умолчанию: поШ. саПЬаск функция Функция, вызываемая по завершении операции Функция обратного вызова принимает два аргумента: • егг: ошибка Если произошла ошибка, аргумент егг будет определен. • ЬЬ: объект’ — Экземпляр Моп§оОВ. Удаление нескольких документов Удаление всех документов со свойством ‘ЕагеюеИ’, равным ‘окну’. сопз! МопдоСИеп! = гедигге( 'топдобб') . МопдоСИепЬ, сопз! иг1 = 'топдобЬ://1осаИтоз1:27017/1езк'; МопдоСИепД.соппесЦ'иг!., ЕипсИоп (егг, бЬ) { 1Г (егг) 1Игол пел Еггог(егг);
с!Ь ,сс11ес1:1сп( 'туСоПесЫоп') .бе!е1:еМапу(// Метод удаления Че1еТеМапу' { ТагеиеП окау }, // Удалить все документы сс свойством ' Гагеи/еИ: окау’ ГипсПоп (егг, гезиИ) { (егг) ТЬгоа' пей Еггог(егг); бЬ.с1озе(); // Не забудьте закрыть соединение, когда за- кончите } ); }); Метод коллекции с!е1е1еМапу() ЬЬ. соПесСюгЦсоПесГюп) .бе1е1ейапу(Н1Сег, орПопз, саНЬаск) Параметр Тип Описание Г11Тег документ Документ, определяющий критерии выбора. орГюпз объект (Необязательно) Опциональные настройки (по умолчанию: пи11) саНЬаск функция Функция, вызываемая по завершении операции Функция обратного вызова (са 11Ь а с к) принимает два аргумента: • егг: ошибка — Если произошла ошибка, ар1умент егг будет определен. • ОЬ: объект — Экземпляр Моп^оВВ. Простое подключение МопдоОЗ.соппесС( шог.добЬ: //ХосеИюзИ:27017/с1а11аЬазеМат1е ', ГипсТ1оп(еггог, оатаоазе) { 1-Г(еггог) гетигп сопзс1е.1од(еггот); сопзт соНесыог = Ьа1аьазе.со11есгюп( 'соПесУюпиате’) ; соИесПсп. 1пзег1( {кеу: 'уаХие'}, ^ипсЫоп(еггог, гезиИ) { сопзо1е 1од(еггог, гезиИ); }); }):
Простое подключение с использованием промисов СОП81 МопдоОВ = геди!ге('топдос1Ь'), МопдоОВ.соппест( 'топдодЬ.//1ооа1Ноз1:;27017/с1а1:аЬазеМате') . Г Нел (-ГипсХюп (ЗаТ аЬа$е) { СОП51 соПесгюп = с1а1аЬа5е .со11есГ1сп( 'соПесХюпМате') ; ге1:игп соПесИоп.хпзеггЦкеу: уа1ие'})>‘ }) ЛНеп(Топс1:хоп( гези11) { соп5о1с.1сд( гезиИ); });
Глава 50. Интеграция МопдоОВ для Ыос1е.]8/Ехрге$8.]8 Введение МопдоБВ является одной из самых популярных баз данных ЫоБ(Д, благодаря поддержке стека МЕАХ Взаимодействие с базой данных Моп^о через приложе- ние на Ехргезз является быстрым и простым, как только вы поймете несколько непривычный синтаксис запросов. Мы будем использовать Моп^оозе .для помо- щи в этом. Примечания Больше информации можно найти здесь: йцр8:/7Моп^оозе)8.сотМос8/§и1с1е. Ь(т1. Примеры Установка МопдоОВ прт 1пз1а11 --зауе топдобЬ прт ЕпзСаП --зауе топдоозе //Простой у/гаррег для облегчения разра- ботки
В вашем серверном файле (обычно называется тпбех ]з или зегуег. ]з) сопз! ехргезз - геди1ге('ехргезз'); сопз! тоздоаЬ = гедлге( 'попдоРЬ'); сопз! топдоозе = геди!ге( тспдосзе ); сопз! топдоСоппес!8сг1пд = 'б!!р://1оса1Гюз!/ба!аоазе пате’; топдоозе .соппес!(пюпдоСоппес!8!г1пд, (егг) => { 1! (егг) { сопзо!е.1сд(1 Соо1с1 по! соппес! !о !Ие ба!аЬазе’); //Не удалось подключиться к базе данных } }); Создание модели Мопдоозе сопя! ЗсМета = топдоозе.8спета, сопз! 0Ь^ес!Тс1 = ЗсНета.Турез.01^ес!1с1; сопз! Аг!1с1е = пей 8сбета({ !1!1е: { !уре: 8!г1пд, ипюое. !гие, гедитгеб: (!гие, Аг!1с1е таз! Науе !111е '] //У статьи должен быть заголовок }. аи!бог: { !уре: 0Ь]ес!1о, ге!. 'С1зег' } }); шоби1е.ехрог!з = топдоозе. тос!е1( Аг!1с1е, Аг!1с1е'); Давайте разберем это. МопдоОВ и Мопдоозе используют (8ОК (на самом деле В804 но это здесь не имеет значения) как формат данных. Вверху мы установили несколько переменных для уменьшения объема кода. Создадим новую схему и присвоим ее константе. Это простой ]804 и каждый атрибут является еще одним объектом со свойствами, которые помогают обеспе чить более согласованную схему'. Ишдие заставляет новые экземпляры, вставляе- мые в базу данных, быть уникальными. Это отлично подходит для предотвраще- ния создания пользователем нескольких аккаунтов в сервисе. Редтгес! — еше один атрибут, объявленный как массив. Первый элемент — это булево значение, а второй — сообщение об ошибке, если значение, которое вставляется или обновляется, не существует. СЬ]ес!1б используется для отношений между моде.тями. Примерами могут быть‘11зегз бауе тапу СоттепТз’. Другие атрибуты могут быть использованы вме- сто Ооуес!1б. Строки, такие как имя пользователя, являются одним из примеров.
Наконец, экспортирование модели для использования с вашими АРЬмаршру- тами предоставляет доступ к вашей схеме. Запрос к вашей базе данных Мопдо Рассмотрим простой НЕТ-запрос. Предположим, что модель из приведенного выше примера находится в файле . /бЬ/шобе15/АП1с1е. ] з. сопзб ехргезз = геди1ге('ехргезз'); сопзб АгИс1ез = геро!ге(' ./бЬ/тоае1з/Аг11с1е’) ; тобиТе.ехрогСз = ТипсИоп (арр) { сопзТ гоибез = ехргезз.Р^и4ег(); гоиТез.де!:('/аг11с1ез', (гед, гез) => { АгИсХез.ИпбО .11т11(5) .1еап() .ехес((егг, бос) => { 1Е (Йос 1епдХГ| > 0) { гез.зепб({ баба: бос }); } е1зе { гез.зепб({ зиссезз: 1а1зе, теззаде: 'Ко боситепгз геХггехеб' }); //Документы не найдены } }); }); арр.изе('/ар1', гоитез); }; Теперь мы можем получить данные из нашей базы данных, отправив НТТР-за- прос на эту конечную точку. Однако есть несколько ключевых моментов 1. 1_ 1т И делает именно т о, что кажется. Мы получаем только пят ь документ ов. 2. 1_еап удаляет некоторые данные из исходного В8ОЫ, уменьшая сложность и нагрузку. Это не обязательно, но полезно. 3. При использовании Нпб вместо НпбОае, убедитесь, что длина бос. Хепдтб больше 0. Это связано с тем, что ТТпб всегда возвращает массив, поэтому пустой массив не обработает вашу ошибку, если не проверить длину. 4. Измените сообщение об ошибке в соответствии с вашими потребностями. То же самое касается возвращаемою документа. 5. Код в этом примере написан с учетом того, что вы поместили его в другой файл, а не непосредственно на сервер Ехргезз. Чтобы вызвать это в сервере, включите следуюшис строки в свой серверный код: сопзб арр - ехргезз(); । еди!ге(' . /рабЬ/бо/ТИтз/ЕПе') (арр);
Глава 51. Библиотека Мопдоозе Примеры Подключение к МопдоОВ с использованием Мопдоозе Сначала установите Мопдоозе с помощью: прт тпзТаИ топдоозе Затем добавьте его в файл зегуег. ] з как зависимость: уаг топдоозе = гедлге( топдоозе’); уаг ЗсЬета = топдоозе.ЗсНета: Далее создайте схему базы данных и имя коллекции: уаг зс1тета№те = пел 8сИета({ гедиезГ: ЗСгщд, Диле: МитЬег }. { соПесИоп: 'соПесСюпМате' }); Создайте модель и подключит есь к базе данных: уаг Мобе1 = топдоозе.тобеЦ ’Мос1еГ , зсЬетаМате); топдоозе.соппесЦ 'топдобЬ:// 1оса1Ьоз11:27017/йЬМате ); Затем запустите Моп^оЬВ и выполните зегуег. ]з, используя команду побе зегуег. ]з. Чтобы проверить, удалось ли подключиться к базе данных, мы можем ис- пользовать события ореп и еггог из объекта Мощщозе.соппесСтоп: уаг сЬ = топдоозе.соппесТтоп; с!Ь.оп('еггог сопзс1е.еггог.Ь1пб(сопзо1е, ‘ссппесИоп еггог:')); // ошибка подключения
бЬ опсе('ореп', ТипсстопО { // мы подключены! }): Сохранение данных в МопдоОВ с использованием Мопдоозе и маршрутов Ехргезз^з Настройка Сначала установите необходимые пакеты с помощью: прш 1пз1а11 ехргезз согз топдоозе Код Затем добавьте зависимости в ваш файл зе гуег. ] з, создайте схему базы дан- ных и имя коллекции, создайте сервер Ехргезз. ] з и подключитесь к Моп^оЛВ: уаг ехргезз = геаи1ге('ехргезз'); уаг согз = геди1ге('согз'); // Мы будем использовать С0Р8 для разреше- ния запросов с других доменов уаг топдоозе = геао1ге( топдоозе'); уаг Зсбета = топдоозе.ЗсЬета; уаг арр = ехргезз(); уаг зсПетаМате = пей Зсбета({ гедиезх: Зсппд, Сипе: !^итЬог }, { со11есТ1оп: 'соИессдопЧате' }); уаг Мобе1 = топдоозе тобе1(‘Мобе1’, зсбетаМате); топдоозе.соппесС('топдобЬ://1оса1Ьоз1: :27017/бЬМате'); уаг рог! = ргосезз.епу.РОРТ || 8060; арр.11з1еп(рог1:, ГипсИоп() { сопзо1е.1од( Мобе.)з 11зсеп1пд оп роге ' + роге); // Мобе.]з слу- шает на порту }); Теперь добавьте маршруты Ехргезз.]з, которые мы будем использовать для записи данных: арр.дет('/зауе/:доегу’, согз(), ТипсТ1оп(гед, гез) { уаг диегу = гед.рагатз диегу; уаг зауебаба = пей Мобе1({ 'гедиезб': диегу,
‘Пне': Мэгб.Е1оог(Оа1:е.пой() / 1800) // Время сохранения данных е формате ипдх ^ппезтатр }).зауе(/ГипсПоп(егг, гезиИ:) { 1Т (егг) Ингой егг; 1Г( гезиИ:) { гез. ]зоп( гезиИ); } }); }); Здесь переменная диегу будет параметром <диегу> из входящего НТТР-запро- са, который будет сохранен в МопдоОВ: уаг зауеба^а = пел Мосе1({ ' гедиезТ': диегу, //... Если возникнет ошибка при попытке записи в МощщВВ, вы получите сообще- ние об ошибке в консоли. Если все пройдет успешно, вы увидите сохраненные данные в формате (8СЖ на странице. //... }) . .зауе(бипс11оп(егг, гезиИ) { 1Г (егг) тЬгой егг; 1Г(гези11) { гез 1зоп(гезиИ); } }); //... Теперь вам нужно запустить Моп§оВВ и выполнить ваш файл зегуе г.] з с по- мощью команды побе зегуег. ]з. Использование Чтобы использовать этот код для сохранения данных, перейдите по следую- щему 1ГКЕ в вашем браузере: НЩр: //1оса1боз1: :8080/зауе/<диегу> ...где <диегу> — это новый запрос, который вы хотите сохранить. Пример: Г|Щр: //ТосаЮозС :8080/зауе/Зауа8сг1р1:%20:18%20Айеяоп1е
Вывод в формате ]8ОМ: { __V. 0, гедиезЕ: бауаЗсгтр! 13 Аиезоте , Е1те: 1469411348, _1б. 57957014Ь93Ьс8640Т2с78с4 } Поиск данных в МопдоОВ с использованием Мопдоове и маршрутов Ехрге$в.|з Настройка Сначала установите необходимые пакеты с помощью: прт 1пз1а11 ехргезз согз топдоозе Код Затем добавьте зависимости в файл зегуег. дз. создайте схему базы данных и имя коллекции, создайте сервер Ехргезз.и подключитесь к Моп^оВВ: уаг ехргезз = гери1ге('ехргезз'); уаг согз = гедо1ге('согз'); // Мы будем использовать С0К8 для разреше- ния запросов с других доменов. уаг топдоозе = гедитге('топдоозе’); уаг ЗсНета = топдоозе.Зсбета; уаг арр = ехргезз(); уаг зсЬетаМате = пе« 8сЬета({ гедиезЕ: ЗЕгЕпд, Типе: МитЬег }, { со11есИоп: 'соИесПопЧате' }); уаг Мобе1 = топдоозе ,тоае1('МоаеГ, зсбетаЧате); топдоозе.соппесЕ('топдооЬ://1оса1ЬозГ:27017/бЬМгте ); уаг рог! = ргосезз.епу.Р08Т || 8080; арр.11зЕеп(рогЕ, ЕипсЕюп() { сопзо1е 1од('Мобе.]з 11зЕеп1пд сп рог! ' + рогЕ); // Чобе.]з слу шает на порту }); Теперь добавьте маршруты Ехргезздз, которые мы будем использовать для за- проса данных:
аор.дет('/Ттпб/:диегу , согз(), Гипсгюп(гед. гез) { уаг диегу = гед.рагатз.диегу; Мос1е1. Т±пс1 ({ 'гедиезТ': диегу }, Гипсс1оп(егг, гезиИ) { И (егг) И гол егг; И (гезиИ) { гез. ]зоп( гезиИ); } е1зе { гез. зепсК бЗЭГч. зТгтпдИу ({ еггог : 'Еггог' // Ошибка })); } }); }); Предположим, что следующие документы находятся в коллекции, связанной с моделью: { "_1сГ • ОЬ]ес11б("578аЬе97522аб414Ь8ееЬ55а1), "гедиезС . РауаЗсгтрГ 18 Аюезсчпе", "Нте" : 1468710551 } { "_1б : ОЬ]есС1с1('578аРе9Ь522аО414Ь8ееЬ55Ь '), 'гедиез!: : эауаЗспрг 1з Аиезоте", "Ите" : 1468710555 } { "_1с1 ОЬ]ес11б("578аЬеа0522аб414Ь8ееЬ55с 1), "гедиезТ : беуаЗспр! тз Алезоте", "Г1те" : 1468710560 } Цель заключается в том, чтобы найти и отобразить все документы, содержа- щие <Дауа5спрГ тз Атеезоте» под ключом «геоиезТ». Для этою запустите МогщоПВ и выполните зегуег.;з с помощью команды побе зегуег.]з. Использование Чтобы использовать этот код для поиска данных, перейдите по следующему 11КЬ в браузере:
Иг1р: //1оса1Ьо$1:8й8Э/Т1пс1/<диегу> ...где <диегу> — это поисковый запрос. Пример: НЩр: //1оса1Гюзс :8080/С1пс1/Зауа8сг1р1:%2018%20Аиезоте Вывод: [{ _1с1: 578аЬе97522ас1414Ь8еео55а , гериезС: ДауаЗспрТ 1з Алезоте", Типе: 1468710551, ______V: 0 }, { _1б: 1578аЬе9Ь522ас1414Ь8еео55Ь , гедиезс: ЗэуаЗсгтрС 1з Аиезоте", Типе: 1468710555, ______V: 0 } { _зс1: 578эЬеа0522ас1414Ь8ееЬ55с , гедиезг: ЗауаЗсгтрС 13 А^езоте", Ите- 1468710560, ______V: 0 }] Поиск данных в МопдсОР с использованием Мопдоэзе, маршрутов Ехргез&.]5 и оператора $1ех! Настройка Сначала установите необходимый пакет с помощью: прт 1пз1а11 ехргезз согз топдсозе Код Затем добавьте зависимости в зегуег.]з, создайте схему базы данных и имя коллекции, создайте сервер Ехргезз . ]з и подключитесь к МопцойВ: уаг ехргезз = геди!ге('ехргезз1); уаг согз = гедь1ге( согз'); // Мы будем использовать С0Р8 для разреше- ния запросов с других доменов. уаг топдоозе = геди!ге('топдоозе ’);
уаг 8сбета - топдоозе. 8с1тета, уаг арр = ехргезз(); уаг зсбетайате = пел 8оКета({ гедиез!: 81г1пд, Тите: МитЬег }, { соПесИоп 'соПес1юпМате' }): уаг Мобе! = топдоозе.тобе!('Мобе1', зсбетаМате); топдоозе соппес1( 'топдобЬ://1оса]1гоз1:27017/бЬМате ); уаг рог! = ргосезз.епу.РОКТ || 8080; аор. 11з1:еп(рогт, Типс!1оп() { сопзо!е.1од( Мобе.дз 11з1еп1пд оп рог1 ' + рог1); // Мобе.дз слу- шает на порту }); Теперь добавьте маршруты Ехргезздз, которые мы будем использовать для за- проса данных: арр.де1('/Нпб/:диегу ’, согз(), ТипсГ1оп(гед, гез) { уаг диегу = гед.рагатз диегу; Мос1е1.11ПС1 ({ геаиез!': диегу }, 1ипс11оп(егг, геяиН) { 11 (егг) 11тгои егг; 1Т (гези11) { гез. ]зоп( гезиИ); } е1зе { гез . зепб(б8ЭМ.81г1пд1-Гу( { еггог : 'Еггог' // Ошибка })); } }); }); Предположим, что следующие документы находятся в коллекции, связанной с моделью. { "_1б ОЬ]ес11б( 578аЬе97522аб414Ь8ееЬ55а '), ''гедиез! : ''бауа8сг!р! 13 Аиезоте", "Ите" : 1468718551 } { "_1б : 0Ь]ес!1б("578аЬе9Ь522аб414Ь8ееЬ55Ь"), "гедиез! : бауаЗсгтр! 1з Аиезоте",
"!1ше : 1468710555 } { _1Р : 0Ь]ес!16("578аЬеа0522а6414Ь8ееб55с '), "гедиез! : За'уаЗсгтр! 1з Аиезоте' , "!1те : 1468710560 } Наша цель — найти и отобразить все документы, содержащие только слово «]ауа8спрН> под ключом «героез!». Чтобы сделать это, сначала создайте текстовый индекс для «героев!» в кол- лекции. Для этого добавьте следующий код в зегуег. ] з: зс!тетаМате.1пбех({ героев!: Чех!’ }); ...и замените: Мсае1.Г1по( { 'героезс’ : риегу }, Гопс!юп(егг, гези1!) { на: Мобе1. Г1пб( •( $!ех!: { Ззеагсб: риегу } }, Гопс!юп(егг, геви1!) { Здесь мы используем операторы МопдоОВ $!ех! и $зеа гсН, чтобы найти все документы в коллекции соПесИопвате, которые содержат хотя бы одно слово из указанного поискового запроса. Использование Чтобы использовать этот код для поиска данных, перейдите по следующему ИКЬ в браузере Н!!р://1оса1Ьоз!.8О80/Г1пб/<риегу> ...и <риегу> — это поисковый запрос. Мопдоозе б!!р: //1осаНпоз! :8О80/'Г1пб/Зауа8сг1р! Вывод: 1{ 16: "578аЬе97522а6414Ь8ееЬ55а
гедиез!: "бауа8сг1рг 1з Анезоне", Мгле: 1468710551, __у: 0 }, { _1С1: "578аЬе9Ь522аб414Ь8ееЬ55Ь ', гедиез!: бзуаЗсгтрД 1з Алезогге", 11те: 1468710555, „у: 0 }, { _1б: 578аоеа0522аР414Ь8ееЬ55с ", гедиез!: бауаЗсгхр! 18 Алезоте , 11те: 1468710560, ______V: 0 }] Индексы в моделях Моп^оПВ поддерживает вторичные индексы. В Мопдоозе мы определяем эти индексы внутри нашей схемы. Определение индексов на уровне схемы необхо- димо, когда нужно создать составные индексы. Подключение Мопдоозе уаг зГгСоппесТюп = 'топдобЬ //1оса1Иоз(::27017/с1ЬМа*пе ; уаг оЬ = топдоозе сгеа1еСог1пес1юп(з1гСоппес11оп); Создание базовой схемы уаг 8сЬета = геди1ге('топдоозе').ЗсПета; уаг изегзЗсКета = пел 8сЬета({ изегпате: { гуре: 81г1пд, гедиггеб: 1гие, ипхдие: бгие }. ета11: { Гуре: 81г1пд, гедитгеб: 1гие }, раззлогб: { гуре: 81г1пд, геди!геб: Ггие },
сгеасеб: { Суре: ОаСе, беСаиТс: ОаТе.пол } }); уаг изегзМобе! = бЬ.тобе1( 'изегз', изегзЗсбета) ; тоои1е.ехрогсз = изегз^обе!; Но умолчанию Моп^оозе добавляет два новых поля в нашу модель, даже если они не определены в модели. Эти поля: дб Мопдоозе присваивает каждой из ваших схем поле _гб по умолчанию, если оно не передано в конструктор Зсйепта. Присвоенный тип — это СЬ]ес1Тс1. чтобы со- впадать с поведением МопдоБВ по умолчанию. Если вы не хотите, чтобы _1б до- бавлялся в вашу схему'вообще, вы можете отключить его с помощью этой опции: уаг изегзЗсбета = пем 8сПета({ изегпате: { Суре ЗТгюд, гедиггеб: Сгие, итдие: Тгие }, { _1б: Га1зе } }); _у или ссгзюпКеу уегзСопКеу — это свойство, установленное на каждом документе при его пер- вом создании с помощью Мощщозе. Значение этого ключа содержит внутреннюю ревизию документа. Имя этого свойства документа настраивается. Вы можете легко отключить это поле в конфигурации модели: уаг изегз8с1тета = пей 8с1тета({ изегпате: { Суре: ЗСгСпд, гедиггеб: Сгие, игидие' Сгие }. { уегдюпКеу Са1зе } }); Составные индексы Мы можем создавать другие индексы, кроме тех, которые создает Мэп§оозе:
изегз8с1теп'а. 1пбех( {изегпате: 1 }); изегз8сГ|еп,а. 1пбех( {ета11: 1 }); В этом случае наша модель будет иметь два дополнительных индекса: один для поля изегпате и другой для поля етаВ. Но мы можем создавать составные индексы: изегзЗсГ|еп;а. 1пбех( {изегпапе : 1 еггаП 1 }); Влияние индексов на производительность По умолчанию Моп§оозе всегда вызывает епзиге1пбех для каждого индек- са последовательно и генерирует событие дпбех для модели, когда все вызовы епзигеТпбех завершились успешно или произошла ошибка. В Моп§о1)В епзиге1пс!ех устарел с версии 3.0.0 и теперь является алиасом для сгеа(е1пбех. Рекомендуется отключить это поведение, установив для опции аи1о1пбех ва- шей схемы значение Та1зе. или глобально для подключения, установив опцию соп-Гдд.аиЮХпбехв Га1зе. изегзЗсбета.зеЦ'аиСоТтбех', ]а!зе); Полезные функции Мопдоозе Мопдоозе содержит некоторые встроенные функции, которые расширяют стандартный НпбО. бос,Г1пб({'зоте.уа1ие : 5}, ГипсСтоп(егг, оосз) { // возвращает массив босз }); ЗауазспрТ Копировать код оос.Г1пбОпе({‘зоте уа!ие’: 5}, Гипс!1оп(егг, бос) { // возвращает документ бос }); Зауазспрт Копировать код бос.Г1пбВу1б(оЬ],_1б, Лите Поп (егг, бос) { // возвращает документ бос }); Поиск данных в МопдоОВ с использованием промисов Настройка Сначала установите необходимый пакет с помощью: грт 1пз1а11 ехргезз согз топдоозе
Код Затем добавьте зависимости в зегуег. ] з, создайте схему базы данных и имя коллекции, создайте сервер Ехргезз. ]б и подключитесь к Моп&оОВ: уаг ехргезз = гесихге('ехргезз'); уаг согз = гедохге('согз ); // Мы будем использовать С0Р8 для разреше- ния запросов с других доменов. уаг топдоозе = гедихге('тспдосзе'); уаг ЗсКета = топдоозе.Зсбета; уаг арр = ехргезз(); уаг зсбетаМате = пей ЗсЬета({ гедиезТ: Зтппд, Типе: МитЬег }, { соПесПоп: 'соНесРхспЧате' }): уаг Мобе1 = топдоозе.тобе!('Мобе1', зсбетаИате); топдоозе соппесЦ'топдобЬ://1оса1Коз1:27017/бЬМгте ); уаг рог! = ргосезз.епу.РОРТ || 8080; эрр. 11зТеп(роГГ, Гипс1хоп() { сопзо1е.1од( Мобе.]5 1хзгепхпд оп рог! ‘ + рог!); // Мобе.]з слу- шает на порту }); арр.изе(Гипс1:1оп(егг, гед гез, пехТ) { сопзо1е.еггог(егг.з(:аск); гее.аТаГиз(500).зепб('ЗотеТбхпд Ьгэке!’); // Что-то пошлс не так! В; арр, изе(ТипсИоп( гед, гез, пехТ) { гез.з1а1из(404),зепб( Зсггу сапТ Тхпб СбаХ! ’); // Извините, не могу это найти1 }); Теперь добавьте маршруты Ехргезз.]з, которые мы будем использовать для запроса данных: арр. деЦ '/Тхпб/:диегу', ссгз(), бипсТхоп(гед, гез, пехС) { уаг диегу = гед.рагатз.диегу; Мобе1.Т1пб({ 'гедиез!': диегу }) .ехес() // не забудьте добавить ехес, запросы имеют атрибут .Сбей, но не являются промисами
.гНег1(Гипстюп(гезиИ) { 1Г (гези1!) { гез.]зоп(ге8и1С); } е1зе { пех!(); // переход к обработчику 404 } }) ,са!с11(пех!); // переход к обработчику ошибок }); Предположим, что следующие документы находятся я коллекции, связанной с моделью: { "_1с1 : 0Ь]ес!1б('578эЬе97522аб414Ь8ееЬ55а ), "гедиез! "ба\/а8сг1рс тз Ажезоте , "!1те" : 1468710551 } { _1б . 0Ь]ес!1б( 578абе9Ь522ао414Ь8ееЬ55Ь ), "гедиез! : "бауаЗсгхр! 1з Ажезоте", "!1те" : 1468710555 } { "_1б : ОЬ]ес!1б("578аЬеа0522аб414Ь8ееЬ55с"), "гедиез!" : "бауа8сг1р! тз А^езоте , "!1те" : 1468710560 } Наша цель — найти и отобразить все документы, содержащие «]а7а$сг1р! 13 Алезоте» подключом «геооез!». Для этого запустите МопдоОВ и выполните зегуег.]з с помощью побе зегч/ег. ]з: Использование Чтобы использовать этот код для поиска данных, перейдите по следующему ИКЬ в браузере: Истр: //ХосаХЬоз! :8080/'(:1пб/<диегу> ...где <-доегу> — это поисковый запрос. Пример: ЬТТр: //ХосаНюз! :8&80/-Г1пО/бауа8сг1р!оА201з%20А«езоп1е
Вывод: [{ 578аЬй97522ас1414Ь8еео55а , гедиези: ^Уа8сг1р1 15 Аиезоте", 11те: 1468710551, ______V: 0 }, { ,1с1: 578аЬечЬ522ас1414Ь8ееЬ55Ь", гериез!: 1а'/а8сг1р1: 1з Аи/езоте", Пте: 1468710555, __V: 0 }, { _1с1: 578аЬеа0522ас1414Ь8еео55с", гедиезг: ^уа8сг1рг 1з Аиезоте", Ите: 14687^0560, __V: б }]
Глава 52. Интеграция М8$01_ Введение Для интеграции любой базы данных с Хос1е.]8 требуется пакет-драйвер, или, как его еще можно назвать, модуль прт, который предоставит вам базовый АР1 для подключения к базе данных и выполнения операций. То же самое спра- ведливо и для базы данных М8ЭДЬ. Здесь мы интегрируем М88(Д с Мобедз и вы- полним несколько базовых запросов к таблицам 8рь. Примечания Мы предполагаем, что у вас будет запущен локальный экземпляр сервера базы данных М88(Д на локальном компьютере. Вы можете обратиться к это- му документу (Ьйр8://1еагп.т1сго8ОЙ.соп1/еп-и8/8д1/1тих/ди]ск8ГаП-]П';щ11-соппес(- иЬиЩи?стеиг=8д1-8егтег-уег16&щЬ8=иЬипГи2004) для получения дополнительной информации. Также убедитесь, что у вас создан соответствующий пользователь с добавлен- ными привилегиями.
Примеры Подключение к 801 через модуль прт твзд! Мы начнем с создания простого Ыос1е.^-приложения с базовой структурой, за- тем подключимся к локальному серверу базы данных и выполним несколь- ко запросов к этой базе данных. Шаг 1. Создайте каталог/папку с именем проекта, который вы собираетесь со- здать. Инициализируйте приложение Мойе.р, используя команду прт 1п1С, кото- рая создаст файл раскаде. ] зол в текущем каталоге. ггкснг ту8д1Арр //папка (директория) создана со ту8д1Арр //переход в новссозданный каталог прт 1п1С //ответьте на все вопросы прт 1пз1а11 //Это завершится быстро, так как мы еще не добавили никакие пакеты в наше приложение. Шаг 2. Теперь мы создадим файл Арр.)з в этом каталоге и установим не которые пакеты, которые нам понадобятся для подключения к базе данных 8(Д. зибо десИС Арр.]3 //Это создаст файл Арр.]з, вы можете использовать свой любимый тексто- вый редактор :) прт 1П5ТО11 --зауе тззд! //Эго установит пакет тззд1 в ваше приложение Шаг 3. Теперь мы добавим базовую конфигурационную переменную в наше приложение, которая будет использоваться модулем тззд] для установления со- единения сопзо1е.1од('Не11о лог 10, ТЫз 1з ап арр То соппесС Со зд1 зегуег."); уаг сопСбд = { изег": "туазег пате", //по умолчанию за "раззиогб : уоиг81гопд(!)Раззлогб", "зегуег : "1оса1ЛозГ , // для локальной машины 'бетаоазе : "зтадхпд , // имя базы данных "орССопз : {
епсгур!": тгое } } зд1.соппесб(сопТ1д, егг => { 1Т(егг) { СЬгол егг ; } сопзо1е.1од("Соппесгюп ЗиссеззГи! !"); пей зд1 .Редиез1() .диегу(' зе1ес1 1 аз питЬег’, (егг, гезиИ) => { //обработка ошибки сопзо1е.б1г(гези11) // Этот пример использует стратегию обратных вызовов для полу- чения результатов В }); зд!.оп('еггог', егг => { // ... обработка ошибок сопзо1е.1од( 8д1 саТаэазе ссппесПоп еггог ", егг); }) Шаг 4. Это самый простой шаг, где мы запускаем приложение, и оно подклю- чается к серверу 8()ь и выводит некоторые простые результаты. побе Арр . )з // Вывод: // НеПо то г ] с1. ТН15 15 ап арр 1о соппесТ То зд! зегуег. // СоппесТюп 8иссеззГи1 ! // 1 Чтобы использовать промисы или азупс для выполнения запросов, обрати- тесь к официальной документации пакета тззд!. • Ргоппзез: 1Шр8://уу^АУ.прт)5.сот/раска§е/т88д1#ргот18ез.
• Азупс/АтИ: 1шр8:/Луиду.прт]8.сот/раска8[е/т88д1#а8упс-аигак.
Глава 53. Многопоточность Введение Хобе.]з был разработан однопоточным. Таким образом, для всех практиче ских целей приложения, запускаемые с Хойе, будут работать в одном потоке. Тем не менее сам ХоДеДз работает многопоточно. Операции ввода-вывода и подобные задачи выполняются в пуле потоков. Кроме того, любой экземпляр приложения Хойе будет запускаться в отдельном потоке, поэтому для запуска многопоточных приложений нужно запускать несколько экземпляров. Замечания Понимание цикла событий (Еееп! 1оор) важно для понимания того, как и за чем использовать несколько потоков Примеры С1из1ег Модуль с1оз1:ег позволяет запустить одно и то же приложение несколько раз. Кластеризация желательна, когда разные экземпляры имеют одинаковый поток выполнения и не зависят друг от друга. В этом сценарии у вас есть один мастер, который может запускать форки (или дочерние процессы). Дочерние процессы работают независимо и имеют свое собственное пространство опера- тивной памяти и цикл событий. Настройка кластеров может быть полезна для веб-сайтов / ЛР1. Любой поток может обслуживать любого клиента, так как он не зависит от других потоков. База данных (например КеЛз) может быть задействована для совместного ис- пользования Сооктсз, так как переменные не могут быть разделены между по- токами: // гопз нт еасЬ 1пз1:апсе уаг с1оз1ег = герц1ге('с1изТег') ; уаг потСРОз = гер111ге( оз ).сриз().ТепдПт;
сопзо1е 1од('1 ат а1лауз саПесГ); 1Т (с1из1ег.1зМаз1:ег) { // гипз оп1у опсе (иК1ип сЬе тазСег); сопзсГе. 1од('I ат СЬе тазгег, 1аипсЬ1лд иогкегз!'); Тог(уаг 1 = 0; 1 < питСРОз: 1т+) с1из!ег.Тогк(); } е1зе { // гипз 1п еасН Тогк сопзс1е.1од( I ат а Тогк!'); // Неге опе сои1с! зсагг, аз ап ехатрГе, а «еЬ зегуег } сопзо1е 1од( 'I ат аЪ/ауз са11еб аз м;е1Г); СЫШ Ргосезз Дочерние процессы (С1пк1 Ргосеззез) используются, когда необходимо за- пустить процессы независимо друг от друга с различными инициализацией и задачами. Каки форки в кластерах. сЫ16. ргосезз выполняется в своем по- токе, но, в отличие от форков, он может общаться со своим родительским про- цессом. Связь происходит в обоих направлениях, поэтому родитель и потомок могут прослушивазъ сообщения и отправлять сообщения. Родительский процесс (../рагел! ]з): уаг с1з11б. ргосезз = гедц!ге('сЬПскргосезз’); сопзо1е.1од('[РагепТ]', 'ТпиаИне ); уаг сННсП = сПНсСргосезз Тогк(____Ыгпате + ’/сНПсГ); сИ1161 ,оп('теззаде’, Типс(:1оп(тзд) { соп8о1е.1од(,' | РагепС]', 'Ап8«ег Тгот сЫ16: ', тзд); }); // опе сап зепб аз тапу теззадез аз опе иапТ сЬ1161.зеп6('Не11о ); // не11с со уоо гео :) сЬ1161.зел6('Не11о'); // Не11с То уои Соо ;) // опе сап а1зо Ьауе ти1Т1р1е сНИбгеп уаг с!и162 = сЫ16_ргосезз Тэгк(___бхгпате + '/сЫ16'); Дочерний процесс (../сЬИсЦз): // Неге »оо16 опс хпхТхаИге Тпхз сН116 // ТЬхз их11 Ье ехесиСеб оп1у опсе соп8о1е.1од(' [СЫ16]', ‘1п11а112е '); // Неге опе ИзСепз Тог пей Тазкз Тгот СНе рагеп!
ргосезз.оп('теззаде', Гипс11оп(те8$адеРготРагепт) { // Оо зоте ДпТепзе логк Неге сопзо1е.1од(' [СН11Р] ’, ’СНИс! РоХпд зоте 1п1епзе лоск’); 1Г(теззадеГготРагеп1: == 'Не11о') ргосезз.зепр('Не11о То уои Тоо е1зе огосезз.зепсЦ л1гаТ7 ); }); Кроме сообщения можно прослушивать множество событий, таких как ‘е г гот’, 'соппестесГ или Ргзсоппест:’. Запуск дочернего процесса связан с определенными затратами. Желательно создавать как можно меньше таких процессов.
Глава 54. Пул соединений Му8рк Примеры Использование пула соединений без указания базы данных Рассмотрим достижение многопользовательского режима (шиИНепапсу) на сервере базы данных с несколькими размещенными на нем базами данных. Многопользовательский режим является обычным гребованием корпоратив- ных приложении в настоящее время, и создание пула соединений для каждой базы данных на сервере базы данных не рекомендуется. Вместо этого можно со- здать пул соединений с сервером базы данных, а затем переключаться между размещенными на нем базами данных по запросу. Предположим, что в нашем приложении есть разные базы данных для ка- ждой компании, размешенные на сервере базы данных. Мы будем подключать- ся к соответствующей базе данных компании, когда пользователь обращается к приложению. Вот пример, как это сделать: уаг роо1 = тузр1,сгеа1еРоо1({ соппесМопИтИ: 10, НозС: ехаггр1е.огд', изег: ЬоЬРу', раззиогс!: 'разз' }); роо! ,де1:Соппес11оп(Гипс(:1оп(егг, соппесТюп) { 1Г (егг) { ге!огп сЬ(егг); } соопесПсп. сбапде118ег( {баСабазе: "Т1гт1"}); соппесг1оп.дсегу("5ЕЕЕСТ * Тгот Ызтогу", Типсбтощегг, баса) { соппесТюп. ге1еазе(); сЬ(егг, оата); }); }):
Разберем пример. При определении конфшурации пула мы не указывали имя базы данных, а указали только сервер базы данных, то есть: { соппесИопИт!!: 10, Коз!: 'ехатр1е.огд', изег: ЬоЬЬу', раззиогО: разз’ } Таким образом, когда нам нужно использовать конкретную базу данных на сервере, мы просим соединение обратиться к базе данных, используя: соппесиоп.сбапде11зег( (баТаЬазе: "Г1гт1"}); Вы можете ознакомиться с официальной документацией здесь: Ъйрз://§Н11иЬ. сот/тузд1]8/тузд1#зсуйс111пй-изег5-апс1-аИег1пй-соппеспоп-51а1е.
Глава 55. Интеграция МуЗОЬ Введение В этой главе вы узнаете, как интегрироваться с Хобедз, используя инструмент управления базами данных Му5>фЕ. Вы научитесь различным способам подклю- чения и взаимодействия с данными, хранящимися в Му$(Д, с помощью про- граммы и скрипта на МоНе.(з. Примеры Запрос объекта подключения с параметрами Когда вы хотите использовать в контент, сгенерированный пользовате- лем, это делается с помощью параметров. Например, для поиска пользователя с именем апнпабау следует сделать так: уаг изегпате = 'апигэбау'; уаг диегузТппд = '8Е1ЕСТ пате, ета11 Ггот изегз у/Ьеге пате = ?'; соппесПоп диегу(диегузЕппд, [изегпате], Тилс11оп(егг, гоууз, Т1е1бз) { 1Г (егг) Изгол егг; 1Г (голз 1епд1Ь) { гойз ,1огЕасЕ('Гипс1:1оп(гоу|) { сопзо1е.1од(гои.пате, 'ета!1 аббгезз 1з’, гои.етат1); }); } е1зе { сопзо!е.1од( ТПеге у»еге по гезиИз.’); } });
Использование пула соединений Выполнение нескольких запросов одновременно Все запросы в Му8рЬ-соединении выполняются один за другим. Это означа- ет, что если вы хотите выполнить 10 запросов, и каждый запрос занимает 2 се- кунды. то выполнение всего процесса займет 20 секунд. Решением является со- здание 10 соединений и выполнение каждого запроса в разном соединении. Это можно сделать автоматически с помощью пула соединений. уаг роо! = тузя1.сгеаСеРоо1({ соппес11оп1_1т11: 10, ЬозГ: 'ехатр1е.огд', озег: боЬбу', раззиогО: 'разе', ааТаЬазе: 'зсИеша' }); Гог(уаг 1=0; 1<10; !++){ роо!.риегу('8Е1ЕСТ аз ехашр1е', ГопсПоп(егг, гол'з, ^1е10з) { 11 (егг) ГГ1Г01Л' егг; сопзо1е.1од(голз[0],ехатр1е); //Показать 1 }); } Это выполнит все 10 запросов параллельно. Когда вы используете пул, вам больше не нужно создавать соединение. Вы мо- жете выполнять запросы напрямую из пула. Модуль Му8р1 будет искать следую- щее свободное соединение для выполнения вашего запроса. Подключение к Му501_ Одним из самых простых способов подключения к Музрь является использо вание модуля тузц1. Этот модуль обрабатывает соединение между приложени- ем .\ойе.]з и сервером Му$(Д. Вы можете установить его. как и любой другой мо- дуль: орт 1пзСа11 --зауе тузр! Теперь вам нужно создать МуЗрЬ-соединение, которое вы сможете использо- вать для выполнения запросов в дальнейшем. сопзХ тузд! = геди!ге( 'тузд!') ; сопзТ соппесТтоп = тузд1.сгеа-1еСоппес1:1оп({
Иоз1. 1оса1бозт’, изег. 'те , раззиогск 'зесгеЕ’, баТабазе. ' баТабазе-зебегга' }); соппесттоп.согтес1(); // Выполнение некоторых запросов // Напоимер ЗЕьЕСТ * ЕРОМ Е00 соппесИоп.епЩ); В следующем примере вы узнаете, как выполнить запрос с использованием объекта соединения. Запрос объекта соединения без параметров Вы от правляете запрос в виде строки, и в ответной функции обратного вызо- ва получаете результат. Функция обратного вызова возвращает вам ошибку, мас- сив строк и поля. Каждая строка содержит все столбцы возвращаемой таблицы. Вот пример для пояснения: соппес!юп,диегу( ЗЕЬЕСТ пате, е1газ1 Тгот изегз’, Типс!.]оп(егг, голо, Тте1бз) ( 1Т (егг) Тбгол егг; сопзс1е.1од('ТГгеге аге: ’, гоиз.1епд!;Ь, 'изегз'); сопзо!е.1од('Е1Г31 изег папе 1з:', гоиз[0].пате); }); выполнение нескольких запросов с одним соединением из пула Могут возникнуть ситуации, когда у вас настроен пул соединений МуЗрЬ, но вам нужно выполнить несколько запросов последовательно: 8Е1ЕСТ 1; 8Е1ЕСТ 2; Вы могли бы просто выполнить их с помощью роо1.диегу. как показано ра- нее, однако если у вас есть только одно свободное соединение в пуле, вы будете вынуждены ждать, пока оно станет доступным, чтобы выполнить второй запрос. Однако вы можете сохранить активное соединение из пула и выполнить столько запросов, сколько вам нужно, используя одно соединение, с помощью роо!.де!СоппесТтоп:
роо! де1Соппест1О11(Типстюп (егг, сопп) { 1Т (егг) геТигп саПЬаск(егг) ; сопп.диегу(‘8Е1ЕСТ 1 А8 зед', ТипсТиоп (егг, гойз) { 1Т (егг) 1:11 гош егг; сопп.диегу( 8ЫЕСТ 2 А8 зед', Типе Псп (егг, гойз) { 11 (егг) 1Нгои егг; сопп.ге1еазе(); са11Ьаск(); }); }); }); Примечание: вы должны помнить о необходимости освободить соединение, иначе останется одно соединение Му8рЬ, недоступное для остальной части пула! Для получения дополнительной информации о пуле подключений МуВрь ознакомьтесь с документацией по Му8рЬ' Ьг»ря://1лчуи.пр1П]8.сот/раска^е/ туздИроойп^-соппесйопз. ‘Юзврат запроса при возникновении ошибки Вы можете прикрепить выполненный запрос к объекту егг, когда возникает ошибка: 7аг д = тузд1.диегу('8ЕЕЕСТ пате ЕРОМ рокебех ННЕРЕ 16' = ?', [ 25 ], ТилсИоп (егг, гезиИ) { 11 (егг) { // Таблица ' 1ез1.рокебех’ не существует егг диегу = д.зд1; // 8Е1ЕСТ пате ЕРОМ рокебех МНЕРЕ 16 = 25 саИЬаск(егг); } е1зе {
са11Ьаск(пи11, гезиИ); } }): Экспорт пула соединений // с1Ь. )з сопзТ тузд1 = геси1ге( 'тузд!') ; сспзТ рос1 = тузо1. сгеа1еРоо1({ соппесИопИтИ:; 10, 11051:: 'ехатрТе.огд', изег: 'ЬоЬ', раззиогс!: 'зесге!', с!а1:аЬазе 'ту_РЬ }): пос!и1е . ехрогг = { деТСоппесТюп: (саИРаск) => { геТигп роо1.де1Соппес1:1оп(са11Ьаск); } } // арр.зз сопзг с!ь = гедихге(’ ./с1Ь1); с1Ь деТСоппесТюпС (егг, сопп) => { сопп.диегу('8ЕТЕСТ зотеТГипд Тгот зотеТаЫе’, (еггог, гезиИз, Г1е1с1з) => { // получить результаты сопп ге1еазе(); }); });
Глава 56 Ы-АР1 Введение М АИ — это новый улучшенный способ создания нативных модулей для Мос1е.]8. Ы-АР1 находится на ранней стадии разработки, поэтому документация по нему может быть неполной или противоречивой. Примеры Приветствие в М-АР1 Этот модуль регистрирует функцию Ье11с в модуле Не 11о. Функция Ье11о вы- водит в консоль сообщение «Не11о иог1б» с помощью рг!п11 и возвращает 1373 из нативной функции в ]а\га8спр1-вызов: «1пс1ибе <побе_ар1.1т> #1псЗибе <з1б1о.1т> оар1_уа1ие 8ау_1те11о(пар1_еп7 епу, пар1_са11Ьаск_1пТо хпТо) { пар!_уа1ие ге1уа1; рпп1Т(' Не11о иог16\п"); пар1_сгеате_пипЬег(епу, 1373, &гетуа!); геТогп ге1уа1; } уо1(1 1п11(пар1_епу епу, пар1_уа!ое ехроПз, пар!_уа1ие тосЮ1е, уо16* РГ1у) { пар1_з1а1из з1а1ия; пар1_ргорег1у_0езспр1эг безе = { /* * Строка, описывающая ключ для свойства, закодированная в 6ТГ8.
*/ .иН8пате = "Ье11о , /* * Установите это значение, чтобы свойство уа!ие объекта дес- криптора свойства * стало ^ауаЗспрт-функцией, представленной методом. * Если этст параметр передан, установите значения уа1ие, денег и зеНег в М1л_1_ * (так как эти члены не будут использоваться). */ .ше1Пос1 = зау.Ье11о, /* * Функция, которая вызывается при получении доступа к свойству. * Если этот параметр передан, установите значения ма1ие и темной в мои * (так как эти члены не будут использоваться). * Данная функция вызывается неявно средой выполнения при до- ступе к свойству * из ЗамаЗсгтрТ-кода (или если выполнено получение значения свойства с помощью * вызова М-АРТ). */ .денег = ииН, /* * Функция, которая вызывается при установке значения свойства. * Если этот параметр передан, установите значения Vа1ие и теМзос! в мин * (так как эти члены не будут использоваться). * Данная функция вызывается неявно соедой выполнения при уста- новке значения свойства * из Рама8сг1рНкода (или если выполнена установка значения свойства с помощью вызова * 1Ч-АР1). */ .зеИег = МОН /* * Значение, которое возвоащается при получении доступа к свой- ству, если * это свойство является свойством данных, * Если этот параметр передан, установите значения деИег, зеттег, те^Коа и Дата в Мл_Е * (так как эти члены не будут использоваться). */ .уа!ие = МОП
/* * Атрибуты, связанные с конкретным свойством. См. пар1_ргорег1:у_ аХХгаЬиХез. */ .аГТтхЬиХез - парх.с1еГаи11, /* * Данные обратного вызова передаваемые в теТЬос!, денег и зеНег, если эта функция * вызывается. */ .баГа = ЧОН }; /* * Этот метод позволяет эффективно определить несколько свойств для заданного обьекта. */ зхахиз - парх_беХхпе_ргсрегххез(епу, ехрсгХз, 1, &с!езс); хТ (зхаХиз ’= парх_ок) геХигп; } МАРТ_ЧСЮ1Л_Е(1ле1]о, хпхХ)
Глава 57. Локализация Ыос1е.]8 Введение Рассмотрим, как поддерживать локализацию в Мобе.)3 с использованием ехргезз. Примеры Использование модуля И 8л для поддержания локализации в приложении на МоРе^з Рассмотрим легковесный простой модуль для перевода с динамическим хра- нением в формате }5О.\. Поддерживает обычные приложения на чистом \обе.)з и должен работать с любым фреймворком (такими как ехогезз, гезттРу и, веро- ятно. другими), который предоставляет метод арр. изе(), передавая в него объек- ты гез и гед. Использует общий синтаксис _('...’) в приложениях и шаблонах. Со- храняет языковые файты в формате ]8ОЫ, совместимом с форматом (леЫгапз]а1:ей ]8ОК. Добавляет новые строки «на лету», когда они впервые используются в ва- шем приложении. Не требуется дополнигельный парсинг: // обычные требования уаг ехргезз = геди!ге('ехргезз'), 118п = геди1ге('118п'), арр = тобо1е.ехрогГз = ехргезз(); 118п.сопТ1диге({ // настройка некоторых локален - другие локали по умолчанию пере- ключаются на ел без предупреждения 1оса1ез: [' еп', ' го', 'бе'], // задает имя соокте для анализа настроек локали соок!е: 'уоогсоокгепате', // где хранить ]зоп-файлы - по умолчанию './1оса1ез'
}); а1гес1огу: ___бтгпате + '/1оса1ез' арр.сопТ1диге(ТипсГ1оп () { // вам нужно будет использовать соокгеРагзег, чтобы сделать соокхез доступными через гер.сооктез арр.изе(ехргезз.соок1еРагзег()); // инициализация 118п, анализиоует гер на наличие заголовков язы- ка, соокхез и т.д. арр.изе(118п.1п11:); }); // обслуживание главной страницы арр.де!(' /’, ТипсПоп (гец, гез) { гез.зепа(гез.__('Не11о Ло^Хс! ')) ; }); // запуск сервера 1Т (1 тос1и1е. рагепх) { арр. 11з1еп(3000)
Глава 58. Сервер Моде без фреймворка Примечания Мойе имеет множество фреймворков, которые помогают быстро запустить сервер, среди них: Ехргезз: самый используемый фреймворк. То(а1: УНИВЕРСАЛЬНЫЙ фреймворк, который имеет все необходимое и не за- висит от других фреймворков или модулей. Но, как известно, универсального решения не существует, поэтом)' разработ- чику может понадобиться создать свой собственный сервер без каких-либо зави симостей. Если приложение доступно через внешний сервер, СОК8 может стать пробле- мой. Рассмотрим код. который поможет избежать этого. Примеры Сервер на Мойе без фреймворка уаг Ь!!р = гери1ге( 'ЫСр'); уаг Тз = геро1ге('Тз'); уаг ра!1э = гери1ге( оа!б'); 11!!р .сгеа!е8егуег(Типс!1оп (геоиез!, гезоопзе) { сопзо1е.1од('гедиез! гедиез!.иг1); уаг Т11еРа!б = + гедиез!. иг1; 1! (ТИеРа!Ь == ' . /') Т11еРа!Ь = ', / 1пс1ех. Ь!т1 ‘; уаг ех!пате = 3!г1пд(ра!б ех!пате(Т11еРа!б)),!оСоиегСазе(); уаг соп!еп!Туре = '!ех!/Ь!т1’; уаг тттеТурез = { ' .б!т1': '!ех!/Ь!т1’,
' .]з' : 'Техт/зауазспрС', }; ' .сзз' : ЧехТ/сзз’, .]зоп : арр11са11оп/]зоп', '.рпд' : ' иладе/рпд', ‘.]рд’: '1таде/]рд', '. дхТ' : '1паде/д1Т', 1 .йэу' : 'аибго/л'ау', ‘ .тр4’ : 'у]бео/тр4’, ' .иоТТ : ‘ аррИсаНоп/ТспХ-ло^Т’, ' .СТТ’: 'аррШсаНоп/ТопХ-СтТ', ‘.еоТ’: ’ аорЪсаСюп/упб рз-ТогТоЬ]ес1 ’, ‘.оТТ’: ’аррНсэНоп/ТопТ-оХТ ’, .зуд' : 'арр11саСюп/1п1аде/зуд+хп11' сопСепСТуре = т1теТурез[ехгпагге] | | 'аррИсагюп/осгесС-зСгеат Тз. геабс11е(Т11еРаТЬ. ТипсТ1оп(еггог, сопТепС) { 1Т (еггог) { 1Т(еггог.собе == 'ЕМОЕМТ'){ Тз. геабЕ11е( ' ./404 .ПСП11', Типс11оп(еггог, сопТепГ) { гезропзе.иг1ГеНеаб(200, { 'СопСепС-Туре': сопСепТТуре }); гезропзе.епа(сопСепТ, 'и1Т-8'); }); ) е1зе { гезропзе.игбСеНеаЩ5Э0); гезропзе.епб('Зоггу, сЬеск 1Ье з11е абтХп Тэг еггог: ' + еггог.собе + ' ,.\п'); гезропзе.епб(); } } е1зе { гезропзе.«г1СеНеаб(200. { ’СопТепТ-Туре': соп!еп1Туре }); гезропзе.епб(соп1:еп1:, 'и1Т-8'); } }); }).11з1еп(8125); сопзоХе.1од('Зегуег гипптпд а! ИТгр://127.0.0.1:8125/1); Решение проблем с СОРЕ // Сайт, который вы хотите разрешить для подключения гезропзе.зеТНеабег(' Ассезз-СопТго1-А11о«-0Пд1п', *');
// Методы запросов, которые вы хотите разрешить гезропзе. зеТНеас1ег( Ассезз-СопГгоТ-АПол-ЧеРПойз1, 0РТ10ГЧ8, РОТ, РАТСН, ОЕЬЕТЕ ') : // Заголс-ки запросов, которые вы хотите разрешить гезропзе. 8еРНеас1ег( Ассезз-СопТгоТ-АПои-НеаЗетз', ИНЬ, сопТепТ-Туре’); СЕТ, РОЗТ, 'Х-Рериез1:ес1 - // Установите в 1гие, если вам нужно, чтобы сайт включал куки в запро- сы, отправляемые на АР1 // (например, в случае использования сессий) гезропзе.зе1Неа0ег( Ассезз-СопТгс! А11ой-Сгес1епГ1а1з’, Тгие);
Глава 59. Ыос1е.]з (ехргез8.]в) с Апди1аг.]з Введение В этой главе показано, как создать базовое приложение на Ехргезз и затем ис- пользовать Ап^о1аг]8. Примеры Создание проекта Мы готовы начать, поэтому выполняем в консоли: ткй1г оиг_рго]ес! ей оиг_рго]есС Теперь мы находимся в папке, где будет размещен наш код. Чтобы создать ос новной файл нашего проекта, можно запустить команду. Как создать каркас проекта на ехргезз? Это просто: прт хпзгаИ -д ехргезз ехргезз-депегаюг В дистрибутивах Тлпох и Мас для установки этой команды необходимо ис- пользовать ЗиЛе, так как они устанавливаются в каталог поае]8, доступ к которо- му имеет только пользователь гооТ. Если все прошло успешно, мы наконец мо- жем создать каркас Ехргезз приложения, просто запустив ехргезз Эта команда создаст пример приложения ехргезз внутри нашей папки. Структура будет следующей:
Ь1п/ риЫ1С/ гоиГез/ У1вй8/ арр.]з раскаде.]зоп Теперь, если мы запустим прт этап и перейдем на (тетр://ХосаХКозГ :3000, мы увидим, 41 о приложение Ехргезз работает. Эго хорошо, но как мы можем объ- единить эго с Ап$и1аг|8? Как работает Ехргезз? Ехргезз — это фреймворк, построенный поверх Мойе.]з. Вы можете ознако- миться с официальной документацией на сайте Ехргезз (1шрз://ехргез8]8.сот/). Для наших целей нужно знать, что Ехргезз отвечает за отображение страни- цы, когда мы вводим, например, Ьгцх/ДосаИтозЕЗОООДтоте. В недавно созданном приложении можно проверить: Файл: гоигез/тпйехдз уаг ехргезз = гедигге('ехргезз'); уаг гоиТег = ехргезз Вои1ег(); /* 6ЕТ Ропе раде */ гои1ег.деГ(, Типс1зоп(гед, гез, пехТ) { гез. гепбег( ’ Тпбех', { ШХе: 'Ехргезз' }); }); тобиХе.ехрогТз = готЛег’ Этот код указывает, что при переходе пользователя на Ипр /ДосаПтозЕЗООО должно быть отображено представление Хпбех и передан ]8ОХ с свойством
Ш1е и значением Ехргезз. Но если мы проверим каталог ухелз и откроем файл хп бех. ] ас1е, то увидим следующее. ехДегбз ТауоиД Ыоск сопДепЕ И1= ДхД1е р Ме1соше Го #{1х11е} Это еще одна мощная функция Ехргезз — шаблонизаторы (Детр1аЕе егдхпез). Они позволяют отображать содержимое на странице, передавая в него перемен- ные, или наследовать другой шаблон, чтобы ваши страницы бьыи более ком- пактными и понятными для других. Расширение файла . дайе. По некоторым сведениям, Дабе сменил название на Род Это по сути тот же шаблонизаюр, но с некоторыми обновлениями и изменениями ядра. Установка Рид и обновление шаблонизатора Ехргезз Итак, чтобы начать использовать Рид в качестве шаблонизатора в нашем про- екте, нужно запустить: прт хпз1а!1 --зауе рид Это установит Рид как зависимость нашего проекта и сохранит его в раскаде. ] зоп. Чтобы использовать его, нужно изменить файл арр. ] з: уаг арр = ехргезз(); // ухеи/ епдхпе зеДир арр зех('ухелз’, рат11.]охп(_бхспаше, 'ухеиз')); арр.зеД('ухел епдхпе’, 'род'); Замените строку счету ещцпе на рп§. и на этом все. Мы можем снова запустить наш проект с помощью прт зТаг! и убедиться, что все работает правильно. Как Апди!аги8 вписывается во все это? Ап$>и1ат)8 — это }ауа8спрг-фреймворк МУЭД (Мобе1-У1е\у-АА'11а(еуег), в основном используемый для создания 8РА (8шд1е Раре Аррйсайоп). Установка довольно проста: вы можете зайти на сайт Ап§и1аг]8 (Ййр5://ап2п1ат]5.ог§,) и загрузить последнюю вер- сию, на данный момент это VI 6.4. После того как мы загрузили Ап§и1ат)8, нуж- но скопировать файл в пашу папку риЫхс/ ]ауазсгюсз внутри проекта. Поясним: это папка.
267 которая обслуживает статические ресурсы нашето сайта, такие как изображе- ния, С88, {ауаЗспрЦфайлы и так далее. Конечно, это можно настроить через файл арр. уз. но мы будем придерживаться простою подхода. Теперь создаем файл с именем пд-арр.у з,в котором будет находиться наше приложение, внутри папки у'ауазсгирбз в роЬЗтс, где также находится Ап§и1аг]8. Чтобы запустить Ап§и1аг]8, нужно изменить содержимое файла У1елз/1ауоиД. род следующим образом: босбуре Гп.т1 Ьып1(пд-арр='Ттгзг-арр') беаб 1111е= ДиИе 11пк(ге1='зТу1езпее(:', ИгеТ= ’ /з-1у1езбее1з/з1у1е.сзз') бобу(пд согЧгоПег^'хпбехСопГгоПег ’) Моск сопбепТ зспр1:(гуре-' СехД-уауазсгхр! ’, згс= уауазсг1р1з/апдМаг.пип.уз') зсг1рГ(Суре=Чехб-уауазсг1о1:', згс=' уауазсгютз/пд-арр. уз’) Что мы делаем здесь? Мы включаем ядро Апяи1аг|8 и наш недавно создан- ный файл пд-арр. ] з, чтобы при отображении шаблона Ап§и1ат)8 был активиро- ван. Обратите внимание на использование директивы пд-арр — она указывает Апйи1аг}8. что это имя нашего приложения, и он должен привязываться к нему. Итак, содержимое нашего файла пд-арр. у з будет следующим: апди1аг.шо0и1е('Гтгзб-арр', []) .сопТгоПегД 1пбехСопДго11ег ’, [$зсоре', ТпОехСоМгоПег]); ГипсТюп 1пдехСоп1:го11ег($зсоре) { $зсэре.пате = ‘зхдТпеб ; } Здесь мы используем базовую функцию Ащщ1аг}8—двустороннее связывание данных. Это позволяет нам обновлять содержимое представления и контролле- ра мгновенно. Это очень простое объяснение, но вы можете поискать информа- цию в Соо&1е или на 81аскОуегйот/у, чтобы узнать, как это работает на самом деле. Итак, у нас есть базовые блоки нашего приложения на Лпяи1аг]8, но есть еще кое-что, что нужно сделать: обновить нашу страницу 1пбех. род, чтобы увидеть изменения в нашем Апдп1аг-приложении. Давайте сделаем это. ехбепбз ХауооД Моск сопТепт б1У(пд-соптго11ег= ’ тпбехСопбгоПег ’) Ы = П11е р Ие1соте {{пате}} 1приТ(Туре='-(:ех1: ’ пд-тобе1=' пате ’)
Здесь мы просто связываем ввод с нашим определенным свойством пате в области видимости Ап§и1аг}8 внутри нашего контроллера: Ззсоре.пзте = 'зтдТпеб'; Цель этого заключается в том, что всякий раз, когда мы изменяем текст в поле ввода, абзац выше будет обновляться с содержимым внутри ({пате}}. Это назы вается интерполяцией и является еще одной функцией Ап§и1аг}8 для отображе- ния содержимого в шаблоне. Итак, все настроено, теперь мы можем запустить прт зТагТ, перейти на М.1р: / /ТосаИзсзТ .3000 и увидеть, как наше Ехргезз-приложенпе обслужива- ет страницу, а Ап§ы 1аг]8 управляет фронтепдом приложения.
Глава 60. 1Чос1е.]$ и МопдоОВ Примечания Это основные операции СКИП для работы с МопдоОВ в Ыос1е.)8. Вопрос: Можно ли сделать то, что сделано здесь, другими способами? Ответ: Да, существует множество способов сделать это. Вопрос: Обязательно ли использовать Моп^оозе? Ответ: Нет. Существуют другие пакеты, которые могут помочь. Вопрос: Где я мозу найти полную документацию но Мощщозе? Ответ: Перейдите по ссылке Ьйрзу/Моп^оозе^.сотМосз/аркМоп^оозе.Мт!. Примеры Подключение к базе данных Для подключения к базе данных Мощщ из приложения на ТЧосГеД8 требуется Моп§оо8е. Установка Мопдоозе Перейдите в корень вашего приложения и установите Мощщоье с помощью команды:
прт 1пзТа11 топдоозе Далее подключаемся к базе данных. уаг топдоозе = гедлге( топдоозе'); // Подключаемся к тестовой базе данных, запущенной на стандартном пор- ту топдоб на 1оса1поз1: топдоозе соппес1('топдобЬ’//1оса1Ьоз1/Тез1:'); // Подключение с использованием пользовательских учетных данных топдоозе . соппесТД 'топдобЬ://ОЗЕР: РА88И0РО@Н08Т:РОНТ/0АТАВА8Е’); // Использование Роо1 81ге для определения количества открытых соеди- нений // Также можно использовать функцию обратного вызова для обработки оши- бок топдоозе соппесТД 'топдобь://ЗосаТЬоз!:?7017/сопзитег5', {зегуег: { рос181ге' 5И }), ТипсТюп(егг) { 1Т(егг) { сопзо1е.1од('еггог 1п ТИ1з') сопзо1е.]од(егг); II Выполнить действия для обработки ошибки } еТзе { сопзо!е.1од('Соппесгеб то тКе баТаЬазе); } } ); Создание новой коллекции В Мопдоозе все основывается на схеме (ЗсНета). Давайте создадим схему: уаг топдоозе = гедоТге('топдоозе’); уаг ЗсЬета = топдсозе.5с1тета уаг Аи1о8сбета = пел 8сНета({ пате : 8Тг1пд, соипТОТ: МитЬег, }); // определение структуры документа // по умолчанию коллекция, созданная в базе данных, будет названа в со- ответствии с пеовым параметром (или его множественным числом) тобиТе.ехрогДз = топдоозе.тобе!( АиТо АиТо8сПета);
// мы можем переопределить это и задать имя коллекции, указав его в третьем параметре. тоаи.1е. ехрогсз = топдоозе. тос!е1( АиТо’, АиЮЗсЬета, 'соПесСюпМате'); // Также мы можем определить методы е моделях. АиСоЗспета.теПтосз.зреак = Гипс (ют () { уаг дгееМпд = тЫз.паше ? Не11о сЬ1з 18 + т!пз.папе + апо I Ьауе соиптз оГ + сГпз.соипЮГ : "I Рои’I Каме а пате", солзо1е.1од(дгееТ1пд); } топдоозе.тобе1('АиСо', АиСоЗсПета. 'соПесПопМгте’); Помните, что методы должны бы зь добавлены к схеме до компиляции ее с по- мощью Мопдоозе. тобе1(), как показано выше. Вставка документен Для вставки нового документа в коллекцию мы создаем объект схемы: маг Ао1о = геди1ге( тобе1з/аито'); мае аигоОЬ] = пел Аисо({ пате: МеиМате', соипгОГ: 10 }); Сохраняем его следующим образом: аигоОЬ] .зауе(-ГипсС1ол(егг, юзегсебАиТо) { 1Г (егг) геСигп сопзо1е.еггэг(егг); 1пзег1-ебАи1:о.8реак(); // оигрис: Не11о г1пз 1з МеиИате апб I Каме соипСз о! 10 }); Это вставит новый документ в коллекцию Чтение Чтение данных из коллекции происходит очень просто. Получение всех дан- ных из коллекцшг уаг Аи1о = геци!ге('тобе1з/аиСо ); АиТо.С1пб({}, Сипсгюп (егг, аиТоз) ( 1Г (егг) гетит сопзэ!е .еггог(егг); // вернет бЗС^-массив всех документов в коллекции
сопзо1е 1од(аи1оз); }): Чтение данных с условием: АоЮ.Т1пб( {соилЮ'Г: {$д1е: 5}}, ГипсПоп (егг, аиТоз) { 1Т (егг) геТигп сопзо1е.еггог(егг); // вернет 38014-массив всех документов в коллекции, где ссипС боль- ше или равен 5 сопзо1е 1од(аиТоз); }); Также вы можете указать второй параметр как объект, определяющий, какие поля вам нужны: АиЮ.Нпб({}, {пате:1}, ГипсИоп (егг, аитоз) { 1Г (егг) ге!игп сопзо1е еггсг(егг); // вернет з80М-массив с полем пате всех документов в коллекции сопзо1е.1од(аоГэз); }); Нахождение одного документа в коллекции: АоЮ.Т1пс10пе({пап1е: "легате }, ГипсТюп (егг, аиЮ) { 1Т (егг) геТигп сопзо1е.еггог(егг); // вернет пеовый объект документа, у которого паше равен пеи/Гюте ’ сопзо1е.1од(аиГо); }); Нахождение одного документа в коллекции по Ш: Ао1:о.ТТпбВуТЩ 123, тигсПоп (егг, аДо) { 1Т (егг) геТигп сопзо1е.еггог(егг) ; // вернет первый 380^-объект документа, у которого 16 равен 123 сопзоХе 1од(аиГо); }); Обновление Для обновления коллекций и документов можно использовать любой из этих методов • ирбагеО • ир6а!е0пе() • ирбаТеМапуО • гер1асе0пе()
ир(1а{е() Метод ирбаСеО модифицирует один или несколько документов (параметры обновления). 6Ь. ИдЫ з. ирбате( { гооп: Вебгост }, { з1а1оз • "Оп ' } ) Эта операция ищет в коллекции ИдЫз документ, где гоош равно ВебгоопГ (1-й параметр). Затем она обновляет свойство згаТиз совпадающих документов до ' Оп" (2-й параметр) и возвращает объект йгИеРезоИ, который выглядит так: { пМаТсйеО" : 1, 'пОрзегГеб" : 0, "пМоббИеО : 1 } Ир(1а(еОпе Метод ОрбатеОпеО модифицирует ОДИН документ (параметры обновления). 6Ь соип1г1ез орбаге( { соипТгу: "&лебеп" }, { сар!1а1: "81оскбо1т } ) Эта операция ищет в коллекции соипГгтез документ, где соипСгу равно "8*ебеп" (1-й параметр). Затем она обновляет свойство сарйа! совпадающею до- кумента до "81оскбо1т" (2-й параметр) и возвращает объект ИгИеРезиИ, кото- рый выглядит так: { аскпо1л'1ебдеб" : {гое, шаТспебСоип!' : 1, ' тобКлебСоипТ" : 1 } ИрйагеМапу Метод ОрбасеМапуО модифицирует несколько документов (параметры обнов- ления). бЬ.Гооб.ирба1еМапу( { зо1б: { $11: 10 } }, { $зет: { зо1б 55 } } ) Эта операция обновляет все документы (в коллекции !ооб), где зо16 мень- ше 10 (1-й параметр), устанавливая зо16 на 55. Затем она возвращает объект йгтсеРезиИ, который выглядит гак: { ' аскпо«1ебдеб" : Тгое, та-СсбебСоопТ : а, 'тобтТтебСоип!:" : Р }
где: • а = количество совпадающих документов • Ь - количество модифицированных документов Нер1асеОпе Заменяет первый совпадающий документ (документ для замены). Эта коллекция соипгпез содержи! три документа: { "ДсТ : 1, 'соипГгу : "5\тес1еп' } { "_1сГ : 2, "соипГгу" : "№гиау1 } { "_1сГ : 3, "соипГгу : ''Браш' } Следующая операция заменяет документ { соипГгу: "БраДп } на документ {соипггу. "Е1п1апсГ }: ОЬ.соипГпез. гср1асе0пе( ( соипггу: 8ра1п" }, { соипГгу: "ЕтпТапс! } ...и возвращает: { "аскпои1есдес! : Ггие, "шаГсНеаСоипГ" : 1, "тоск/хебСоипГ" : 1 } Теперь коллекция соипГгГез содержит: { "_1д" : 1, соипггу" : "Зиедеп" } { "_1с1" : 2, 'соипГгу : "Исглау ' } { : 3, соипггу : "Е4п1апа } Удаление Удаление документов из коллекции в Моп§оозе выполняется следующим образом: АиГо гето7е({_1с!:123}, ГипсГюп(егг, гези^Г){ 1-Г (егг) гегигп сопзо!е.еггсг(егг); сопзо1е.1од(гези1г); // это выведет результат удаления го умолча- нию в МопдоЭВ });
Глава 61. Архитектура и внутренняя работа Мойере Примеры Мос1е.]5 — «под капотом» Мсс1е.|5 — «в движении» ЯцгМгп*
Глава 62. Код Модеме для 8ТО1Ы и 8Т00УТ без использования библиотек Введение Это простая программа на Гмос1е.]5, которая принимает ввод от пользователя и выводит его в консоль. Объем ргосезз является глобальным и предоставля- ет информацию о текущем процессе 1Чос1е.)8, а также контроль над ним. Буду- чи глобальным, он всегда доступен в приложениях Ыо(1е.]5 без использования гсдитгеО. Примеры Программа Свойство ргосезз.зтбзп возвращает поток, эквивалентный или ассоцииро- ванный с зСсНп. Свойство ргосезз.зСбоиС возвращает поток, эквивалентный или ассоциированный с зТбоиС: ргосезз.згб1п.гезите(); сопзо1е. 1од('ЕгтСег СЬе баСа то Ье Лзр1ауеб'); ргосезз.з1:б1п.оп( баса , 'Гипс'С1оп(ба1:а) { ргосезз.зСбоит иг1Те(ааУа); });
Глава 63. Основы проектирования Мос1е.]8 Примеры Малое ядро, малые модули Создавайте небольшие однопрофильные модули не только с точки зрения размера кода, но и с точки зрения охвата, чтобы они выполняли одну задачу: а - "8та11 1з ЬеаиСтГо! Ь - "Маке еасП ргодгат до опе гН1пд ие11.1 Шаблон Неас1ог Шаблон ВеасДог является «сердцем» асинхронной природы Ыос1е.]8. Он позво- ляет системе работать как однопоточный процесс с серией генераторов событий и обработчиков событий, с помощью постоянно работающего цикла событий. Неблокирующий движок ввода-вывода Мойе — НЬдо Шаблон ОЬзегсег (ЕуепСЕпибсег) поддерживает список зависимых/наблюда- телей и уведомляет их: уаг еуепбз = гедо1ге('еуепТз'); уаг еуепГЕтШег = пел еуепСз. Еуеп1ЕпнПег() ; уаг г!пдВе11 = Топспоп Г1пд6е11() { сопзо1е. 1од( ' Сг1пд сгьгд гг1пд’); } еуепбЕт11:1:ег,оп( 'доогОреп', гтпдВеП) ; еуепсЕпитсег. етп( 'ооогОреп');
Глава 64. Управление ошибками в Мос1е.]8 Введение В этой главе мы изучим, как создавать объекты ошибок, а также как вызывать и обрабатывать ошибки в Хо(1е.]5, Примеры Создание объекта ошибки (Еггог) пе\у ЕггоНтезза^е) Создает новый объект ошибки, где значение теззаде устанавливается в свойство теззаде созданного объекта. Обычно аргумент теззаде передается конструктору Еггог как строка. Однако если аргумент теззаде является объек- том, а не строкой, конструктор Еггог вызывает метод л с8гг1пд() у переданно- го объекта и устанавливает это значение в свойство теззаде созданного объек- та ошибки: 7аг егг = пел Еггог("Тбе еггог теззаде"); сопзоХе.Ход(егг.теззаде); // Выводит: ТИе еггог теззаде сопзоХе.1од(егг); // Вывод: // Еггог: ТИе еггог теззаде //а! ... Каждый объект ошибки имеет трассировку стека. Трассировка стека содержит сообщение об ошибке и показывает, где именно она произошла (выше приведен вывод трассировки стека). Как только объект ошибки создан, система захваты- вает трассировку' стека ошибки на текущей строке. Чтобы получить трассировку стека, используйте свойство зТаск любого созданною объекта ошибки. Следую- щие две строки идентичны: сопзоХе.Ход(егг); сопзоХе. Ход(егг.з1:аск);
Выброс ошибки Выброс ошибки означает исключение. Если исключение не обработано, сер- вер 1\обе.]з завершится аварийно. Следующая строка выбрасывает ошибку: ДЬгой лей Еггог( 8оше еггог оссоггесГ); или уаг егг = пей Еггог( Зоше еггог оссоггеб ); сИгой егг; или гМгой Богле еггог оссиггесГ; Последний пример (выброс строк) не является хорошей практикой и не реко мен,дуется (всегда выбрасывайте ошибки, которые являются экземплярами объ- екта Еггог). Учтите, что если вы выбросите (ГЬгодлг) ошибку в вашем коде, система завер- шит работу на этой строке (если нет обрабо]чиков исключений), и никакой код после этой строки не будет выполнен. уаг а = 5; уаг егг = пей Еггог(8спе еггог теззаде"); сЬгой егг; // это выведет стек ошибки, и сервер Мобе.]‘з остановится а++' // эта строка никогда не будет выполнена сопзо1е.1од(а); // и эта также Но в этом примере: уаг а = 5; уаг егг = пей Еггог("8о1ле еггог теззаде'); сопзо!е.1од(егг); // это выведет стек ошибки а++; сопзо1е.1од(а); // эта строка будет выполнена и выведет б Блок 1гу...са1сН Блок 1 г у ..саИсН используется для обработки исключений. Помните, исключе- ние означает выброшенную ошибку, а не ошибку. Дгу { уаг а = 1; Ь++; // это вызовет ошибку, так как Ь не определена соп.яо1е.1од(Ь); // эта строка не будет выполнена } саГсб (еггог) {
сопзоТе 1од(еггог); // здесь мы обрабатываем ошибку, вызванную в блоке Тгу } В блоке сгу э++ вызывает ошибку, и эта ошибка передается в блок сатсб, где она может быть обработана или даже выброшена снова с некоторыми изменени- ями. Рассмотрим следующий пример; Ггу { уаг а = 1; Ь++; сопзо1е.1од(Ь); } са1сИ (еггог) { еггог.теззаде = ‘Ь уэгтаЫе тз ипОеГтпеб, яо Убе ипбеТтпес! сап'! Ье тпсгетепУеб ; |Ьгои еггог; } В приведенном выше примере мы изменили свойство теззаде объекта ошиб- ки. а затем выбросили измененную ошибку. Вы можете выбросить любую ошибку в вашем блоке Г гу и обработать ее в бло- ке сабсЬ: Тгу { уаг а = 1; ТЬго^ пел Еггог(‘8оте еггог теззаде'); сопзо1е.1од(а); // эта строка не будет выполнена } саУсК (еггог) { сопзо1е 1од(еггог); // будет выброшена вышеуказанная ошибка }
Глава 65. Производительность Ыос1е.}8 Примеры Цикл событий При мер блокирующей операции 1еТ 1оор = (1, тах) -> { иЫ1е (1 < тах) 1++ геТигп 1 } // Эга операция заблокирует Мобе.^з, // потому что она ориентирована на процессор (СР11-Ьоипс1). // Вам следует быть осторожными с подобным кодом. 1оор(0, 1е+12) Пример неблокирующей операции ввода-вывода (Ю-Ьоипд) 1еГ 1=0 сопзТ з1ер = тах => { и/Ь11е (1 < тах) 1++ сопзо1е. 1од(' 1 = %сГ, 1) } сопз! Т1ск = тах => ргосезз.пехГТ1ск(з-1ер, тах) // это отложит выполнение цикла м/ЬНе б з1ер до циклов цикла событий // любая даугая операция, ориентированная на ввод-вывод (напримев, чтение файловой системы), может выполняться параллельно 11ск(1е+6) 11ск(1е+7)
сопзо1е.1од( ЧЫз «111 оиДрас ЬеТоге а11 оГ ±1ск орегаУюпз. 1 = %б1, 1) сопзо1е.1од(’Ьесаизе Иск эрегаПэпз «111 Ре розИропеР') 11ск(1е+8) Проще говоря, цикл событий — это одиопоточный механизм очереди, кото- рый выполнет ваш код, ориентированный на процессор, до завершения его вы- полнения, и код, ориентированный на ввод-вывод, в неблокирующем режиме. Однако «под капотом» !У'обе.]& использует многопоточность для некоторых своих операций через библиотеку ИЬну. Документацию по этой библиотеке мож- но найти по ссылке йПрз://11Ьиу.ог2/. Рекомендации по производительности • Неблокирующие операции не блокируют очередь и не влияют на производительность цикла. • Однако операции, ориентированные на процессор, будут блокировать очередь, поэтому вам следует избегать таких операций в вашем коде на Хо(1е.]'з.
Хойе.)8 не блокирует операции ввода-вывода, так как передает их выполне- ние ядру операционной системы, и когда операция ввода-вывода предоставляет данные (как событие), она уведомляет ваш код с помощью переданных вами об- ратных ВЫЗОВОВ Увеличение тахЗоскеТз Основы гедитге(' Мир'). д1оЬа!Адепс .тахЗоскеСз = 25 // Вы можете изменить 25 на ТпЕДпиу или другое значение эксперимен- тируя Но умолчанию Мос(е)8 использует тах8оске1з - 1пйпйу (начиная с \70.12.0). До версии ?4ос1е у0.12.0 значение по умолчанию было тахЗоскеТз - 5. Так что после более чем пяти запросов они будут поставлены в очередь. Если вы хотите увеличить параллелизм, увеличьте это число. Установка собственного агента АР1 (айр использует 6) оЬа1 АдепТ. Вы можете предоставить свой собственный агент. Например: сопз!: Мир = геди1ге('Мир') сопзС тубГотюизАдегТ = пе« Мир. АдепТ({ кеерАЦуе: Тгие }) ту61огюизАдетЦ .пахЗоскеТз = 1пТ1п11у Нир. гедиез!: ({ адепт: туБХогтоизАдеп!: }, ...) Полное отключение пула сокетов сопз!: (тир = теди1ге('(тир1) СОП31 орИопз = {....} орТюпз. адепТ = Та1зе сопзТ гедиез!: = Нир. гедиезТДорТюпз) Подводные камни • Вам нужно проделать то же самое для АР1 (Шрз, если вы хотите добиться таких же эффектов. • Учтите, что, например, АМЗ будет использовать значение 50 вместо 1пйпйу. Включение §г1р сопз!. Мир = геди!ге('Мир') сопз! Тз = геоитге('Тз')
сопзТ 2110 - геяи1ге('г11Ь’) П1Гр.сгеа!е8егуег((гериезГ, гезропзе) => { сопз! з!геат = Гз.сгеа1ейеаа81геат( '1пс1ех.ЫтГ ) сопз! ассер1зЕпсос1пд = гедиез!.Кеайегз['ассер!-епсосипд'] 1е1 епсойег = { 1лазЕпсос1ег : Та1зе, соп1:еп1:Епсос11пд: {}, сгеа1еЕпсос1ег : () => 1Ьгой ТЬеге 1з по епсодег } 1Г (!ассергзЕпсо<11г|д) { ассертзЕпсоскпд = ' ’ } 1Т (ассер^зЕпсоскпд .1па1с11(/ХодеНаЕехЬ/)) { епсос1ег = { ИазЕпсос)ег : Хгие, соп1еп1Епсос11пд: { ' соп1еп1-епсоскпд' : 'аеТ1а1е }, сгеаТеЕпсойег : ?11Ь сгеаГеОеПаЕе } } е!зе !? (ассер^зЕпсоскпд .таГ.сЬ(/ХЬдгтрХО/)) { епсос1ег = { ИазЕпсойег : Егие, соШепгЕпсоскпд: { 'сэпгепАепсосНпд' : 'дгхр' }, сгеагеЕпсобег : гИЬ.сгеаЕеСгир } } гезропзе..уг11:еНеаа(2е0, епсоаег .сопХепгЕпсоскпд) 1Т (епсойег ЬазЕпсос1ег) { зГгеат = зЕгеат р!ре(епсос1ег.сгеа1еЕпсос1ег()) } з1геат.р1ре(гезропзе) }) .1181ел(1337)
Глава 66. Новые функции и улучшения 1Мос1е.]$ у6 Введение С выходом Мобедь гб в качестве новой версии ЬТ8 произошел ряд улучшений благодаря новым стандартам Е$6. В этой главе мы рассмотрим некоторые из но- вых функций, введенных в Мойе.]8 у6, и примеры их реализации. Примеры Параметры по умолчанию для функций ГипсПоп ас!дГ«о(а, Ь - 2) { ге1игп а + Ь; } ас!аТ«о(3) // Возвращает результат 5 С добавлением параметров по умолчанию для функций вы теперь можете сде- лать аргументы опциональными и задать им значения по умолчанию на ваше усмотрение. Остаточные параметры Еипстюп агдитепгЬегд^Ь(. . .агдз) { геУигп агд5.1епдИ1; } агдитеп11епд11т(5) // возвращает 1 агдитеп11епдСН(5, 3) // возвращает 2 агдитеп11епд1:Ь(5, 3, 6) // возвращает 3 Если перед аргументом функции указать ..., то все переданные функции ар- гументы будут восприниматься как массив. В этом примере мы можем переда-
вать несколько аргументов и получать длину массива, созданного из этих ар- гументов. Оператор расширения (Зргеас! ОрегаТог) ТипсМоп туЕипсЫоп(х, у, г) { } уаг агдз = [и, 1, 2]; туГипс1юп(. ..агде); Синтаксис расширения позволяет расширить выражение в местах, где ожи- даются несколько аргументов (.для вызовов функций), несколько элементов (для массивов) или несколько переменных. Подобно остаточным параметрам, просто поставьте... перед массивом. Стрелочные функции (Агго« ЕипсйопБ) Стрелочная функция—это новый способ определения функции в ЕСМА8спр( 6. // традиционный способ объявления и определения функции уаг кит = ТипсТ1оп(а,Ь) { геТигп а+Ь; } // Стрелочная функция 1е1 зит = (а, Ь) => а+Ь; // Определение функции с использованием нескольких строк 1е1 сбескИЕуеп = (а) => { 1Т( а % 2 ~ 0 ) геТигп тгие; е1зе геТигп Еа1зе; } ЙН8 в стрелочных функциях ТЬ1з в функции ссылается на объект-экземпляр, который использовался для вызова этой функции, но тЫз в стрелочной функции равен сЫз функции, в которой определена стрелочная функция. Давайте попробуем разобраться с помощью диаграммы:
Л теперь рассмотрим использование ХЫз на примере’ уаг поггса1Еп = ТипсИоп(){ сопзо1е, 1од(ТМз) // ссылается на глобальный объект (д1оЬа1/ и/1пс1ои). } уаг агго^Гп = () => сопзо1е.1од(1:1т1з); // ссылается на глобальный объ- ект, так как функция определена в области глобального объекта уаг зегутсе = { сопзТгисЮгЕп : ТипсИоп(){ сопзо!е.1од(СЬ1з); // ссылается на объект зегутсе, так как объ- ект зегутсе используется для вызова метода. уаг пезседЕп = Типс1:1оп(){ сопзо1е.1од(1Ь1з); // ссылается на глобальный объект, по- тому что объект-экземпляр не использовался для вызова этого метода. } пез1:ес1Еп(); }. агголЕп : ТипсТ1оп(){ сопзо1е.1од(б1т1з); // ссылается на объект зегуъсе, так как эбъ ект зегуюе использовался для вызова метода. 1еС Тп = () => сопзо1е.1од(Т111з); // ссылается на объект зегуюе, так как стрелочная функция определена в функции, которая вы- зывается с использованием объекта-экземпляра.
^п(); } } // вызов определенных функций сопз1:гисГогРп(); аггоиЕп(); зегу1се.сопз1гисЮгЕп(); зегу1се.аггоиЕп(); В стрелочной функции 1618 — это лексическое окружение, которое пред- ставляет собой область видимости функции, в которой определена стрелочная функция. Первый пример — это традиционный способ определения функций, и, соот- ветственно, Пэ 18 ссылается на глобальный объект (§1оЬа1/и] пбош). Во втором примере ГГнз используется внутри стрелочной функции, поэтому 1К13 ссылается на область, в которой она определена (что является глобальным объектом или объектом млп(1оэ/у). В третьем примере 161з ссылается на объект зетсе, так как объект зеппсе используется для вызова функции. В четвертом примере стрелочная функция определена и вызывается из функ- ции, область видимости которой — объект зеппсе, поэтому она выводит объект зепйсе. Примечание: в Койе.'з выводится глобальный объект, а в браузере — объект уяпсКлу.
Глава 67. Ыос1е.]§ с С0Р8 Примеры Включение С0Я8 в ехрге88.]8 Так как Хойе.]8 часто используется для создания АР1. правильная настройка СОН8 может стать спасением, если вы хотите иметь возможность отправлять за просы к АР1 с разных доменов. В этом примере мы настроим СОК8 для самой широкой конфигурации (разре- шение всех типов запросов с любою домена). В вашем зегуег ]§ после инициализации ехргезз' // Создание сервера ехргезз сопз! арр = ехргезз(); арр.изе((гед, гез, пех!) => { гез.ЬеабсЦ ' Ассезз-Соп1:го1-А11ои- Огтдзп', ; // разрешенные заголовки для ргеТИдЫ запросов // КТСрз: //беуе1орег .гпогШа .огд/еп-118/с1осз/6]оззагу/ргеП1дЫ:_ гедиез! гез.(1еас!ег( 'Ассезз-Соп1го1-А11о«-Неабегз', Огхдхп, Х-&едиез1ес1- )Ш1т, СопГепГ-Туре, Ассер!'); пех!(); арр.ор):1опз(, (гед, гез) => { // разреиенные методы ХНР гез.1теааег(’Ассезз-Соп1:го1-А11о»ч-Меспос1е СЕТ, РАТСН, РОТ, Р08Т, ОЕЕЕТЕ, 0РТ10М8'); гез.зепа(); }); }):
Обычно Мог1е.]8 работает за прокси-сервером на продакшн-серверах. Следова- тельно, сервер обратного проксирования (например, АрасПе или М#1пх) будет от- ветственен за настройку’ СОКЕ». Чтобы удобно адаптировать этот сценарий, можно включить СОК8 в Кобе.]5 только в режиме разработки. Это легко сделать, проверив переменную окружения МСОЕ_ЕМУ: сопзС аро = ехргезз(); И (ргосезз.епу.М00Е_ЕМ7 === беуеТортегтС') { II настройки С0Р8 }
Глава 68. 1Чос1е.]$ с Е36 Введение Е56, ЕСМА8спр( 6 или Е82015 — это спецификация ]ауа8спр1, которая позволя ет использовать синтаксический сахар. Это большое обновление языка, которое предоставляет множество новых возможностей. Более подробную информацию о Г^ойе и Е86 можно найти на сайте: НгГрз:// по(1е]8.ог§/епЛеагп/§е(:пп$’-81ап.ес1/есгпа5сг1р1-2015-е8б-апс1Ьеуопс1. Примеры Поддержка Е56 в К4ос1е.|5 и создание проекта с ВаЬе! Стандарт Е86 еще не реализован полностью, по- этому вы сможете использовать только некоторые из новых возможностей. Вы можете увидеть список текущих поддерживаемых функций Е8Ь на сайте 1Шр://пос1е.§гееп/. Начиная с Мос1е.]8 версии 6 появилась доволь- но хорошая поддержка. Поэтому, если вы работаете с Модеме версии 6 или выше, вы можете наслаждать- ся использованием Е86. Однако, возможно, вы так-
же захотите задействовать некоторые нереализованные функции и некоторые функции из будущих стандартов. Для этого вам потребуется транспайлер (тран- скомпилятор). Можно запустить транспайлер во время выполнения и сборки, чтобы ис- пользовать все функции Е8б и даже больше Самый популярный транспайлер для }ача8сг1р( называется ВаЬе). ВаЬе! позволяет вам использовать все функции из спецификации Е86 и не- которые дополнительные, не входящие в стандарт, функции с •зЩ^е-0’, такие как тшрогС 1К1пд Тгош ‘Изтпд’ вместо уаг ТЫпд = геди!ге('ТЫод'). Если мы захотим создать проект, в котором будем использовать функ- ции ' а Гаде - 0 , такие как ЕпрогГ, нам нужно будет добавить ВаЬе! в качестве транспайлера. Вы увидите, что проекты, использующие РеасС и Уие, а также дру- гие шаблоны на основе СотпюпбЗ, часто реализуют ' зГаде- 0’. ткбтг ту-езб-арр сб ту-езб-арр прт 1П11 Установите ЬаЬе1, пресет Е86 и зГа^е-О: прт хпзСаИ --зауе-беу ЬаЬе1-ргезеС-ез2015 ЬаЬе1-ргезе1-з1аде-2 ЬаЬе1- с1т ЬаЬе1-гед1з1ег Создайте новый файл с именем зегуег ] з и добавьте базовый НТТР-сервер: ттрогГ ЫТр Егот 'Ш1р Кггр.сгеа1е8егуег((гед, гез) => { гез .уугхТеНеаб (200, {'СопСепГ-Еуре': ЧехГ/р1а1п’}) гее епб( 'Не11с ’Лог1б\п') }). 1ззтеп(3000. '127.0.0.Г) сопзо1е.1од('Зегуег гиппхпд а! НГГр;//127.0.0.1:3000/') Обратите внимание, что мы используем впрогТ ЫТр Ггот 'ЫЛр' — это функция ‘збаде-б', и если она работает, это значит, что мы правильно настрои- ли транспайлер. Если вы запустите посе зегуег. ] з, он завершится с ошибкой, не зная, как об- рабатывать (троге. Создайте файл ,ЬаЬе1гс в корневом каталоге вашего проекта и добавьте следу- ющие настройки: { "ргезеГз . ["ез2015", зтаде-2"]. 'р1ид1пз": [] } Теперь вы можете запустить сервер с помощью команды: побе згс/1пбех.]з --ехес ЬаЬе1-побе
В завершение, запуск грана 1айлера во время выполнения на продакшн-при- ложении — не лучшая идея. Однако мы можем реализовать несколько скриптов в нашем раскаде. ] зоп, чтобы облетчить работу зсг:тр(:з : { "з1:аг1 . пссе ЛзХ/хпбех . ]з , "беу' : "ЬэЬе1--побе згс/1пбех.]з", "ЬаИб РаЬе1 зге -б 6131:", "розНпзтаП : прт гип Ьи11с1 }. вышеописанное будет компилировать код в каталог дзет при установке прт и позволять прт згап использовать гранспилированный код для нашего про- дакт и приложения. Команда прт гип бе у запустит сервер и ВаЬе1 во время выполнения, что впол- не допустимо и предпочтительно при работе над проектом локально. Пойдя дальше, вы можете установить побешоп: прт 1пз1а11 побетоп --зауе-беу для отслеживания изменений и перезапуска побе приложения. Это действительно ускоряет работу с ВаЬе! и \’обе.]8. В вашем раскаде.]зоп просто обновите скрипт беу, чтобы использовать побешоп: "беу": "побетоп зге/гпбех ]з --ехес ЬаЬе1-побе', Использование Е8б в вашем Мойере-приложении Е86 (также известный как Е82015) — это набор новых возможностей для язы- ка ]ауа8спрг, направленный на то, чтобы сделать его более интуитивно понят- ным при использовании ООП или при решении современных задач разработки. Предварительные условия 1. Ознакомьтесь с новыми возможностями Е86 на сайте 1Шр://е8б-Геашге8.ог^—это может помочь вам решить, действительно ли вы хотите использовать его в вашем следующем К'обедз-приложении.
2. Проверьте уровень совместимости вашей версии Пойе на сате 1Шр://пос1е.§гееп. 3. Если все в порядке — давайте кодировать! Вот очень короткий пример простого приложения «НеПо Йо г 1 б» с использо- ванием Е86: 'озе з1:г1с1' с1азз Ргодгат { сопз1;гисЮг() { сЫз.теззаде = 'РеПо езб } рГ1П1() { зеГНтеоиЦО => { сопяо1е.1од(1±1з.теззаде); 1Ь1з.рг1гт(() ; }, МаПз. гапбот() * 1030); } } пе^ Ргодгат() ,рг1пЦ); Вы можете запустить эту программу и наблюдать, как она выводит одно и то же сообщение снова и снова. Теперь давайте разберем ее построчно: ‘озе зТгхсС' Эта строка необходима, если вы собираетесь использовать Е86. Строгий (з(псС) режим намеренно имеет другие семантические особенности по сравне- нию с обычным кодом.
с1азз Ргодгат Невероятно — ключевое слово с1азз! Для справки: до Е56 единственным спо- собом определения класса в )ауа8спр( было использование ключевого слова ТипсСхоп: ЕипсТлоп МуС1азз() { // определение класса } уаг туС1аззСЬ]ест = пел МуС1азз(); // создание нового объекта типа МуС1азз При использовании ООП класс — это очень важная возможность, которая помогает разработчику представлять определенную часть системы (разбиение кода на части критично, когда код становится большим, например, при написа- нии серверного кода): сопз!гис1ог() { ГЫз .теззаде = 'РеПо езб :)'; } Признайте, это довольно интуитивно! Это конструктор класса — данная уникальная «функция» будет выполняться каждый раз, когда создается объект из этого конкретного класса (в нашей программе — только один раз): ргтпТД) { зесТ1теои-(:(() => // это стрелочная функция { соп5о1е.1од(1б1з.теззаде); ГР1з.рг1пС(): II здесь мы вызываем метод 'рг1п1' из самого шаблона класса (в данном случае это рекурсия) }, Ма1Н.гапбот() * 1000); } Так как рг!п1 определен в области видимости класса, это фактически метод, который можно вызывать как от объекта класса, так и из самого класса! Итак, до сих пор мы определяли наш класс. Пришло время его использо- вать:
пел Ргодгат().рг1п1(); ...что эквивалентно: уаг ргод = пей РгодгапЦ); // определение нового объекта типа 'Ргодгат' ргод.рг!п1:(); // исполозование программы для самовывода В заключение: Е56 может упростить ваш код, сделать его более интуитив но понятным и легким для понимания по сравнению с предыдущей версией |ага5спрг. Попробуйте переписать свой существующий код. и вы сразу увидите разницу. НАСЛАЖДАЙТЕСЬ:)
Глава 69. Использование Ыос1е.]8 с Огас1е Примеры Подключение к Огас1е ОВ Очень простой способ подключения к базе данш>гх ОКАСЬЕ — использование модуля ог ас1ебо. Эт от модуль управляет подключением между вашим приложе- нием на Ыос1е.]8 и сервером Огас1е. Вы можете установить его, как любой другой модуль прт 1пз1:а11 огасЗебЬ Теперь вам нужно создать подключение к ОКАСЬЕ, которое вы сможете ис- пользовать для выполнения запросов сопз! огас1ебЬ = геалге('огас]ебЬ ); огасТебЬ.десСоппест1оп( { изег : о!1", раззиогд : 1раззлогд , солпесС81г1пд . ОРАС1Е_ОЕУ_ОВ.Т№_МАМЕ" }, соппЕхесиГе ); солпесГЗГгТпд «ОКАСЬЕ_ВЕ\ЦЭВ_Т\А_МАМЕ» может находиться в фай- ле [пзпапез.огд в том же каталоге или в месте, где установлен ваш Огас1е 1п8(ап( СИелЕ Если на вашей машине для разработки не установлен клиент Огас1е 1пз1ап1, вы можете следовать руководству по установке 1пз{ап1 СИепГ дтя вашей операци- онной системы.
выполнение запроса на объекте соединения без параметров Теперь вы можете испо.гьзоъать функцию соппЕхесиТе для выполнения за- проса. У вас есть возможность получить результат запроса как объект или мас- сив. Результат выводится в сопзсХе. Ход: ТипсХХоп соппЕхесиТе(егг, соппесТюп) { 1Т (егг) { сопзоХе.еггог(егг.теззаде); геТигп; } зд1 = зеХес! 'тезе' аз с1, 'огасХе' аз с2 Тгот биаХ"; соппесТХоп.ехеси!е(здХ, {}, { оиТЕогтаТ: огасХебЬ.ОВДЕСТ }, // или огасХебО.АРНАУ Типс1Хоп(егг, гезиХт) { 1Т (егг) { сопзоХе.еггог(егг.теззаде); соппРеХеазе(соппесСХоп); гесигп; } сопзоХе.Ход(гезиХт.техаОаТа); сопзоХе.Ход(гезиХг.го«з); соппРе1еазе(соппес11оп); }); } Так как мы использовали соединение без пула, необходимо освободить его по- сле использования: ТипсГХоп соппРеХеа5е(соппесСХоп) { соппестюп. сХозе( ТипсТХоп(егг) { ХТ (егг) { сопзоХе.еггог(ег г.теззаде); } }); }
Вывод для объекта будет таким: [ { пате С1 }, { пате' ’С2’ } ] [ { С1 : Чез!’, С2: 'огас1е' } ] А вывод для массива будет следующим: [ { пате "СГ }, { пате: ' С2 ’ } ] [ [ ЧезЕ', 'огас1е ] ] Использование локального модуля для упрощения запросов Чтобы упростить выполнение запросов из ОкАСЕЕ-БВ, вы можете вызывать свой запрос следующим образом: сопзе огас1е = гедитге(‘./огас1е.]з'); сопз! зд1 = зеЕесС ЧезЕ' аз с1, 'огас1е' аз с2 Чот Виа11; огас!е диегуОЬ]есЕ(зд1. {}, {}) ,ЕНеп(ГипсЕ1оп(гези1Е) { сопзо1е.1од(гези1Е.голзI0]['С2']); }) -саЕсЬ(ГипсЕ1оп(егг) { пехЕ(егг); }); Создание соединения и выполнение запроса включено в файл огас1е.]з со следующим содержанием: ' изе зЕгтсЕ'; сопзЕ огас!ебЬ = геди!ге('огас1ебЬ'); сопзс огас1еОЬРе]еазе = ГипсЕюп(сопп) { сопп.ге1еазе(ТипсС1оп (егг) { 14 (егг) сопзо1е.1од(егг.теззаде) ; }); }; ГипсЕтоп диегуАг гау(зд1, ЬтбРагатз, орЕюпз) { орсюпз. тзАиЕоСоттлЕ = ГаХзе; // мы выполняем только ЗЕЕЕСТ-запросы геЕигп пей Ргот1зе(ТипсС1оп(гезоКе, ге)есЕ) { сгас1ебб.детСоппесЕ1эп( { изег : о11 , раззлогб ' раззлсгб , соппесЕЗЕппд : ОРАСЕЕ.ОЕУ ОВ ТИА МАМЕ .ЕПеп (Гипс-Стоп (соппесИоп) {
//сопзо1е 1од('зд1 Ход: " + зд] + ' оаггтз + ЫпбРагатз); соппес11оп.ехеси1:е(зд1, ЬтпбРагэтз, орИопз) ЛЬеп(-Гипс1гоп(гезиИз) { гезо1уе( гезиИз); ргосезз.пехсТ1ск(Типс1юп() { огас!еОЬРе1еазе(соппес1:1оп); }); В .саТс11(Типс11оп(егг) { ге]ес1(егг); ргосезз пех1Т1ск(Рипс(:1оп() { огас1еОЬРе1еазе(соппес1:1сп); }); }); }) .саТсЩТипсГюгЦегг) { ге]есХ(е г г); }); }); } ГипсТюп диегуО1^ес1;(зд1, ЬтпйРагашя, ор^юпз) { ор11опз[ оиТРогтаГ ’ ] = огас1ес1о.ОЕк)ЕСТ; // по умолчанию огас!ес1Ь. АРРАУ гетигп диегуАггау(зд1, ыпс1Рагап81 ор^юпз); } тос1и]е.ехрог1з = диегуАггау; тос1и1е ехрогХз. диегуАг'-ау = диегуАггау; тос1и]е.ехрог18.диегуОЬ;ес1 = диегуОЬтес!; Обратите внимание, что у вас есть два метода — диегуАггау и диегуОЬ]ест — для вызова на вашем объекте огас!е
Глава 70. Руководство для начинающих по Мос1е.]5 Примеры Не11о \ЛГог1с1! Разместите следующий код в файле с именем Ие110'лог1с1 ] з: сопзо1е. 1од(’Не11о Йог1с1 ); Сохраните файл и выполните его через Ыос1е.]'8: псде Ье11олог1с1 ]з
Глава 71. Фреймворки 1Чос1е.]8 Примеры Фреймвооки для веб-серверов Ехргеаа уаг ехргезз = геди1ге('ехргезз’); уаг арр = ехргезз() ; арр.деГ('/‘, ТипсИоп (гея, гез) { гез зепс1( ’НеПо И1ог1с1!'); }); арр. Из1:еп(3000, ТипсГшп () { сопзо1е.1од('Ехатр1е арр 1181еп1пд оп рог! 3000!'); }); Коа уаг коа = геди1ге('коа’); уаг арр - коа(); арр.изе(ТипсР1оп *(пех(){ уаг згаг! = пей Оане; у!е1с1 пех!; уаг тз = пел 0а1е - 81аг1: сопзо1е.1од(’%з %з - %з', 1И15.теЕЬос!, 1И1з.иг1, тз); }); арр.изе^ипсИоп *(){ 1И1з.Ьос!у = 'Не11о ‘Лог1с1 ; }); арр.11з1еп(3000);
Фреймворки для интерфейса командной строки СоттапЛег.]8 уаг ргодгат = геди1ге('соттапЬег'); ргодгат .уегз1оп('0.0.1 ') ргодгат .соттапсЦ 1и') с!езсг1р11эп( 1г.1Иа112е рго]ес! сопНдигаПоп') .ас11оп(Гипс11оп(){ сопзоЗе ]од( Н1 ту Рг1епс1! ! ! ’); }); ргодгат соттапс!( Руе [гате] ’) .с!езсг]р11оп(' 1п1Г1а117е рго]ес! сопИдигаиоп ) . ас11оп(Типс-(:1ог.(пате) { сопзо!е.]од('Вуе ' + пате + '. 1Т лаз доод 1о зее уои1); }); ргодгат ,соттапс1( '*') асЫогЦТипсНоЩепу) { сопзо!е.1од( Еп1ег а \/а1ю соптапсГ); 1:егт1па1е(1гие); }); ргодгат рагзе(ргосезз.агду); Уогра1.}8 сопз! уогра1 = геди!ге(‘уограГ)(); уогра1 ,соттапс1( Тоо', ОиРриТз "оаг .’) .асИоп^ипсНоЦагдз, саНЬаск) { 1Ь1з.1од('Ьаг’); са11Ьаск(); }); уогра! . <1е11т11е г ( туарр$') .зЬол();
Глава 72. История Мос1е.]8 Введение Рассмотрим историю Мойе.)5 и информацию о версиях. Ключевые события по годам 20С9 • 3 марта — проект был назван «побе». • 1 октября — первый предварительный просмотр прт, менеджера пакетов Мобе. • 8 ноября — оригинальный доклад Райана Даля (создателя Мобе.)з) о Мобе. ]’зна ]8СопГ 2009. 2010 • Ехргезз: фреймворк для веб-разработки на Мобе.]з. • Первоначальный выпуск ЗоскеНо. • 28 апреля — экспериментальная поддержка Мобе.]з на Негоки. • 28 июля — технический доклад Райана Даля о Мобе.]з в Соо§1е. • 20 августа — выпуск Мобе.(з 0.2.0 2011 • 31 марта — руководство по Мобе.)з. • 1 мая — прт 1.0: выпуск.
• 1 мая — АМА («спроси меня о чем угодно») с Райаном Далем на КейсЫ. • 10 июля—Завершена работа над книгой «Тйе Хойе ВеяшпегВоок», введение в МоДе.]5. о Комплексный учебник по Хобе.]8 для начинающих. • 16 августа — ЫпкесИп использует Кобе.]8. о ЫпкесИп запустил полностью обновленное мобильное приложение с новыми функциями и новыми компонентами. • 5 октября — Райан Даль рассказывает об истории Ыос1е.)8 и о том, почему он его создал. • 5 декабря Мос1е.)8 в производстве в Ь'Ьег. о Менеджер по разработке НЬег Кёртис Чамберс объясняет, почему ею компания полностью перестроила свое приложение с использованием Мк1е.|8 для повышения эффективности и улучшения опыта партнеров и клиентов. 2012 • 30 января — создатель МойеДз Райан Даль уходит от повседневных дел, связанных с Хойе • 25 июня — вышла Хос1е.)8 с0.8.0 [стабильная версия]. • 20 декабря — выпущен Нар! — фреймворк Х’оскф. 2013 • 30 апреля — стек МЕАХ: Моп^ойВ. Ехрге88]8. Ап§п1аг]8 и Хос1е.]8. • 17 мая — как мы создали первое приложение еВау на Ыос1е.)8. • 15 ноября — РауРа! выпускает Кгакеп, фреймворк Мос1с.]8. • 22 ноября —утечка памяти в Х’оДе.]8 в Ша1шаП. о Эран Хаммер из лабораторий М’айпаП пришел к основной команде Мос1е.)8, жалуясь на утечку памяти, которую он отслеживал месяцами. • 19 декабря — Коа — веб-фреймворк для Ь)ос1с.]8. 2014 15 января — Т| ЕоЫате берет на себя проект Хойе.
• 23 октября — консультативный совет Мобе.]8. о |оуеп(:инесколькочленовсооб1цесгваМобе.]8 объявили предложение о создании Консультативного совета Мобе.]8 как следующего шага к полностью открытой модели управления проектом с открытым исходным кодом. • 1У ноября — Мобе.]8 в Пате СгарЪз — МеШтх. • 28 ноября — 1О.]8 ас1шхронный1;ОдляУ8]ауа8СПрК 2015 • 14 января —10.]8 1.0.0 • 10 февраля |оуеШ стремится создать Мобе.]8 Гоипбайоп. о ]оуеп(, 1ВМ, М1СГО8ОЙ, РауРа1, ПбеШу, 8ЛР и ТЬе Ыпих Роипбайоп объединяют усилия, чтобы поддержать сообщество Мобе.]8 с нейтральным и открытым управлением. • 27 февраля — предложение о примирении Ю.]8 и Мобе р. • 14 апреля — при ватные модули прт. • 28 мая — руководитель проекта Мобе Т] Роп(аше уходит и покидает ]оуеп(. • 13 мая — Ыобе.]8 и ю.)8 объединяются под эгидой Мобе Роипбайоп. • 2 августа — Тгасе — мониторинг производительности и отладка Мобе.]8. о Тгасе — это визуализированный инструмент мониторинга микросервисов, который предоставляет все необходимые метрики при работе с микросервисами. 13 августа — 4.0 — это новая 10. <24 12 октября — Мобе У4.2.0, первый выпуск с долгосрочной поддержкой.
• 8 декабря — Ар1§ее, Ш8Ш&81 аскиУаТюо присоединяются к Мобе.]8 Роипбайоп. • 8 и 9 декабря — Кобе 1п(егас1п/е. о Первая ежегодная конференция \обе.]8 от Мойедз Еоппйайоп. 2016 • 10 февраля — Ехргезз становится инкубированным проектом. • 23 марта инцидент с 1ейра<1. • 29 марта — Соо#1е С1оиб ИагГопп присоединяется к Побе.]8 Гоипбаиоп. <22 • 26 апреля — у прт 210 000 пользователей. РЗ • 18 июля - С| Зйуепо становится СТО прт. • 1 августа—Тгасе. решение для отладки Мобе )8, становится общедоступным. • 15 сентября — первая 1мос1е ТпГегасцуе в Европе. • 11 октября — выпушен менеджер пакетов уагп. • 18 октября — Мос1е.]8 6 становится версией с долгосрочной поддержкой. Ссылка «История Хобе.]8 на временной шкале»: йир8://Ь)о8.г18т§81аск.сот/1и8(огу- оГ-побе-]8/.
Глава 73. Маршрутизация в Ыос1е.]8 Введение Рассмотрим, как настроить базовый веб-сервер Ехргезз под Мойедз, и исследу- ем маршрутизатор Ехргезз. Примечания В конечном итоге, задействуя маршрутизатор Ехргезз, вы можете использо- вать функции маршрутизации в своем приложении, и это легко реализовать. Примеры Маршрутизация веб-сервера Ехргезз Создание веб-сервера Ехргезз Сервер Ехргезз оказался удобным и получил широкое распространение. С каждым днем он становится все более популярным. Давайте создадим сер вер Ехргезз. Для управления пакетами и гибкости в управлении зависимостями мы будем использовать ХРМ (Хойе Раскате Мапа^ег). 1. Перейдите в каталог проекта и создайте файл раскаде. ] зоп. раскаде.узоп { 'паше : ехргеззРооЕег", ЧегзЕоп : 0.0.1", 1 зспрсз : { ’зЕагЕ": 'побе Зегуег.]з }.
"с!ерепс1епс1ез": { "ехргезз : "А4.12.3 } } 2. Сохраните файл и установите зависимость Ехргезз, используя команду прп хпзСаИ. Это создаст папку по0е_то0и1е5 в вашем каталоге проекта вместе с необходимыми зависимостями. 3. Создайте веб-сервер Ехргезз: перейдите в каталог проекта и создайте файл зегуег. ]з зегуег.]з уаг ехргезз = геси!ге( ехргезз ); уаг арр = ехргезз(); // Создание объекта 9оиТег() уаг гоаТег = ехргезз.Роо1ег(); // Обеспечьте все маршруты здесь, это для главной страницы. гои1ег деТ("/”, Еипс(:хоп(гед, гез) { гез.]зоп({'теззаде' Не11о Иог1б }); }): арр.изе("/арх , гооТег); // Слушайте этот порт арр.1хз1:еп(3000. Еипс1иоп() { сопзо!е. 1од( "Цуе аС Роге 3000 ); }); 4. Запустите сервер, введя следующую команду: побе зегуег.]з Если сервер запущен успешно, вы увидите что-то вроде этого: О ' рга1айврм1а<> -/г*асФ/гои(|пд-ехргеи рга1а<)®рга1а<1:-/геас1]1/гои11пд ехрге$$$ пойе ьегуег,)^ ы*е а! Рог1 зеве
5. Теперь откройте браузер или Розппап и сделайте запрос к Ипр:// ]оса11ло8Г:3000/ар1/. Вывод будет таким: I 1оса1Ьо51:3000/ар1/ > С О О 1оса1Коы 3000/ар!/ {"теззаде": "НеНо НогАсГ} Это все, мы познакомились с основами маршрутизации Ехргезз. Теперь давайте обработаем СЕТ, РО8Т и другие запросы. Измените ваш файл зегуег. ] з следующим образом: уаг ехргезз = гедо1ге( ехргезз'); уаг арр = ехргезз(); // Создание объекта РоиТег() уаг гоиСег = ехргезз.РоиТег(); // Промежуточное ПО маршрутизатора, упомянутое перед определением маршруюз. гои1ег.и5е(ГопсТ1ог1(гер, гез, пех!) { сопзо1е.1од(+ грд.тетНоб); пехр(); }); // Обеспечьте все маршруты здесь, это для главной страницы гооСег .де1(, ТипсСюп( гед. гез) { гез.]зоп({'теззаде : "Не11о Иог1б"}); }); арр.изе("/ар1 , гоЛег); эрр 1131:еп(3000, ЕипсТ1Оп() { сопзоТе 1од("Пуе а! РогЕ 3000'); });
Доступ к параметрам в маршрутизации Вы также можете получить доступ к параметрам из ИМ., например, Ьсгр // еуатр1е.сот/ар1/:пате/. Таким образом можно получить доступ к параметру паше. Добавьте следующий код в ваш файл зегуег ] з: гоиЕег ,уе1( ' /изег/.16", Типс1юп( гец, гез) { гез.]зоп( {' теззаде Не11о + геу.рагаггз.16}); }); Теперь перезапустите сервер и перейдите по [(гетр : /ЛосаИюзР :ЗО0О/ар1 / изег /Мет] [4], вывод будет таким: В 1оса1Ьо&сЗООО/а|. х С О © 1осаЖ<кС.ЗООО/ар</и5ег/Абет {«еззаде":“Не1То Аде»"}
Глава 74. Ыос1е.]*§ с КесГ|8 Замечания Рассмотрим основные и наиболее часто используемые операции в побе _ геб]з Вы можете использовать этот модуль, чтобы задействовать всю мощь Кесйз и соз- давать действительно сложные приложения на Хойе )8. С этой библиотекой ста- новятся доступными множество интересных вешей, таких как надежный слой кеширования, мощная система обмена сообщениями РиЬ/8иЬ и многое другое. Чтобы узнать больше о библиотеке, ознакомьтесь с документацией: йНрз^'/утмь пргщз.сот/раска^е/гесИз Примеры Начало работы побе_геб13, как вы могли догадаться, является клиентом Кесбз для Мойе.)з. Вы можете установить его через прт, используя следующую команду: прт 1п51а11 геЛз Как только вы установили модуль побейте Л з, вы готовы к работе. Давай- те создадим простой файл арр.]з и посмотрим, как подключиться к Кесйз из Хос1е.)8.
арр.]’8 уаг гесПз = гедитге( гесиз'); сИепС = гес!1з.сгеагеОИегИ:(); //создает нового клиента По умолчанию гебтз сгег1еС1тегт(:() будет использовать 127.0.0 1 и 6379 в качестве хоста и порта соответственно. Если у вас другой хост/порт, вы можете указать их следующим образом: уаг сИепХ = гейта.сгеа(:еС11еп1:(рогт, позТ); Теперь вы можете выполнить какое-то действие, после того как соединение будет установлено. В основном вам просто нужно прослушивать события под- ключения, как показано ниже. с1тепС.оп('соппесХ', ГипсСюпО { сопзо!е.1од(’соппесТеб') ; }); Итак, следующий фрагмент кода добавляется в арр. ] з: уаг гейта = гедотге( гейта’); уаг сИепТ = гесИз сгеаСеСИеггЦ); с1теп1.оп( соппесС’, Еипсстоп() { сопзо1е.1од('соппесЕей'); }); Теперь введите побе арр в терминале, чтобы запустить приложение. Перед вы полнением этого кода убедитесь, что ваш сервер Кесйз запущен. Сохранение пар «ключ-значение» Теперь, когда вы знаете, как подключиться к Кейта из Мойе.]8, давайте посмо- трим, как сохранять пары «ключ-значение» в хранилище Кейта. С охранение строк Все команды Кей18 представлены в виде различных функций на объекте с11еп1. Чтобы сохранить простую строку, используйте следующий синтаксис: с1тепС.ае1('Ггателогк ', 'АпдоТагОЗ ); пли сИегтС. зет( [ 'Егапел’огк', 'Апди1агй8’ ]); В приведенных выше примерах строка ‘Апди1агй8’ сохраняется с ключом Тгатеи'огк’. Обратите внимание, чт о оба примера делают одно и то же. Един- ственное различие в том, что первый передает переменное количество аргумен-
тов, в то время как второй передает массив агдз в функцию с11егй . зе1(). Вы также можете передать необязательный обратный вызов, чтобы получить уве- домление, когда операция будет завершена: сИеп!.. зег (' Ггателогк , 'Апди1агд8 , ЕипсПоп (е г г, гео1у) { сопзо1е.1од(гео1у); }); Если операция не удалась по какой-либо причине, аргумент егг в обратном вызове будет содержать ошибку. Чтобы получить значение ключа, выполните следующее: сИегЦ ,де1( ‘ Ггатемогк , Типс(:1оп(ег г, гер}у) { сопзо1е.1од(гер1у); }); Функция с11епт . дет() позволяет получить ключ, сохраненный в Кесйз. Зна- чение ключа можно получить через аргумент обратного вызова гер1у. Если ключ не существует, значение гер1у будет 1густым. Сохранение хешей Часто сохранение простых значений не решает вашу задачу. Вам может пона добиться сохранять хеши (объекты) в КесПз. Для этого вы можете использовать функцию НшзегО, как показано ниже: с11еп1.ЬтзеЦ ' Ггателогкз', ' ]ауазсг1р1:', Апди1аг38’, 'сзз', 'ВооТзбгар', ‘побе , ’Ехргезз'); с11еп1. НдеСа11( ’'Егатеиогкз ’, Еипс11оп(егг, оЬ]ес1) { сопзо1е.1од(оЬ)ес1:); }); Приведенный выше пример сохраняет хеш в Кесйз, который сопоставляет ка- ждую технологию с ее фреймворком. Первый аргумент для ЬпзеСО — это имя ключа. Последующие аргументы представляют пары «ключ-значение». Анало- гично пдегаНО используется для получения значения ключа. Если ключ най- ден, второй аргумент в обратном вызове будет содержать значение, которое яв- ляется объектом. Учтите, что КесПз не поддерживает вложенные объекты. Все значения свойств в объекте будут преобразованы в строки перед сохранением. Вы также можете использовать следующий синтаксис для сохранения объектов в Несйз: с11еггс. Ктзе1:( Чгателогкз , { '^азсгЕр):’ : ' Апди1аг381, ’сзз': ВооГзСгар , побе’: ' Ехргезз' });
Необязательный обратный вызов также может быть передан для получения уведомления, когда операция будет завершена Все функции (.команды] могут быть вызваны с использованием эквивалентов в верхнем'нижнем регистре. Например. сИеп!. КтзеХО и сХтепТ. НМ8ЕТ() — это одно и то же. Сохранение списков Если вы хотите сохранить список элементов, вы можете использовать списки НесПз. Чтобы сохранить список, используйте следующий синтаксис: сХтепС. гризЩ [' Ггатеиогкз', 'аэди1аг]з ', баскЬопе ], ^ипс1юп(егг, гер!у) { сопзоХе.Ход(герХу); // выводит 2 }); Приведенный выше пример создает список с именем Тгатеиогкз и добавля- ет в него два элемента. Таким образом, длина списка теперь равна двум. Как вы можете заметить, мы передали массив агдз в гризЬ. Первый элемент массива представляет имя ключа, а остальные представляют элементы списка. Вы также можете использовать ХризЬО вместо грыз НО, чтобы добавлять элементы слева. Чтобы получить элементы списка, вы можете использовать функцию ХгапдеО, как показано ниже: сХтепХ ,Хгапде('Гга'пеиогкз', 0, -1, ЕипсТюгЯегг, гер1у) { сопзоХе.Ход(герХу); // ['апдиХаг]з', баскЬопе ] }); Обратите внимание, что вы получаете все элементы списка, передавая -1 в ка- честве третьего аргумента в 1 гапде(). Если вам нужно подмножество списка, вы должны передать конечный индекс. Сохранение множеств Множества похожи на списки, но разница в том, что они не допускают дубли- катов. Таким образом, если вы не хотите иметь повторяющихся элементов в ва- шем списке, вы можете использовать множество. Вот как мы можем изменить наш предыдущий пример, чтобы использовать множество вместо списка: сХтепт. зассК [ садз', ' агдиХа ] з ', 'баскЬопе]8', етбег]з'], ЕипсХ10п(егг, герХу) { сопзоХе.1од(герХу); // выводит 3 });
Как видите, функция забсЦ) создает новое множество с указанными элемен- тами. Здесь длина множества равна трем. Чтобы получить элементы множества, используйте функцию зшетЬегзО, как показано ниже: с11епТ.зтетЬегз('тадз , Гипстюп(егг, гер!у) { сопзо1е.1од(гер!у); }); Этот фрагмент кода получит все элементы множества. Обратите внимание, чт о порядок не сохраняется при получении элементов Это был список наиболее важных структур данных, используемых в каждом приложении, работающем на Кесйз. Помимо строк, списков, множеств и хешей вы можете сохранять упорядоченные множества, Куре г ьодкодз и многое другое в Кейь. Если вы хотите получить полный список команд и структур данных, изу- чите официальную документацию по Кесйз. Помните, что почти каждая команда ВесНз доступна на объекте сИепЕ, предоставляемом модулем побс_геб1з. Некоторые дополнительные операции, поддерживаемые побе_гесй5 Проверка существования ключей Иногда может понадобиться проверка того, существует ли ключ, чтобы дей- ствовать соответственно. Для этого можно использовать функцию ехтзТзО, как показано ниже: сИегй .еххз(:8( 'кеу', ГипсТ1оп(егг, гер1у) { И (гер1у === 1) { сопзо1е.1од('ехтзтз1); } е!зе { сопзо1е.1сд( 'боезпХ'! ехтз!:'); } }); Удаление и установка времени жизни ключей Иногда вам нужно очистить некоторые ключи и инициализировать их зано- во. Чтобы удалить ключи, вы можете использовать команду Ие1, как показано ниже: с] теп! . бе1( ‘'Ггате^огкз , ^ипсИопСегг, гер1у) { сопзо1е.1од(гер1у); }); Вы также можете задать время истечения срока действия для существующего ключа следующим образом: сИепТ. зеТ:(' кеу1 ', уа!1');
с11еп1:.ехр1ге('кеу1 ', 30); Приведенный выше ггример устанавливает время истечения срока действия 30 секунд для ключа кеу1. Увеличение и уменьшение значений Кесйз т акже поддерживает увеличение и уменьшение значений ключей. Что- бы увеличить значение ключа, используйте функцию тпс г (), как показано ниже: с1теп1 .зет( 'кеуГ , 10. Гипс1юп() { с11еп1.1псг(' кеуГ , Гипс1юп(егг, гер1у) { сопзо1е.1од(гер1у); // выводит 11 }); }); Функция юс г() увеличивает значение ключа на 1. Если вам нужно увеличить его на другое количество, вы можете использовать функцию 1псгоу(). Анало- гично, для уменьшения значения ключа можно использовать функции бесг() и оесгоу().
Глава 75. Ыос1е Раскаде Мападег (прт) Введение Ыос1е Раскате Мапа§ег (прт) предоставляет две основные фупкпии: • Онлайн-репозитории для пакетов/модулей Ыойедз, которые можно найти на сайте 8еагсйлюйе]8.ог^. • Утилита командной строки для установки пакетов Мобедз, управления версиями и зависимостями пакетов Мос1е.]'8. Синтаксис прт <соттапс!>> где <соттап(1> — одна из следующих команд: • ас!с1-изег • бергесаТе • 1пз1а11 • асШизег • досз • 1пТо • ар1Ье1р • есНТ • хпИ • аоХМог • ехр1оге • 1зп(а11 • Ып • Тад • тззиез • Ьодз • Т1пО • 1а • с • ТТпа-^иоез • Ипк • сасЬе • дет • 113Т • сотр1е1юп • )те!р • 11 • сопНд • ЬеЗ-р-зеагсТ1 • 1п • с!с1р • Иоте • 1од1п • декоре • 1 • 1з
• оисааТес! • гип-зспрр • ТЗГ • о«/пег • 3 • ип • раск • зе • ип1пз1а11 • ргеТ1х • зеагсЬ • ип1хпк • ргипе • зе! • иприЬИзЬ • риЫ1зН • зИол • ипзгаг • г • з11Г1пктугар • ир • гЬ • згаг • ирбаге • геЬиПс! • зГагз • V • гетоуе • з1аг! • уегзюп • геро • зРор • 71ем/ • гез^аг'С • зиР1Тос!и1е • «Ьоат1 • гт • 1ад • гооТ • 1езг Параметра 1 Параметр Пример ассезз прт риЬПзЬ -ассезз-риЬНс Ып прт Ып -я ес!11 прт е 611 еоппес! Ие1р прт Не1р тП Ш11 прт тИ шзгаИ прт 1П8Ы11 1шк прт 1тк ргипе прт ргипе риЬНзЬ прт риЫ1зН./ гезЫП прт гезГаП 8(аг( прт зИагГ $гор прт 8(агТ ирйа1е прт ирбаге уегаоп прт уегзхоп
Примеры Установка пакетов Введение Пакет — 310 термин, используемый в прт для обозначения инструментов, ко- торые разработчики могут задействовать в своих проектах. Это включает в себя все, начиная от библиотек и фреймворков, таких как )(^пегу и Ап^и1аг|8, и закан- чивая такими инструментами как Си1р. ]з Пакеты размещаются в папке, кото- рая обычно называется пос1е_тоби1ез и содержит файл раскаде. д зоп. Этот файл содержит информацию обо всех пакетах, вкпочая любые зависимости, которые являются дополнительными модулями, необходимыми для использования кон- кретного пакета. Ырт использует командную строку как дтя установки, так и для управления пакетами, поэтому пользователи, желающие освоить его, должны быть знакомы с основными командами своей операционной системы, например, с переходом по директориям, а также с возможностью видеть содержимое директорий. Установка ЮМ Обратите внимание, что дтя установки пакетов необходимо, чтобы ХРМ был установлен. Рекомендуемый способ установки ХРМ — использование одного из устано вочных пакетов со страницы за1рузки Хобедз: ИНр8://пос1е)8.ог§/еп,'с1оугп1оас1/ раска^е-тапаяег. Вы можете проверить, установлена ли у вас уже Гмос1е.]8, выполнив команду прт -V или прт ^егзюп. После установки ХРМ через установочный пакет Хобедз обязательно проверь- те наличие обновлений. Это связано с тем, что ХРМ обновляется чаще, чем уста- новочный пакет Хобе.)8. Чтобы проверит], наличие обновлений, выполните сле- дующую команду: прт 1пз1а11 прт@1а1:езТ -д
Как установить пакеты Чтобы установить один или несколько пакетов, используйте следующую команду: прт тпзТаИ <раскаде-пате> или прт 1 <раскаде-пате> . . . например, чтобы установить 1ос1азб и ехргезз прт 1пзТа11 1обазЬ ехргезз Примечание: эта команда установит пакет в каталоге, в котором в данный момент находится командная строка, поэтому важно убедиться, что выбран правильный каталог. Если в вашем текущем рабочем каталоге уже есть файл раскаде. ] зоп и в нем определены зависимости, то прт тпзГаИ автоматически разрешит и установит все зависимости, перечисленные в файле. Вы также можете использовать сокра- щенную версию команды прт хпзТа! 1, которая выглядит так: прт ь Если вы хотите установить конкретную версию пакета, используйте: прт 1пз1а11 <пате>@<уегз1оп> Например, чтобы установить версию 4.11.1 пакета 1 ос!азИ: прт гпзГаИ 1ос1аз118“4.11 .1 Если вы хотите установить версию, которая соответствует определенному ди- апазону версий, используйте: прт хпзгаП <пате>@><уегз1оп гапде> Например, чтобы установить версию, которая соответствует «уегзюп >= 4.10.1» и «уетоп < 4.11.1» пакета 1обазб: прт 1пз1а11 1обазб@ '>=4.10.1 <4.11.1" Если вы хотите установить последнюю версию, используйте: прт 1пз1а11 <пате>|@1а1езТ Команды выше будут искать пакеты в централь- ном репозитории прт на сайте ]эйр8:/Ммллг.прт]8. сот/. Если вы не хотите устанавливать из реестра прт, поддерживаются и другие варианты, такие как:
# пакеты, распространяемые в виде сагЬаИ прт юзТаИ <СагЬа11 Т11е> прт 1пз1:а11 <сагЬа]1 иг1> # пакеты, доступные локально прт 1пз1а11 <1оса1 раТп> # пакеты, доступные как дп-репозиторий прт тпзГаИ <д!1 гетоТе и-1> # пакеты, доступные на СИНиЬ прт зпз1а11 <изегпате>/<герсз11огу> # пакеты, доступные в виде дхз! (требуется раскаде.дзоп) прт 1пз1а11 д!з1:<д1з1-1д> # пакеты из конкретного репозитория прт 1пз1а11 --гедхзХгу=пггр://тугед.тусотрапу сот «раскаде пате> # пакеты из определенной группы пакетов # см. прт зсоре прт тлз^аИ @«зсоре>/<пате>(Э<легз1оп>) # Скоупинг полезен для отделения приватных пакетов размещенных в при- ватном ^/реестре, от публичных, устанавливая реестр для определенной области видимости: прт сопТтд зеТ ©тусотрапу:гедтзТгу ПСТр://тугед.тусотрапу.сот прт 1пзСа11 @тусотрапу/<раскаде пате> Обычно модули устанавливаются локально в папке поде_тоди1ез, которую можно найти в вашем текущем рабочем каталоге. Это тот каталог, который бу- дет использовать геди! ге() для загрузки модулей, чтобы сделать их доступными для вас. Если вы уже создали файл раскаде.]зоп, вы можете использовать опцию -зауе (сокращение з) или один из ее вариантов, чтобы автоматически доба- вить установленный пакет в ваш раскаде.]зоп как зависимость. Если кто-то еще установит ваш пакет, при автоматически прочитает зависимости из файла раскаде.]зоп и установит указанные версии. Обратите внимание, что вы все еще можете добавлять и управлять своими зависимостями, редактируя файл позже, поэтому обычно полезно отслеживать зависимости, например, так: прт ЕпзТаП --зауе <пате> # Установить зависимости
или при 1пз1а11 -з <пате> # сокращенная версия -зауе или прш 1 -8 <пате> Чтобы установить пакеты и сохранить их только в том случае, если они нужны для разработки, а не для работы приложения, выполните следую- щую команду: прш ъпзТаП --зауе-беу <паше> # Установить зависимости для разработки или прш 1пз1а11 -0 <пате> # сокращенная версия --зауе-беу или прт 1 -б <пате> Установка зависимостей Некоторые модули не только предоставляют библиотеку для использования, но и содержат один или несколько бинарных файлов, которые предназначены для использования через командтгую строку Хотя вы все еще можете установить эти пакеты локально, часто предпочтительнее устанавливать их глобально, что- бы можно было использовать инструменты командной строки. В этом случае прт автоматически свяжет бинарные файлы с соответствующими путями (на- пример, /озг/1оса1/Ып/<пате>), чтобы их можно было запускать из команд- ной строки. Чтобы установить пакет глобально, используйте: прт тпз'ЕаП --д1оЬа1 <пате> или прт хпзТаП д <пате> или прт 1 -д <пате> Например, чтобы установить инструмент командной строки д гипт: прт 1пз1а11 -д дгипГ-сИ Если вы хотите увидеть список всех установленных пакетов и их соответству- ющих версий в текущем рабочем пространстве, используйте:
прт 3151 прт 1181 <пате> Добавление необязательного аргумента имени может проверить версию кон- кретного пакета. Примечание: если у вас возникают проблемы с разрешениями при попыт- ке установить модуль прт глобально, не поддавайтесь искушению использо- вать зибо прт 1пз1:а11 - д .... чтобы обойти проблему. Предоставление сторонним скриптам возможности выполняться в вашей системе с повышенными привиле- гиями опасно. Проблема с разрешениями может означать, что у вас есть пробле- мы с тем. как сам прт был установлен. Если вас интересует установка Мобе в «пе- сочнице пользователя», вы можете попробовать использовать путл. Если у вас есть инструменты сборки или другие зависимости, предназна- ченные только для разработки (например, Спт{), вы, возможно, не захотите включать их в приложение, которое вы развертываете. В этом случае вы захо- тите иметь их в качестве зависимости, предназначенной только для разработ- ки, которая указана в раскаде.]зоп под беуСерепоепсЗез. Чтобы установить пакет как зависимость, предназначенную только для разработки, используйте -зауе-беу (или - б). прт ьпзтаП --зауе-беу <пате> // Установить зависимости для разработ- ки, коюрые не включаются в ргобосИоп или прт ЗпзСаИ -0 <папе> Вы увидите, что пакет добавлен в беуСерепйепсЗез вашего раскаде. ] зоп. Чт обы установить зависимости загруженного/клонированного проекта Мобе. ]8, вы можете использовать: прт Зпз1а11 или прт 1 прт автоматически прочитает зависимости из раскаде. ] зоп и установит их. ЮМ за прокси-сервером Если ваш доступ в интернет осуществляется через прокси-сервер, возможно, вам потребуется изменить команды прт ЗпзСаП, которые обращаются к удален- ным репозиториям, прт использует файл конфигурации, который можно обно- вить через командную строку: прт сопТтд зеС
Вы можете найти настройки прокси-сервера в панели настроек вашего брау- зера. Как только вы получите настройки прокси (ШЬ сервера, порт, имя пользо- вателя и пароль), вам нужно настроить конфигурации прш следующим образом. $ прш сопТьд зеС ргоху ЬИр://<изегпате> :<разз»огс!>©<ргоху зегуег- иг1> :<рог1:> $ прт сопТгд зе! Ылрз-ргоху Ккр://<изегпате> :<разз«огб^©<ргоху- зегуег-ог1>:<рэгг> Поля озегпате, разз/югб, рог! являются необязательными Послетого каквы установили эти параметры, команды прт 1л8Ха11, прт 1 -ди другие будут ра богагь корректно. Скоупы и репозитории # Установить репозиторий для скоупа "тузсоре" прт сопГтд зеГ ©тузсоре:гедьзсгу 1гЩр://гед1зсгу.согрсгагюп.сот # Войти в репозиторий и ассоциировать его со скоупом 'тузсоре" прт аббизег --гедтзтгу=НГ1р://гертз1:гу.согрогаРтоп сот --зсоре=© тузсоре # Установить пакет ту11Ь из скоупа "тузсоре прт ХпзДаИ ©тузсоре/туИЬ Если имя вашего пакета начинается с ©тузсоре и скоуп тузсоре ассоцииро- ван с другим репозиторием, прт риЫ1з1г загрузит ваш пакет в этот репозиторий. Вы также можете сохранить эти настройки в файле .пртгс: ©тузсоре: гедтзСгу^ггр: //гедэзГгу. согрогаГюп .сот //гедлзРгу . согрога^юп .сот/ :_ааЫтТокеп=хххххххх-хххх-хххх- ххххххххххххххх Это полезно, к примеру, при автоматизации сборки на С1-сервере. Удаление пакетов Чтобы удалить один или несколько локально установленных пакетов, ис- пользуйте: прт ипгпзТаИ <раскэде пате> Команда иптпзТаП в Ь’РМ имеет пять алиасов, которые также можно ис- пользовать:
прт гетоуе «раскаде пате> прт гт «раскаде пате* прт г «раскаде пате* прт ип11пк «раскаде пате> прт ип «оаскаде пате* Если вы хотите удалить пакет из файла раскаде. ] зоп в рамках удаления, ис- пользуйте флаг-зауе (сокращение: -8): прт ип1пзСа1] --зауе «раскаде пате> прт ип1пз1а11 -8 «раскаде пате* Для зависимостей разработки используйте флаг -зауе беу (сокращение: - 0): прт итпзсаП --зауе-аеу «раскаде пате? прт игипзТаИ -0 «раскаде пате> Для необязательных зависимостей используйте флаг --зауеорНопа! (сокра- щение: -0): прт ип1пз1а11 --зауе-орИопа! «раскаде пате> прт иптзСаП -0 «раскаде пате* Для пакетов, установленных глобально, используйте флаг -д1оба] (сокраще- ние: -д) прт опдпзГаП -д «раскаде пате* Основы семантического версионирования Прежде чем публиковать пакет, необходимо его версионировать. прт поддер- живает семантическое версионирование, что означает наличие патчей, минор ных и мажорных релизов Например, если версия вашего пакета 1.2.3, чтобы изменить версию, необ- ходимо; 1. раЮй ге1еазе. прт уегзюп раТсб -> 1 2.4 2. ттог ге1еазе: прт уегзюп т1пог=>1.3 0 3. тащг ге!еазе: прт уегзтоп та)ог => 2.0.0 Вы также можете указать версию напрямую: прт уегзтоп 3.1.4 => 3.1.4 Когда вы устанавливаете версию пакета с помощью одной из команд прт, ука- занных выше, прт изменяет поле версии в файле раскаде ]зэп, выполняет ком-
мит, а также создает новый тег Он с версией с предшествующей «V», как если бы вы выполнили команду7: д11 1ад V3.1 4 В отличие от других менеджеров пакетов, таких как Вомгег. регистр прт не требует создания тегов Ой для каждой версии. Но если вам нравится исполь- зовать теги, вы должны помнить о необходимости отправки нового тега после увеличения версии пакета: дт.1 ризб огхдтп ггазтег (для отправки изменений в раскаде.]зоп) дИ ризб ог1дхп у3.1 4 (для отправки нового тега) Или вы можете сделать это сразу с помощью команды: д11 ризб огЕдтп шазтег -Гадя Настройка конфигурации пакетов Конфигурации пакетов Иобедз содержатся в файле раскаде.]зоп, который можно найти в корневом каталоге каждого проекта, Вы можете создать новый файл конфигурации, вызвав пргп гп11: Он попытается прочитать текущий рабочий каталог для информации о репо- зитории СгГ (если огг существует) и переменных окружения, чтобы попытаться автоматически заполнить некоторые значения-заглушки. В противном случае он предоставит диалог ввода для основных параметров. Если вы хотите создать раскаде. ]зоп с настройками по умолчанию, исполь- зуйте: прт 1П11 --уез # или прт 1П11 -у Если вы создаете раскаде.)зоп для проекта, который вы не собираетесь пу- бликовать как пакет МРМ (например, только для управления вашими зависимо- стями), вы можете указать это намерение в файле раскаде. ] зоп: 1. ДополнительноустановитесвойстворгтуаТевТгие.чтобыпредотвратить случайную публикацию. 2. Опционально установите свойство 11сепзе в «ЕКЫСЕЫЗЕВ», чтобы запретить другим использовать ваш пакет.
Чтобы установить пакет и автоматически сохранить его в раскаде. ]зоп, ис- пользуйте: прт 1пз1а11 --зауе <раскаде> Пакет и связанная с ним метаинформация (например, версия пакета) появят- ся в ваших зависимостях. Если вы сохраните его как зависимость для разработки (используя --зауе-деу), пакет вместо этого появится в ваших деуберепдепстез. При использовании такого минимального файла раскаде.]зоп вы можете столкнуться с предупреждениями при установке или обновлении пакетов, со- общающими, что у вас отсутствуют описание и поле репозитория. Хотя эти со- общения можно игнорировать, вы можете избавиться от них, открыв раскаде. ] зоп в любом текстовом редакторе и добавив следующие строки в объект ]8ОЫ: дезсгтрсюп": Мо дезсгюСтоп . "герозтАогу : { ргтуабе": Тгое Публикация пакета Сначала убедитесь, что вы настроили свой пакет. Затем вам нужно войти в си- стему прт]з. Если у вас уже есть пользователь МРМ: прш 1од1п Если у вас нет пользователя: прт аддизег Чтобы проверить, чго ваш пользователь зарегистрирован в текущем кли- енте: прт сопТАд 1з После этого, когда ваш пакет будет готов к публикации, используйте: прт риЫАзб И все готово. Если вам нужно опубликовать новую версию, убедитесь, что вы обновили версию вашего пакета. В противном случае МРМ не позволит вам опубликовать пакет.
{ паше : раскаде-пате , "уег51оп : "1,0.4" } Запуск скриптов Вы можете определить скрипты в вашем раскаде. ] зоп, например: { "паше": 'уоиг-раскаде "уегзХоп : "1.0.0", "безсгдртюп : ' , "тагп : "дпбех.]з", "аиТПог : “Исепзе : "18С", "берепбепстез': {}, ' беуберепбепсхез : {}, "зсгбрТз : { "есНо : есЬо Ье11о!" } } Чтобы запустить скрипт есбо, выполните команду при гип есбо из команд- ной строки. Произвольные скрипты, такие как есбо выше, должны запускать- ся с помощью команды прт гип <зсг!р1 пате>. прт также имеет ряд официаль- ных скриптов, которые он запускает на определенных этапах жизненного цикла пакета (например, ргетпзтаП). Полный обзор того, как МРМ обрабатывает поля скриптов, можно найти в документации: 0Шр8://'(]осз.пр1П]8.сот'с11/у10/и8ш§-прт/ 8СПрТ8). Скрипты ПРМ чаще всего используются для таких задач, как запуск сервера, сборка проекта и запуск тестов. Вот более реалистичный пример:
зспртз’: { "Тез!": тосба СезТз", "згаг! : рт2 зтагт 1пдех.]з“ } В записях скриптов командные про1раммы, такие как тосНа, будут работать при установке как глобально, так и локально. Если запись командной строки не существует в системном РАТН, прт также проверит ваши локально установ- ленные пакеты. Если ваши скрипты становятся стишком длинными, их можно разделить на части, например: зсгтртз : { "уегу-сотр1ех-сэттапд’’ : прт гоп сЕатп-1 && прт гоп сЬаш-2 , "сЬа1п-1": лебраск", 'сЬа1п-2": поде арр.]з } Удаление лишних пакетов Чтобы удалить лишние пакеты (пакеты, которые установлены, но не указа- ны в списке зависимостей), выполните следующую команду: прт ргипе Чтобы удалить все пакеты разработки, добавьте флаг -ргодосТтоп: прт ргипе -ргодисГюп Список установленных пакетов Чтобы сгенерировать список (в виде дерева) текущих установленных паке- тов, используйте: прт 1131 Команды 18, 1а и 11 являются синотгимами команды ИзТ Команды 1а и 11 отображают дополнительную информацию, такую как описание и репозиторий. Опции Формат ответа может быть изменен с помощью передачи опций. Прт 1151 -]5ОП • ] зоп — показывает информацию в формате
• 1опд — показывает расширенную информацию • ра гзеаЫе — показывает парсируемый список вместо дерева • д 1 оЬа 1 — показывает глобально установленные пакеты • берПт — максимальная глубина отображения дерева зависимостей • беу/беуе1ортеп1: — показывает бегПерепбепсзез • ргоб/ргобостюп — показывает берепбепсзез При желании вы также можете перейти на домашнюю страницу пакета: прт (юте «раскаде пате> Обновление прт и пакетов Так как ПРМ сам по себе является модулем Мобедз, его можно обновить с по- мощью него самого. Если операционная система — ХМшйоууз, командная строка должна быть запу щена от имени администратора: прт тпзГаИ -д потщПа'СезТ Если вы хотите проверить наличие обновленных версий, вы можете выпол нить: прт оиСбаРеб Для обновления конкретного пакета: прт ирбаТе <раскаде пате> Это обновит пакет до последней версии в соответствии с ограничениями в раскаде.]зоп. Если вы также хотите зафиксировать обновленную версию в раскаде. ] зоп: прт ирбаГе «раскаде оате> --зауе Закрепление модулей на конкретных версиях По умолчанию прт устанавливает последнюю доступную версию модулей в соответствии с семантическим версионированием зависимостей. Это может стать проблемой, если авт ор модуля не придерживается правил семантического версионирования и, например, вводит разрушающие изменения в обновлении модуля.
Чтобы закрепить версию каждой зависимости (и версию их зависимостей и т. д.) за конкретной версией, установленной локально в папке побе_тодь1ез, используйте: прт зИгзпкйгар Это создаст файл прт-збг1пки1гар. ]зоп рядом с вашим раскаде. ]зоп, в кото- ром будут перечислены конкретные версии зависимостей. Настройка для глобально установленных пакетов Вы можете использовать орт 1пзга11 -д, чтобы установить пакет глобально. Обычно это делается для установки исполняемого файла, который вы можете до- бавить в свой путь для запуска. Например: прт тоз1а11 -д ди1р сП Если вы обновите свой путь, вы сможете вызывать ди1р напрямую. На многих операционных системах при 1пзга11 -д попытается записать в каталог, в который ваш пользователь, возможно, не сможет записать, на- пример, /изг/Ып. В этом случае не следует использовать зибо прт хпзИаП, так как существует потенциальный риск для безопасности при запуске произволь- ных скриптов с зибо, а пользователь гооТ может создавать каталоги в вашем домашнем каталоге, в которые вы не сможете записывать, что усложнит буду- щие установки. Вы можете указать МРМ, куда устанавливать глобальные модули, через файл конфигурации ~/ пртгс. Это называется префиксом, который можно просмотреть с помощью прт рге^хх: ргеТ1х=~/.прт-д1оба1-тоби1ез Этот префикс будет использоваться всякий раз, когда вы запускаете прт 1пз1а11 -д. Вы также можете использовать прт 1пз1а11 --рге'Стх ~/.прт- д 1оЬа 1 -тоби1ез, чтобы установить префикс при установке. Если префикс совпа- дает с вашим конфигурационным файлом, вам не нужно использовать -д. Чтобы глобально установленный модуль мог быгь задействован, он должен находиться в вашем пути: ехрсг! РАТН-$РАТН:~/.прт-д1сЬа1-то0и1ез/Ь1П Теперь, когда вы запустите прт 1пзГа11 д ди!р-сП, вы сможете использо- вать ди 1р.
Примечание: когда вы выполняете прт 1пз(:а11 (без -д), префикс будет ка- талогом с раскаде. ] зоп или текущим каталогом, если он не найден в иерархии. Это также создаст каталог побе_тоби!ез/.Ьтп, в котором будут находиться ис- полняемые фай .ты. Если вы хотите использовать исполняемый файл, специфич- ный для проекта, нет необходимости использовать прт 1пз(:а11 д. Вы можете использовать тот, что находится в побе_тоби1ез/ . Ып. Связывание проектов для более быстрой отладки и разработки Сборка зависимостей проекта иногда может быть утомительным заня- тием. Вместо публикации версии пакета в ХРМ и установки зависимости для тестирования изменений используйте прт Ипк. Он создает симво- лическую ссылку, чтобы последний код можно было протестировать в ло- кальной среде. Это облегчает тестирование глобальных инструментов и за- висимостей проекта, позволяя запускать последний код перед созданием опубликованной версии. Код помощи МАМЕ прт Ипк - 8ут11пк а раскаде Го1бег 8УЙОР818 прт Ипк (1п раскаде сПг) прт Ипк [ / ] [@] аИаз: прт 1п Шаги для связывания зависимостей проекта При создании ссылки на зависимость обратите внимание на то, что будет ссы- латься на имя пакета в родительском проекте. 1. Перейдите в каталог зависимости (например, сб . /ту - бер). 2. Выполните прт Ипк. 3. Перейдите в проект, который будет использовать зависимость. 4. Выполните прт Ипк ту-бер или. если используется пространство имен, прт Ипк ©патезрасе/ту-оер.
Шаги для связывания глобального инструмента 1. Перейдите в каталог проекта (например, сб езИпТ-лаГсб). 2. Выполните прт 11пк 3. Используйте инсзрумент. 4. Выполните езл --доте!:. Проблемы, которые могут возникнуть Связывание проектов иногда может вызвать проблемы, если зависимость или глобальный инструмент уже установлены Использование прт ипюзТаИ (-д) <ркд> с последующим выполнением прт 1шк обычно решает любые воз- никающие проблемы.
Глава 76. Мойе \/ег5юп Мападег (пут) Примечания Чтобы установить пут с использованием последней версии, перейдите по ука- занной ссылке на СйНпЬ (ЬПр8://ргИиЬ.сот/пут-51т/пУ1п), где будут предоставле- ны актуальные пг1. Примеры Установка ЫУМ Вы можете использовать сиг1: сиг! -о- Икрз: / /гаи.д! ТЬиЬизегсопЕепТ.сот/сгеаТ1оп1х/пут/у0.31 .3/ 1П5Та11.81з | ЬазН или идеЕ: «дет -дО- 1т(1:р5://ган.д11ЬиЬи5егсоп1еп'С.сот/сгеа11оп1х/пут/у0.31.3/ тпзТаН.зН | Ьазп Проверка версии МУМ Чтобы проверить, что пут был установлен, выполните: соттапб -у пут Если установка прошла успешно, должно выводиться ‘пут’.
Установка конкретной версии Моде Список доступных удаленных версий для установки пут 1з-гето(:е Установка удаленной версии пут зпз'ГаП <уегзюп> Например: пут тпзСаП й.10.13 Использование уже установленной версии поде Чтобы просмотреть доступные локальные версии поде через ЫУМ: пут 1$ Например, если пут 1з возвращает: $ пут 1з У4.3.0 У5.5.0 ...вы можете переключиться на версию У5.5.0 с помощью: пут изе У5.5.0 Установка пут на Мас 08Х Процесс установки Вы можете установить Ходе Уегзюп Мападег, используя дзЛ, сиг1 или «де!. Запустите эти команды в терминале на Мас О8Х. Пример с сиг1: сиг1 -о- Ы:Срз://гал.д1гбиЬизегсоп1епт.сот/сгеа11оп1х/пут/у0.31.3/ ЕпзгаИ зб | Ьазб Пример с ту^ес: идет -дО- К1Л:рз://гал.д1ГПиЬизегсоп1:еп1:.сот/сгеа1:1ОП1х/пут7уЭ.31 .3/ 1пзта11 зб | ЬазК Проверка корректности установки АПТИ Чтобы проверить правильность установки пут. закройте и снова откройте терминал и введите пут. Если появляется сообщение пут: соттапо поб Гоипд,
возможно, ваша ОС не имеет необходимого файла базб.рго'ГИе. Введите в терминале СоисЬ ~/.Ьазб. ргоТ11е и запустите вышеуказанный скрипт уста- новки снова. Если вы все еще получаете сообщение пут: соттапб по! Еоопб, попробуйте следующее: • Введите в терминал папо . оазбгс. Вы должны увидеть ехрогС-скрипт, почти идентичный следующему: ехрогС МУМ 0]К="/И&егз/]оИпбое/.пуш'’ [ -з "$МУМ_01Р/пут.зИ" ] && . “$МУМ_В1К/пут.зЬ“ • Скопируйте ехрогГ-скрипт и удалите его из Ьазбгс. • Сохраните и закройте файл .ЬазИгс (СТВЕ+О Еп1ег — СТКЬ’Х). • Затем введите папо ,Ьазб_ргоЕ11е, чтобы открыть ВазН РгоШе. • Вставьте скопированный ехрогТ-скршгт в ВазЬ РгоШе на новой строке. • Сохраните и закройте Вазй РгоШе (СТКЕ+О — ЕШег — СТКЕ+Х). • Наконец, введите папо Ьазбгс, чтобы снова открыть файл .Ьазбгс. • Вставьте следующую строку в файл: зоогсе ~/.пут/пут . зб • Сохраните и закройте (СТКЕ+О — Ешег — СТКЬ+Х). • Перезапустите терминал и введите пут, чтобы проверить, работает ли он. Установка псевдонима для версии поде Если вы хотите задать псевдоним (айаз) для установленной версии побе, выполните; пут аИаз <пате> <уегзюп> Для удаления псевдонима используйте: пут ипаЕтаз <пате> Подходящий пример использования — если вы хотите задать какую-то версию, отличную от стабильной версии, как версию по умолчанию. Вер- сии, для которых заданы псевдонимы по умолчанию, загружаются в консоли по умолчанию. Пример: пут аИаз ЗеСаоИ 5.0.1
Тогда каждый раз при запуске консоли/терминала будет присутствовать вер- сия 5.0.1 по умолчанию. Примечание: пут аТтаз # ИзЛз а!1 аИазез сгеаСеб оп пут Запуск любой произволоной команды в подсистеме с нужной версией Моде Список всех установленных версий Хойе: пут 1з У4.5.0 уб.7.0 Запуск команды с использованием любой установленной версии Мобе: пущ гип 4.5.0 --уегзТоп ог пут ехес 4.5.0 побе --уегзтоп Рипплпд побе у4.5.0 (прт У2.15.9) у4.5 0 пут гип 6.7.0 --уегзюп ог пут ехес 6.7.0 побе --уегзьоп Рипптд побе у6.7 0 (прт уЗ 10.3) уб.7.0 Использование псевдонима пут гип бе!аи1(: --уегзгоп ог пут ехес беГаиИ побе --уегзТоп Риппгпд побе у6.7 0 (прт у3.10.3) Уб.7.0 Установка версии Мойе ЬТ8 пуш лпзбаП -Из Переключение версий пут изе У4.5.0 ог пуш изе зТаЫе ( а11аз )
Глава 77. ОАШЬ 2.0 Примеры ОАиТЬ 2 с реализацией ЯесИз — дгапЦуре: раззшогс! В этом примере мы будем использовать ОАшй 2 в КГ.8Т АРТ с базой данных КесИь Важно: вам нужно будет установить базу данных КесН.з на вашем компьютере. Загрузите ее отсюда для пользователей 1лпих: Ьйрз://гес118.1о/бои/п1оас15/. ...или отсюда для установки версии на Шшскиуз: Ыф8т7§1(2шЬ.сот/8ептсе81аск/ гесПз-мапботсз.
Также мы будем использовать настольное приложение КеШз Мапа^ег. устано- вите его отсюда: Ьйр8://тес118.ю/т8ц;Н/. Теперь нам нужно настроить наш сервер Ыос)е.)8 для использования базы дан- ных КеО18. • Создание серверного файла: арр . ] з уаг ехргезз = геди1ге('ехргезз’), ЬобуРагзег = геро1ге(‘Ьобу-рагзег'), оаиСЬзегуег = геди1ге('оаиСЬ2-зегуег’); // Лои1с1 Ье: 'оаи1Ь2- зегуег’ уаг арр = ехргезз(); арр.изе(ЬобуРагзег иг1епсобеб({ ехСепбеб: Ггие })), арр.изе(ЬобуРагзег.]зоп()); арр оаиГб = оаиС:Ьзегуег({ гпос1е1; геди!ге(' ./гоиГез/0аи1Г|2/тос1е1'), дгапсз: [ раззиого’, 'геТгезб_токеп' ], беЬид: Сгие }); // Обработка запросов на выдачу токеное арр а!1('/оаиСЬ/Сокеп’, арр.оаиЫз .дгагтЦ)); арр.деС('/зесгеС', арр.оаиСЬ аиСпопзеО, ГипсСюп (гед, гез) { // Требуется действительный ассезз_Сокеп гез.зепб('ЗесгеС агеа ); }); арр.деС(' /риЬИс', ТипсЫоп (гед, гез) { // Не требует ассезз_1:океп гез.зепс!('РиЬИс агеа ); });
// Обработка онибок арр,изе(арр.сэиЬК.еггогНапР1ег()); арр.ПзТеп(3004): • Создание модели 0АШЬ2 в гоитез/0аиТИ2/тоЬе1.]з уаг тос1е1 - тобиТе.ехрогХз, иШ = геди!ге('иДП'), гесНз = геди1ге('гесНз’); уаг с!Ь = геЬтз.сгеатеСИепН); уаг кеуз = { Юкеп: '1окепз‘%з', сИепТ: ' с11епТз :%з', геГгезЫокеп: ‘ геСгезЬ.Токепз :%з’, дгапЬГурез: ’ сПепТз :%з :дгапг_Турез', изег: изегзЛз' }; июЬе1.деТАссеззГокеп = ТипсСюп (ЬеагегТокеп, саПЬаск) { с1Ь Иде1:а11(иг11.Тогп1аГ(кеуз.1океп, ЬеагегТокеп), ГипсЫоп (егг, Сокеп) { И (егг) геТигп са1]Ьаск(егг); 1Т (!Токеп) геТигп са11Ьаск(); саПЬаск(пи11, { ассеззТокеп: токеп.ассеззТокеп, сИепЫС: Токеп.с11епТ1с1, ехрггез- Токеп.ехоггез ? пей/ 0аге(1:окег. ехрхгез) : пиП, изегТб Токеп ,изег1с1 }); }); }; 1Лсс1е1.деТС11епг = ТипсТюп (сПепЫс! сПепгЗесгеТ, саПЬаск) { с1Ь,Ьде1аП(и1:П.Тогп1а1:(кеу8.с11еп'1:, сИепЫс!). ГипсПоп (егг, сИепТ) { 1Т (егг) геТигп саПЬаск(егг); 1Г (1с11еп1: || сНепТ.сИепТЗесгеТ !== сИепТЗесгеТ) геТигп саПЬаск(); са11Ьаск(пи11. { сИепЫЬ: с!1еп1 .сПепПа. сПептЗесгет: сПепт.с11епх5есгег }); }); };
тос!е1.десРеГгезЫокеп - Типстюп (ЬеагегТскеп, саПЬаск) { с1ь. Ьде1:а11( и!:11. ТогтаГ (кеуе. геГгезИТскеп, реагегТокеп), Гипспэп (егг, гокеп) { П (егг) гесигп са11Ьаск(егг); И (Иокеп) геТигп са11Ьаск(); са11оаск(пи11, { геГгезпТскеп: Сскеп ассеззТокеп, сИепЫск гокеп.с11епЫс), ехрхгез: Токеп.ехрХгез ? пен ОаТе(1океп.ехр1гез) : пи11, изегТЬ: 1океп.изегТб }); }); }; тоЬе1. дгапТТуреАПолео = ТипсГюп (с11еп11д, дгапГТуре, саПЬаск) { с1Ь.з15П1е1пЬег(и1П.+огп1а1(кеу5.дгапЫурез, сИепПЬ), дгапНуре, саПЬаск); }; 1ЛоЬе1.зауеАссеззТокеп = ГипсТюп (ассеззТокеп, с11епТ1с1, ехрагез, изег, саПЬаск) { ЬЬ. Нтзе1(и1П.Тогта1(кеуз.Гокеп, ассеззТокеп), { ассеззТокеп: ассеззТокеп, сИепПЬ: сИепТЮ, ехртгез: ехрагез ? ехрХгез.ГоТЗОЗТтпдО : пиП, изегХЬ изег.1Ь }, саПЬаск); }; тоЬе1. захеРеГгезИТокеп = ГипсСюп (геГгезЬТокеп, сПепПЬ, ехрггез, изег, саПЬаск) { ЬЬ.Ьшье(:(и1]1.Гог1г1а1(кеуз.геГгезЬТокеп. геГгезКГокеп), { геГгезЬТокеп: -еГ-езЬТокеп, сПепМЬ: сИепПс!, ехрГгез: ехрагез ? ехртгез.То1503гг1пд() : пиП. изегТЬ: изег. 1с1 }, саПоаск); }; тоЬе1.деГ1)зег = ГипсТюп (изегпате, разз^огс!. саПЬаск) { ЬЬ.Ьде1аП(и1П.'ГогтаГ(кеуз.изег, изегпате), ГипсТХоп (егг, изег) { П (егг) геГигп са!1Ьаск(егг);
11 (!озег || раззлогс! !== изег.раззлогб) гесигп са11Ьаск(); са11Ьаск(пи11, { 16: изегпате }); }); Вам нужно только установить йесПз на вашем компьютере и запустить следу- ющий файл Ко6е.]з: #! /изг/Ь1п/епу побе уаг 6Ь = гецит ге(' гебьз') .сгеа1еСНеп-(:(); ОЬ лпи1И() .Ктзе1( 'изегз'.изегпате', { 16: 'изегпате', изегпате; 'изегпате', раззиогб: 'раззмзгсГ Нтзе1('с11еп1з:с11еп1:', { с11еп116: ‘с11еп1’, с11еп!8есгет: 'зесгес' }) // с11еп!16 + сИепТЗесге! Со базе 64 «111 депегаСе У2хр2И50ОпМ1УЗЛ6А== . за66(' сИепСз ’сИеп! :дгап1_1урез1 , [ 'раззлогб', ' геТгезЩСокеп' .ехес(-Гипс11оп (еггз) { 1Т (еггз) { сопзо1е.ег гог(еггз[0].теззаде); гесигп ргосезз ехИ(1); } сопзо1е.1од( СИепг апо изег аббеб зиссезз1и11у'); ргосезз.ех11(); }); Примечание: этот файл установит учетные данные для вашего фронтенда для запроса токена Итак, ваш запрос из выборки базы данных Кесйз после вызо- ва вышеуказанного файла будет следующим:
• сма*е*1М»$«п«г Мммм*|а й А И а • Пример вызова АР1 Заголовок: 1 аиСКопгаМоп: Вазтс, за которым следует пароль, установленный при первой настройке Ксскз: а.сИепПй + зесгеПб в Ьазе64 2. Форма данных: изегпэте: пользователь, запрашивающий токен ра з зло г с!: пароль пользователя дгап1_1уре. зависит от тою. какие опции вы хотите выбрать, обычно используется раззугогй, который требует только изегпаше и раззАлютй, чтобы быть созданными в Кесйз.
Данные в Кесйь буду] такими: { "ассезз.Юкеп ': 1бЗГе602Ог12а086есЬ2Ь996^7Ь7ае874120с4Г", "Сокеп.Суре . Ьеагег , // Будет использоваться для доступа к АР1 + ассезз+Гокеп, например: Ьеагег 1бЗГе602ба12а086есЬ2р99бГб7Ь7ае87412 0с4Г "ехр1гез_1п": 3600. "геГгезЬ.Гокеп": "Ь6аб56е5с9аЬа63с85б7е21Ы514680ЬЫ:711450 } Теперь нам нужно вызвать наш АР1 и получить некоторые защищенные дан- ные с помощью токена доступа, который мы только что создали: Когда токен истекает. АР! выдает ошибку о том. что токен истек, и вы не смо- жете получить доступ ни к одному из вызовов ЛР1: ® «т о г ” О Вм>*« 11 ГО<41 СвЖет-Тур* лом О а
Далее рассмотрим, какие действия следует предпринять, если токен истека- ет. Для начала поясним: если токен доступа истекает, в Кесйз есть возможность вызова геГгезЬ_токеп, который ссылается на истекший токен доступа. Поэтому нам нужно снова вызвать оаигй/Гокеп с геТгез!т_1океп в дгапт_1уое и устано- вить авторизацию на Вазк сИепПО :с11епТ5есгеТ (в Ьазе 64!), а затем отпра- вить геГгезН.Сокеп. Это сгенерирует новый токен доступы с новой датой истече- ния срока действия. Иа следующем изображении показано, как получит ь новый токен доступа: о ап О »свт О О О *** - Н1Мо«7 V Н*к Нм4т 'от, мп УагмЫи V --------------------------- «лЬопмиоо вам ПхргУ/ЫЮпМУХЛаЛ” ✓ X СогЧалГТур* вррИоаНоп/«*»*«* 1о»п»-цНепс«<й<1 / X Йа* Она Маа 1ЯС00Ч моеар МОЭМ **ПО*О гаОааП.М**’ ела456ак9*Ва4>с«и?»21Ы 1)44Мш?Н4$а X дгал1 1ур« п(гааЛ Юкап X ДМГГМЯ МЛШГПЯ Надеемся, что это поможет!
Глава 78. раскаде.]8оп Замечания Вы можете создать раскаде. ] зоп с помощью команды ПрШ 1П1Т ...которая затребует у вас базовую информацию о вашем проекте, включая идентификатор лицензии. Примерь! Основное описание проекта { "пате : ту-рго]есТ , "7ег51оп : '0.0.1", "с1езсг1р1:1оп" : ТЬтз 1з а рго]есГ.", "аитбог ; Зотеопе <зстеопе@'ехап’р1е.сот^ , "сопСпЬиДогз': [{ пате : Зотеопе Е1зе', ета11": "е1зе“ехатр1е.сот }], "кеутогбз : ["1трго7ез , "зеагсбхпд ] } Поле Описание пате Обязательное поле для установки пакета. Должно быть в нижнем ре- гистре, одним словом без пробелов (допускаются дефисы и подчеркивания). уегаоп Обязательное поле дтя версии пакета, использующее семантическое версионирование.
Поле Описание беьспрйоп Краткое описание проекта аийтог Указывает автора пакета. сопГпЬШотз Массив объектов, по одному для каждого участника. кеу^огбя Массив строк, который поможет пользователям находить ваш пакет. Зависимости оерепбепстез : { тооиХе-пате : '0 10"} • ехасХ: 0.1.0 установит конкретную версию модуля. • пеи/езт ГП1П0Г уегдХоп: Л0.1.0 установит новейшую минорную версию, например 0.2.0, но не установит модуль с более высокой мажорной версией, например 1 О 0 • пеиезТ раГсб: 0.1.x или -0.1.0 установит самую новую пагч-версию. например 0 1.4. но не установит модуль с более высокой мажорной или минорной версией, например 0.2.0 или 1.0.0 • итХбсагб: * установит последнюю версию модуля. • дП героз11:огу. установит ГагЬаИ с тазтег-ветки репозитория $й. Можно также указать #зба, #1ад или #Ьгапсб: о СйНпЬ: изег/рго^сТ иги изег7ргс]есТ#у1 .0.0 о иг1. дт (:://д111аЬ.сот/изег/рто]ес1: .дИ или д!1://дХТХаЬ.сот/ изег/рго]ес1.д1С#беуе1ор • локальный путь: й1е:..;ИЬ/рго]ес{ После добавления их в ваш раскаде . ] зоп используйте команду при 1пз1а11 в каталоге вашего проекта в терминале. (1е\Оереп(1епс1е8 бех-ОерепбепсХез": { " ппос1и 1е - пате . '0.1.0' } Для зависимостей, необходимых только для разработки, таких как тести- рование, стилизация, прокси и т.д. Эти беу-зависимости не будут установлены при выполнении команды прт ХпзТаИ в режиме ргобисПоп.
Скрипты Вы можете определить скрипты, которые могул быть выполнены или запу скаются до или после другого скрипта: { 5СГ1р18 : { ргеГез! : зсгтртз/ргеРезГ.]з 1езт : зсгтрСз/ТезТ., ’ розПезС ' зсггрСз/розПезТ .тз } } В этом случае вы можете выполнить скрипт, запустив любую из этих команд: $ прт гоп-зспрС Гез! $ прт гип 1езХ $ прт 1ез1 $ прт 1: Предопределенные скрипты Имя скрипта Описание ргериЫцЬ Запускается перед публикацией пакета. риЬПзй. роМриЬИзй Запускается после публикации пакета. ргетзСаП Запускается перед установкой пакета. тзГаП. розипмаП Запускается после установки пакета. ргешнпяаП. шипзгаП Запускается перед удалением пакета рояитпыаП Запускается после удаления пакета. ргруегмоп, уегзюп Запускается перед изменением версии пакета. ро81уегз1оп Запускается после изменения версии пакета. ргеГезС, 1ез(, розйезГ Запускается командой прт (езЬ ргезюр. з(ор, розГМор Запускается командой прт зюр. ргезГап, 81ап, розгзгап Запускается командой прт з1ап. ргегезГаП, гезгап, ромгелап Запускается командой прт гезГап.
Пользовательские скрипты Вы также можете определить свои собственные скрипты так же, как и предо- пределенные скрипты: { зсгХр'Сз : { "ргес!": 1 зспрСз/ргест^з", с! : зсГ1р1з/с1.]з", розЮ1 : зсгхрСз/розТсх. ]5 } } В данном случае вы можете выполнить скрипт, запустив одну из этих команд: $ прт гип-зсг1рС с! $ прт гип с! Пользовательские скрипты также поддерживают пред и пост-скрипты. как показано в примере выше. Расширенное определение проекта Некоторые дополнительные атрибуты, такие как герсзИогу, Ьидз или Ьотеоаде. анализируются веб-сайтом ИРМ и отображаются в инфобоксе для этих пакет ов { "тахп": зегуег.]з , "герозхгогу' : { "туре : дтС", ' иг1' : дтт+1ттСр8://д1гЬиЬ.сот/<ассоипгпате>/<геро51Согупа1пе>. ди" }, Ьидз": { "иг1 : Ьссрз ://дНЬиЬ.сот/<ассоипСпапе>/<героз1Согупате>/ ьззиез" }, "Ьотераде' : ' (гССрз:/УдИСшЬ.сот/<ассоип'Спате>/<героз1гогупате>#ге абте", "Шея : [ зегуег.]з , // исходные файлы ВЕДОМЕ.тб", // дополнительные файлы 11Ь // папка со всеми включенными файлами }
Поле Описание шаги Основной скрипт для этого пакета. Этот скрипт возвращается, когда пользователь требует пакет, герозАТог у Расположение и тип публичного репозитория. Ьидз Трекер ошибок для этою пакета (например, СпНил). Иотераде Домашняя страница для этого пакета или общего проекта. Г11ез Список файлов и папок, которые должны быть загружены, когда ио тьзователь выполняет команду прт тЫаВ <раска$епапте>. Изучение файла раскаде,рэп Файл раскаде. дзоп, обычно находящийся в корне проекта, содержит мета- данные о вашем приложении или модуле, а также список зависимостей для уста- новки из прт при выполнении прт АпзДаП. Чтобы инициализировать файл раскаде. ] зоп, введите прт 1П11 в командной строке. Чтобы создать раскаде. ] зоп с настройками по умолчанию, используйте: прт 1п11 --уез или прт гпИ -у Чтобы установить пакет и сохранить его в раскаде. ] зоп, используйте: прт 1пз1а11 {раскаде пате} -зауе Вы также можете использовать сокращенную запись: прт 1 -5 {раскаде пате} МРМ-алиасы -5 для -зауе и -0 для -зауе-беу сохраняют в производственных зависимостях или в зависимостях разработки соответственно. Пакет появит ся в ваших зависимостях; если вы используете -зауе-беу вместо -зауе, пакет поя- вится в беуОерепбепстез. Важные свойства раскате.{зоп: { "пате : тоби1е-пате’, "уегзАоп": "10.3.1 , безспрИоп' : Ап ехапр1е тсби1е То ШизДгаДе 1бе изаде оТ а раскаде.]зоп ,
'аиХИог : "Уоиг Мате <уоиг.па1ге@ехатрХе.огд>*, "сопХгхЬиХогз : [{ "пате ': "Еоо Ваг", ета11": ' Гоо.Ьаг@ехатр1е.сот' )], 'Ьгп": { тобиХе-папе": . /Ьхп/тобиХе-пате }, "зсгХр^б": { Хез! : уолз --зрес --ХзоХаХе", зХагХ": "побе хпбех.33' , ргеберХоу1: "есЬо АЬоиг го берХоу , розХберХоу'' еспо ОерХоуеб", 'ргериЬХХзК : соГГее --Ьаге --сотрХХе --оиТриХ Иь/Тос зге/ Гоо/*.соГГее }. ’таХп": 11О/Гоо.]з , "герозКогу : { 1уре : "дХХ", иг1 Ы1рз: //д11ЬиЬ.сот/изегпате/геро" }, 'Ьидз“: { иг1 ’ ЫЛрз://дНИиЬ. сот/изегпате/Хззиез }, кеумогбз": [ 'ехатрХе' "берепбепсХез": { ехргезз : 4.2.x }, беуОерепбепсхез": { аззите : "<1.0.0 || >=2.3.1 <2.4.5 || >=2.5.2 <3.0.0" }, реегОерепбепсхез : { "тотепГ' : >2.0.0' }, ’ргеГегСИоЬаГ : Тгие, ’ргиуаХе : 1гие, 'риЫгзНСопТхд : { гедхзГгу' : ГгСТрз.//уоиг-рг1ха1:е-Иоз1:еб-прт. гедхзТгу .ботат сот' }, 'зиЬботаХп : ' ГэсЬаг", апа1уге : 1гие, "Исепзе": М1Т",
"Шез : [ '11Ь/Г00 ]8 } Информация о некоторых важных свойствах: паше — уникальное имя вашего пакета, которое должно быть написано строч- ными буквами. Это свойство обязательно, и без него ваш пакет не установится. 1. Имя должно содержать не более 214 символов. 2. Имя не може г начинаться с точки или нижнего подчеркивания. 3. Новые пакеты не должны содержать заглавных букв в имени. уегз!оп — версия пакета указывается по семантическому версионированию (зеп^ег). Предполагается, что номер версии записывается как МА}ОК.МШОК. РАТСН, и вы увеличивает е: 1. МА]ОК-версию при внесении несовместимых изменений в АР1. 2. М1ИОК версию при добавлении функционала, совместимого с предыдущими версиями 3. РЛТСН-версию при внесении обратно совместимых исправлений ошибок. аезспрсхоп — описание проекта. Старайтесь делать его кратким и точным. эотИог — автор этого пакета. Ото — объект, который используется для экспорта бинарных скриптов из ва- шего пакета Предполагается, что ключ — это имя бинарного скрипта, а значе- ние— относительный путь к скрипту. Эю свойство используется пакетами, ко- торые содержат интерфейс командной строки (СЫ). зсг1р1з — объект, который предоставляет дополнительные прт-команды. Предполагается, что ключ — это прт-команда, а значение — пуль к скрипту. Эти скрипты мотут быть выполнены при запуске прт тип {соттапб пате} или прт гиг.-зегют {соттапб пате}. таю основная точка входа в вага пакет. При вызове гери!ге(' {тосйНе пате} ’) в Мос1е.]3 этот файл будет фактически загружен. Настоятельно рекомен- дуется, чтобы требование основного файла не вызывало побочных эффектов. На- пример. требование основного файла не должно запускать НТТР-сервер или под- ключаться к базе данных. Вместо этого вы должны создать что то вроде ехрогТз. 1П1С = ТипсТюп () {..} в вашем основном скрипте. кеуиогбз — массив ключевых слов, описывающих ваш пакет. Опи помогут пользователям найти ваш пакет. оеуОерепбег.стез — эго зависимости, которые предназначены только для раз- работки и тестирования вашего модуля. .Зависимости будут установлены авто-
матически. если только переменная окружения МООЕ_ЕМУ=ргобисТ1оп не уста- новлена. В этом случае вы все равно можете установить эти пакеты с помощью прт тпзСаИ--беу. реегЭерепбепслез — если вы используете этот модуль, то реегСерепбепслез перечисляет модули, которые вы должны установить вместе с этим. Например, тотепС-Нтегопе должен быть установлен вместе с тотепС, пот ому что он явля- ется плагином для тотепС, даже если он не требует геритгеС'тотепТ") напрямую. ргеТег61ооа1 — свойство, указывающее, что этот пакет предпочтительно устанавливать глобально с использованием прт лпзДаИ -д {тоби±е пете}.Это свойство используется пакетами, которые содержат интерфейс командной стро- ки (СП). В остальных случаях не следует использовать это свойство. риЬ11зКСопТ1д — эго объект с конфигурационными значениями, которые будут использоваться для публикации модулей. Установленные значения кон- фигурации переопределяют вашу конфигурацию прт по умолчанию. Наибо- лее распространенное использование рор11з1тСоп'('1д — публикация вашего па- кета в частный прт-рееслр, чтобы у вас по-прежнему были преимущества лрт, но для частных пакетов. Это делается путем простого указания НКЬ вашего част- ного прт в качестве значения .для ключа гед!з1гу. Т11ез — это массив всех файлов, которые должны быть включены в публику- емый пакет. Может использоваться как путь к файлу, так и путь к папке. Все со- держимое папки будет включено. Это уменьшает общий размер вашего пакета, включая только правильные файлы для распространения. Это поле работает со- вместно с файлом правил .поттдпоге. Источник; Нпрзу/Ьгосузепрт.ог^/.
Глава 79. Разбор аргументов командной строки Примеры Передача действия (глагола) и значений сопз! орПопз = геди!ге( сотггапс1ег ); орПопз . орГ1оп("-V, --уегЬозе , "Ве уегЬозе ); орГюпз согг.тапд( "сопуегг") ,а11аз("с ) .с1е5сг±р1 дон( 'СопуегГз три! ГПе Го оиГри! ГПе ) ,ор1:1оп( -1, --1п-Г1]е <'Г11е_пате> , 1 1приг Т11е ) . орПоп("-о, --оиГ-Г11е <Г11е_пате>' , 'ОиГриГ Г11е") .ас11оп(с1оСоп7ег'С); орГюпз.рагзе(ргосезз.агд^); 1Г ('орГюпз.агдз.ХепдГЬ) орПопз.Пе1р(); ГипсТюп с1оСопуег1:(ор11опз) { // с1о зотегЫпд ’лГГЬ орПопз. 1пЕ11е и орПопз.оиГГПе } Передача булевых переключателей сопз! орПопз = геди!ге(1 сотггапдег ); орГюп.з .орГ1оп("-V, --уегЬозе") .рагзе(ргосезз.агду); 1Г (оргюпз.уегЬозе) { сопзо1е. 1од( 1_еТ з паке зоне подзе1'); }
Глава 80. Интеграция РаззроП Примечания Пароли всегда должны быть хешированы. Простым способом защиты паро- лей в Мос1е.)8 будет использование модуля Ьсгур!-побе]з. Примерь! Начало работы РаззроП необходимо инициализировать с помощью промежуточного ПО раззрэг!. 1П111а112е(). Для использования сеансов входа требуется промежу- точное ПО раззрог!.зеззтопО- Обратите внимание, что методы раззоог!.зег1а112е() и разярог!. с1езег1а11хе11$егО должны быть определены. РаззроП будет сериализовать и де- сериализовать экземпляры пользователя в и из сессии. сопз! ехргезз = геци1ге('ехргезз'); сопз! зеззюп = гер1пге( 'ехргезз-зеззюп'); сопз! раззрог! = геци1ге('раззрог!1); сопз! соокзеРагзег = гецшге('соокте-рагзег'); сопз! арр = ехргеззО ; // Требуется для чтения соокцез арр изе(соок!еРагзег()); раззрог!.зег1а112еизег(Типс!1оп(и5ег, пех!) { // Сериализация пользователя в сессии пех!(пи11, изег); }); раззрог! .с!езег1а112е11Еег(Типс!1оп(и5ег| пех!) { // Использование ранее сериализованного пользователя
пехГ(пи11, изег); }); // Настройка промежуточного ПО ехргезз-зеззюп арр.иее(зе831оп('{ зесгеХ: 'тре саке 13 а Не', гезауе: Тгие, зауе11п1П11:1а112есГ Ние })); // Инициализация раззрогт арр, изе(раззрог1,1п11:1а112е()); арр,изе(ра88рогГ_зезз1сп()); // Запуск сервера ехргезз на порту 3000 арр.11згеп(3000); Локальная аутентификация Модуль. раззрог1-1оса1 используется для реализации локальной аутентифи- кации. Этот модуль позволяет вам аутентифицировать пользователей, исполь- зуя имя пользователя и пароль в ваших приложениях на Ыойецз. Регистрация пользователя: сопзТ раззрогЕ = геди1ге('рэззрогЕ'); сопзЕ Ьоса18ЕгаЕеду = гедихге('ра&зрогЕ-1оса1').ЗЕгаЕеду; // Используется именованная стратегия, так как используются две ло- кальные стратегии: // одна для регистрации, другая - для входа раззрогЕ.и&е(' 1сса181дпир1, пел Юса18ЕгаЕеду( { // Переопределение параметров по умолчанию, // которые - изегпате и 'раззл'огсГ изегпате!-1е1а: еггаИ', раззчогбРхеХа: 'раззлогсГ, раззРедТоСаПЬаск. Егие // позволяет нам передать весь запрос в об- ратный вызов. }, ГипсЕюп(гед. етаП, раззлогс!, пехЕ) { // Проверка в базе данных, зарегистрирован ли пользователь Ехпс111зег6уЕп1а11(ета111 ТипсЕхоп(изег) { // Если етах! уже существует, прекращаем процесс регистрации и // передаем 'Га1зе в обратный вызов
1Т (изег) гегогп пехс(пи11, <3136); // Иначе создаем пользователя е1зе { // Пароль должен быть хеширован! 1е! пеиОзег = сгеа!ейзег(ета11, раззлогй); пе'ли8ег.зауе(Типс!1сп() { // Передаем пользователя в обратный вызов ге!игп пех!(пи11, пелПзег); }); } }); ПК- Вход пользователя: сопат раззрог! = гедщге('раззрсгх'); сопз! 1оса15!га!еду = "еризге('раззрог!-1оса1'),5!га!еду: раззрог!,изе('1оса181дп1п', пей 1оса12!га!еду({ изегпатеЕ1е1с1 : 'етатГ, разз1логбР1е1с1 разз^огб’, }, !и11С!1оп(етаЛ1 раззиогб, пех!) { // Поиск пользователя р1пс1П8егВуЕта11(ета11, ТипсТюп(изег) { // Если пользователь не найден, прекращаем процесс входа // Пользовательские сообщения могут быть предоставлены в функ- ции проверки, // чтобы дать пользователю больше деталей относительно неудач- ной аутентификации 1! (!изег) ге!игп пех!(пи11 Та1зе, {теззаде: ТГпз е-та11 ас1с1гез8 1з по! аззос1а!ес1 и1!Гт апу ассоип!.'}); // Иначе проверяем, правильный ли пароль е!зе { // Если пароль неверный, прекращаем процесс нхсда 1! (! 1зРаззиюгс1\га11а(раззлогс1)) ге!игп пех!(пи11, Та1зе); // Иначе передаем пользователя в обратный вызов е1зе геТигп пех!(пи11, изег); } }); })):
Создание маршрутов // ... арр.изеГраззрогС.ГпШаПхеО); арр.изеСраззрогт зезз1оп()); // Маршрут для входа // Стратегии РаззрогС являются Ш1с1с11ейаге арр.роз1:('/1од1п', раззрог!. аи1Иеп11саСе( 1оса181дп1п', { зиссеззВеОтгест: '/те', ГалГи геЯесИгесТ: '/1од1п' })); // Маршрут ,цля регистрации арр розГ('/гедьзГег', ра$зрог1:.аитЬеп1:1са'1е( 1оса181дпир', { зиссеззРеЫгесИ: (аПигеРесИгест: '/зздпир })); // Вызов гед 1 одой*() для выхода арр. деЦ '/ГодоиЬ', Гипс11оп(гед, гез) { гед.1одои1(); гез. гес11гест(' / ’); }); арр. ИзТеп (3000); Аутентификация через ГасеЬоок Модуль раззрогт-ТасеЬоок используется для реализации аутентификации через ГасеЬоок. В этом примере, если пользователь не существует при входе, он создается. Реализация стратегии: сопзт раззрогЬ = гедлге( ’раззоогт'); сопз! ГасеЬоокЗсгагеду = геди!ге('раззрегЬ-ГасеЬоок'),81гаГеду; // Стратегия по умолчанию называется ^асеЬсок раззрогС.изе(пей ГасеЬоок81гаГеду({ сИепЬЮ: 'уоигсИепЫс! , сПепТЗесгеС: уоигсГтепТзеоге! , саПЬаскОКС: ' /аЛЬ/ГасеЬоок/саПоаск’ }, // ГасеЬоок отправит токен и профиль пользователя
Гипс<1оп(1океп. геГгезЬТокеп. ргоТПе, пехЬ) { // Проверяем в базе данных, зарегистрирован ли пользователь Г1пс111зегВуРасеЬоок1с1(ргсТ11е.1с1, Типс11оп(изег) { // Если пользователь существует, возвращаем его данные в саПЬаск 1Т (изег) геСигп пехЦпиП, изег); //В противном случае создаем пользователя е1зе { 1ес пеиЗзег = сгеаге1)зегЕготЕасеЬоок(ргоГ11е, Юкеп); пеу/Пзег.заме^ипсиспО { // Передаем пользователя в саПЬаск ге!игп пех1(пи11, пемОзег); }); } В; })); Создание маршрутов // ... арр.изе(раззрог1:.1п1Т1а112е()); арр.изе(раззрог1.зезз1оп()); // Маршрут для аутентификации арр.деТ('/аиЫт/СасеЬоок ', разярогЬ . аиСЬепЫса!^ ' -ГасеЬоок', { // Запрос дополнительных разоешений у РасеЬоок зсоре: етаП' })); // Маршрут, вызываемый после аутентификации пользователя через ЕасеЬоок арр де1('/аиШ'ТасеЬоок/саПЬаск', раззрогб .аиТНепТ1са1:е( '-ГасеЬоок', { зиссеззРес11гес1: ‘/те’, Тат1игеРес11гес1:: '/' }) ); //... арр 11з1еп(3000); Простая аутентификация по имени пользователя и паролю Б вашем файле гои1ез/1пс1ех. ]з: Здесь изег — это модель для изегЗсйета. гоибег.роз-Ц /1од1п', Гипс1:1оп(гед, гез, пехС) {
1Г (!гед Ьобу.изегпате || ! гец .Ьсду раззиогс1) •{ геТигп гез.з1:а1:из(400) ,]зоп({ теззаде: 'Р1еазе Т111 ои! а11 Т1е1аз' }); } раззрог1:.аи1:Ьеп1:1са1:е( 1эса1 , ТипсНоп^гг, изег, 1пТо) { (егг) { сопзо1е.1од("ЕАА0А : + егг); ге1игп пехД(егг); } 1Е(изег) { сопзо1е.1од( Озег ЕхгзГз!"); // Все данные пользователя можно получить через изег.х гез.]зоп({"зиссез8" : 1гие}); гсбигп; } е1зе { гез ]зоп({"зиссезз Еа1зе}); сопзо1е.1од("Еггог + еггогАезропзе()) ; гегигп; } })(гед, гез, пех!); }); Аутентификация через 6оод1е с использованием РаззрогХ Мы можем использовать простой модуль прт для аутентификации через Соо§1е, называемый раззрог!-доод1е-оаи1Г|20. Рассмотрим пример, в котором примере создана панка сопПд, в которой на ходится файлы раззрог!. ] з и доод1е . ] з в корневом каталоге В вашем файле арр. ] з включите следующий код: уаг ехргезз = геди!ге('ехргезз'); уаг зеззгоп = гедо1ге('ехргезз-зеззюп'); уаг разорит! = геди!ге('./сопГад/раззрогЧ:'); // путо к файлу раззрог! уаг арр = ехргезз(); раззрсгЦарр); // остальной код для инициализации сервера и обработки ошибок В файле раззрог!. у з в папке сопТл д включите еле,дующий код: уаг рэззрог! = гедо1ге('раззрег!’),
доод1е - гедтге(' ./доод1е'), 1)зег = геди!ге('./../тоде1/изег'); // Изег - это модель топдоозе тос1и]е.ехрог1з = ТипсНощ арр) { арр изе(раззрог1;. 1П1Г1а11ге()); арр.изе(ра5зрогг.5езз1эп()); раззрог! .зег1а11геизег(-(:ипсг] эп(изег, оопе) { с1опе(пи11, изег); }); раззрог!,с1езег1а11геизег(Гипс11оп (изег, йопе) { с!опе(пи11, изег); }); доод1е(); }; В файле доод1е ]з н той же папке сопТтд включите следующий код: уаг раззрогЧ = гедлге( раззрогД'), СоодТеЗДгаДеду = геди1ге( ра83рогг-досд1е-оаи1:И20 ) .ЗСгаТеду, Озег = геди!ге(' ,/тос1е1/изег'); тос1и1е. ехрогТз = ТипсПоп () { раззрог!,изе(пел 6оод1е81:гагеду( { сИепГЮ: 'СПЕЮ 10', сИепГЗесгеГ: 'СПЕЮ 8ЕСРЕТ’, са11Ьаск1)Р1: "(гсср: //1оса1 Ьозг :3000/аи11п/доод1е/са11Ьаск ' }, ТипсС1оп(ассеззТокеп, геТгезПокеп, ргоТПе, сЬ) { 11зег .Г1поОпе({ доод1е1г1 : ргоГ11е.1с1 }, ТипсПоп (егг, изег) { 1Т(егг){ геДигп сЫегг, Та1зе, {теззаде : егг}); }е1зе { 1Т (изег != '' && изег != пиП) { гесигп сЬ(пи11, изег, {теззаде . Озет "}); } е1зе { уаг изегпате = ргоТ11е.(Изр1ауЧате.8р1:Щ ' '); уаг изегОаДа = пег.1 11зег({
пате : ргоГИе.скзрТауМгте, изегпапе : озегпате[0], раззлогс! : изегпате[0], ТасеЬоокТо : ' ', доод1е1^ : ргоТ11е.1с1, }); II Отравляем ета11 пользователю на случай, если нужно отправить // вновь созданные учетные данные для последующе- го входа без использования Соод1е изег0а1:а.ЗаУе(Типс1:1оп (егг, пеиизег) { 1Т (егг) { геТогп сЬ(пи11, Га1зе, {теззаде : егг + ! 1 1 Р1еазе Тгу адагп }); } е1зе { геТигп сЬ(пи11, пеиизег); } }); } } }); } )); }; В этом примере, если пользователь отсутствует в базе данных, создается но- вый пользован ель для локального использования, используя поле доод!е1с! в мо- дели пользователя.
Глава 81. разгроме Введение РаззрогГ — популярный модуль авторизации для \’ос1е.)8. Проще говоря, он об- рабатывает все запросы на авторизацию пользователей в вашем приложении. РаззроП поддерживает более 300 стратегий, что позволяет легко интегрировать вход через ГасеЬоок, 6оо#1е или любую другую социальную сеть. Стратегия, кото- рую мы рассмотрим здесь, — это коса), где вы аутентифицируете пользователя, используя собственную базу данных зарегистрированных пользователей (с ис- пользованием имени пользователя и пароля). Примеры Пример 1оса181га!еду в раззроП ]з уаг раззрог! = геди!ге('раззрогг'); уаг 1оса181:га1еду = герог ге(' раззрог1:-1оса1') ЗГгабеду; раззрогГ . зег1а112е0зег(рипс'Сюп( изег, боле) { // Р зегьаИгебзег вы решаете, что хранить в сессии Здесь мы со- храняем только 16 пользователя. 6опе(пи11, изег.ю); }); раззрог! .с1езег1а112е115ег(1:ипс1:1сп(1б, допе) { // Здесь вы извлекаете всю информацию с пользователе из храни- лища сессии, используя 16 пользователя сохраненный ранее с помощью зег1а112е1)зег. об Г1пд8у1д(1д, Сипспоп(егг, озег) { 6опе(егг, озег); }); });
раззрог!. изе(.пел 1оса18(:га1еду(Типсг1оп(изегпате, разз*уогс1, <3опе) { РЬЛ1пРСпе( {' изегпате : изе тэте}, ГипсИоп (егг, згийеп!) { 1Т(егг) геСигп аопе(егг,{теззаде:теззаде}); // Неправильный номер или пароль; уаг разз_гегг1еуеб = зГиНелг.разз.лсг^, Ьсгур!,сотраге(раззлогб, разз_ге!г1еуес1, Типс!1оп(еггЗ, соггес!) { 1Г(еггЗ){ теззаде = [{"тзд": “Тпсоггес! Раззу/огс1!1 } ] , гегигп допе(пи11,!а1зе,{теззаде:теззаде}); // Непра- вильный пароль } тПсоггес!) { ге!игп 0опе(пи11, згибеп!); } }); }); })); арр.изе(зеззюп({ зесгеС: 'зирег зесге!' })); // Чтобы раззрог! запомнил пользователя на других страницах. (Прочтите о хранилище сессий. Мы использовали ехргезз-зеззтопз.) арр. изе(раззрог1 1П11:1а11ге()) ; арр.изе(раззрог!.зезз1оп()); арр .роз!(' / ’, раззрог!.аи!(тепИса!е(' 1оса1 , {зиссеззРес!1гесГ : ’ / изегз’, ГаПигеПескгес!: ’/’}), /ипс!1оп(гед,гез,пех!){ });
Глава 82. Проблемы производительности Примеры Обработка длительных запросов в Мойер Так как Мойер однопоточный, требуется обходной пул ь для длительных вы- числений. Примечание: этот пример «готов к запуску». Не забудьте подключить )(ртегу и установить необходимые модули. Основная логика этого примера: 1. Клиент отправляет запрос на сервер. 2. Сервер запускает процедуру в отдельном экземпляре Мойер и немедленно отправляет ответ с соответствующим Н) задачи. 3. Клиенгпостоянно отправляет запросы на сервер дляполучения обновлений статуса данной задачи. Структура проекта: рго]есС | раскаде.]5оп I тпйех.Ыт! I—18 таю. ]аиегу-1.12.0.ттп. ]з 1----ЗГ7 I арр.]8 |—тойе1з | Тазк.]8 1--Тазкз йаса-ргосеззог.дз
аррдз: уаг ехргезз = гедихге('ехргезз ); уаг арр = ехргезз(); уаг Ь!!р = геди!ге(‘Ь1!р’).Зегуег(арр); уаг топдоозе = геди!ге( топдоозе’); уаг ЬобуРагзег = гедлге('Ьос1у-рагзег'); уаг с№1 Ргосезз = гедихге('сЬНрргосезз'); уаг Тазк = гедихге('./тойе1з/!азк1); арр.изе(Ьо(1уРагзег и г 1епсос1ей ({ ех!епйес1: !гие })); арр.изе(ЬойуРагзег.]зоп()); арр.изе(ехргезз з!а!хс(__сИгпате + арр.де!('/', Гипс!1оп(гедиез!, гезропзе){ гезропзе гепаег( хпоех.ЫтГ); }); // Маршрут для самого запроса арр.роз!('/1опд-гиппюд-гедиез!’, Типс!юп(гедиез!, гезропзе){ // Создаем новый элемент задачи для отслеживания статуса уаг 1 = пей Тазк({ з!а!из: 'Зтагипд }); !.зауе(!ипс!аоп(егг, газк){ // Создаем новый экземпляр Мойе.дз для выполнения отдельной за- дачи в другом потоке 1азкРгосеззог = сЬ11 ^Ргосезз.Гогк( ' ./згу/!азкз/с!а!а-ргосе88ог.]з'); // Обрабатываем сообщения, приходящие от процессора задач !азкРгосеззог.оп(‘теззаде’, Типс!1оп(тзд){ тазк.з!аси8 = тзд.з!а!из; !азк зауе(); }.Ыпс1(!Ы8)) ; // Закоываем ранее открытый экземпляр Мойе.)з после заверше- ния задачи !азкРгосеззог.оп('с1озе ’ Гипс!1оп(тзд){ !Ыз к 111 () ; }); // Отправляем некоторые параметры для нашей отдельной задачи уаг рагатз = { теззаде' ’НеИо Тгот таю !Ьгеаб‘ }; !азкРгосеззог.зепР(рагатз);
гезропзе. зГа1:из( 200). ]зсп(1азк) ; }); }); // Маршрут для проверки завершения вычислений по запросу арр.роз'Ц'/18-геайу', ГипсГ1оп(гедиезГ, гезрспзе){ Таяк . Т1пс1Ву1с1 (гедиезГ. Ьсбу. 16) ехес(Типс'11оп(егг, тазк){ гезропзе.згагиз(200). ]зоп(1азк); }); }); топдоозе.соппесх( ' топдобЬ ://1оса1Г|О8Г/1:езт'); пггр.11згеп('1234'); (азк.]з: уаг топдоозе = гедлге('топдоозе'); уаг ГаякЗсЬета = топдоозе.Зенета({ згаХия: { Гуре: ЗГппд } }); топдоозе тобе1('Тазк', ГазкЗсНета); тос1и1е .ехрогГз = топдоозе. тобеЦ 'Тазк ’); ааГа-ргосеззог.]8: ргосезз.оп( 'теззаде', ГипсГюп^зд){ 1П11 = Гипс11оп(){ ргосезз0а1а(тзд.теззаде); } .Ып6(1Р1з) () ; ГипсГюп ргосеззСаЩтеззаде){ // Отправляем обновление статуса е основное приложение ргосезз.зепб( { зГаГиз: 'Йе Ьахе зГагГес! ргосеззюд уоиг с1а(:а. ' }); // Долгие вычисления зе1Т1теои1:(Гипс1:1оп() { ргосезз.зелб({ зГаГиз: 'Оопе!' ));
// Уведомляем Мойе.]з, что задача завершена ргосезз.йт-зсоппесЦ); }, 5000); } }); ргосезз.оп('ипсаадЬТЕхсерг1он', ТипсТ1оп(егг){ сопзо1е.1од("Еггог Ьаррепей: + егг.теззаде + "\п" + егг.зДаск + "Ап"); сопзо1е.1од( бгасеДиПу ТтптзЬ ДНе гоиНпе. ); }); тйех.Й1т1: <!ООСТУРЕ Ыт1> <Ыт1> <Иеас1> <зспр1 згс= ./]з/]циегу 1.12.0. пип. ]з"></зсг1р1:> <зсг1р1 згс= ./]8/та1п. ]з"></зспрр> <!Ьеай> <Ьойу> <р>Ехэтр1е оТ ргосеззюд 1опд-гипп1пд пос1е гедиезхз.</р^ <Ьи11оп 1с1="до" ±уре= ЬиДгоп >Кип</Ьи11оп> <Ьг /> <р >1_од :</р> сДехДагеа 1й='1од" гоиз="20" со1з= 50'></ЕехГагеа> </Ьойу> </1лт!> тат.)з: $(йоситеп1) ,оп(' геайу ’, Типс1юп(){ $('Ядо’),оп('с11ск', ТипсРзоп(е){ // Очистка логсв $("#1од").уа1("); $.роз1("/1опд-гипп1пд-гедиез1:", {зоте.рагатз: 'рагатз' }) . сЮпеГ^ипсИоп^азк) { $("#1од ).уа1( $( #1од ).ха1() + '\п' + Разк.зРаТиз); // Функция для отслеживания статуса задачи ТипсИоп ирс1а1еЗ'СаДиз()-{ $.роз1( /13-геайу", {1й: 1азк._1с1 })
,аопе('<:ипсг1ог|( гезропзе) { $("#1од ).уа1( $("#1од ).уа1() + Лп’ + гезропзе.зСаТиз); 1Г(гезропзе.81а1из != Сопе!'){ сбескТазкТттеоот = зеИптеои'ЦирааНеЗГаНиз, 500); } }); } // Начало проверки задачи уаг сЬескТазкТхтеооГ = зегТ1теоис(ирс1аГе51атиз, 100); )); }); }); раска§е.]8оп: { "пате": побеРгосеззог", 'берепбепслез : { Ьойу-рагзег": "М .15.2", "ехргезз": 'л4.14.0 , Ыт1 : 0.0.10", "топдоозе' : "А4.5.5 } } Обратите внимание: этот пример предназначен для объяснения основной идеи. Для использования в производственной среде он требует доработок.
Глава 83. Интеграция с Ро81дге$01_ Примеры Подключение к РозТдгеЗОЬ Рассмотрим использование ПРМ-модуля Розе дге801 Установите зависимость: прт 1пз1а11 рд -зауе Теперь нужно создать подключение к РозТд г е801_, которое вы сможете исполь- зовать для выполнения запросов. Предположим, что у вас ОатаЬазе_Мате = згийептэ, НозТ = 1оса1ЬозХ и ОВ_11зег = розТдгез уаг рд = гедотге( рд ); уаг соппесИопЗТгхпд = рд://роз^дгез :роя1дге8@1осаП1оз1:: 5432/ зсибспТз1; уаг сИепТ = пей рд.С11епт(соппес11оп81г1пд); с11еп1.соппес1(); Запрос с использованием объекта подключения Если вы хотите использовать объект подключения для запроса к базе данных, вы можете использовать этот пример кода: уаг диегуЗТгщд = "8Е1ЕСТ пате, аде РВОМ зТибепЕз ; уаг диегу = сИепТ .диегу(диегу8тг1пд) ; диегу оп( гои , (гои, гезиИ) => { гезиИ аОбРс«( гои) ; }); диегу.оп( епб ТипсИоп (гезиИ) { // ЛОГИКА });
Глава 84. Структура проекта Введение Структура проекта на Мойе.]8 зависит от личных предпочтений, архитектуры проекта и используемой стратегии инъекции модулей. Также она влияет на со- бытийно-ориентированную архитектуру которая использует механизм динами- ческого инстанцирования модулей. Чтобы создать структуру МУС, необходимо разделить серверный и клиентский код, так как клиентский код, вероятно, будет минимизирован и отправлен в браузер и является публичным по своей приро де. Серверная часть или бэкенд будет предоставлять АР1 для выполнения опера- ций СКИП. Примечания Проект, описанный выше, использует модули Ьгои'зегйу и Vие. ] 5 в качестве основы для представления и библиотек минимизации. Поэтому структура про- екта может незначительно измениться в зависимости оттого, какой МУС фрейм- ворк вы используете. Например, директория Ьи11б в папке риЬИс должна содер- жать весь код МУС. Вы можете настроить задачу, которая будет это делать за вас. Примеры Простое Мос!е,]8-приложение с использованием М\/С и АР1 • Основное различие заключается в разделении динамически генерируемых директорий, которые будут использоваться для хостинга, и исходных директорий. • Исходные директории будут содержать файл или папку' конфитурации в зависимости от объема конфигурации, который может включать конфигурацию окружения и конфигурацию бизнес-логики. которую можно поместить в директорию сопНд.
|-- СооИд |-- сопНд. _)8оп |-- аррСопНд |-- реСз.сопТтд |-- раупепг.сопТ1д • Теперь рассмотрим важнейшие директории, в которых различаются серверная (бэкенд) и клиентская части проекта. Две директории зегуег и иеЬарр представ.гяют собой соответственно бэкенд и фронтенд, которые можно разместить в исходной директории, например зге Вы можете использовать другие названия в зависимости от личных предпочтений для зегуег пли иеьарр, в зависимости от того, что вам кажется более логичным. Однако не следует выбирать слишком длинные или сложные названия, так как это внутренняя структура проекта. • Внутри директории зегуег вы можете разместить контроллеры, а также файл Арр. ] з/1пбех. ]з, который будет основным файлом Койе.]8 и точкой входа. Директория зегуег также может содержать директорию сНо, в которой будут находиться все объекты передачи данных, используемые контроллерами АР1: |-- зегуег |-- бсо | — рег.]з |-- раупеот.]з |-- соп!го1]ег |-- РеДзСопбгоПег.]з |-- РаупегйСопТгоПег.]з I" Арр ]8 Директория «еЬаор может быть разделена на две основные части: риЬИс и шус. Это снова зависит от выбранной стратегии сборки. Мы используем ЬгоуузеггГу для сборки части МУС в веб-приложении и минимизации содержимо- го из директории тус: |-- «ебарр |-- риЬИс |-- Ьи11б // будет содержать минимизированные скрипты (тус) |-- хтадез |-- тоизс.]рд | — саН.зрд |-- зту1ез |-- зСуХе.сзз |-- У1еиз
- - ретЗтоге Ьтт1 - - раутеоТбаТеиау. Г11ип1 - - Кеабег. Ыт1 - - Тоогег.НГт! - - 1пбех.1тгт1 • Директория ту с будет содержать фронтенд-логику. включая модели, контроллеры представлений и любые другие утилитарные модули, которые могут понадобиться как часть интерфейса. Также файл тпбех. ]5 или з1ге11.]з, в зависимости от предпочтений, будет частью этой директории: |-- ГЛУС |-- соп1го11егз |-- ОазЬЬогаа. ]5 |-- Не1р.]5 |-- 1_од1п.]8 |-- оШз |-- 1пс1ех.]8 Итак, в конце вся структура проекта будет выглядеть следующим образом. Простая задача сборки, например, с использованием ди1р ЬгоизегИу, будет минимизировать скрипты МУС и публиковать их в директории роЫтс. Затем мы можем предоставить эту директорию как статический ресурс через ехргезз. изе(зСаС1с( роЬ11с )) АР1 |-- побе_тоби1ез |-- зге |-- зегуег |-- сопТгоПег |-- Арр.]з // поае арр |-- иеЬарр |-- роЫтс |-- зТу1ез |-- 1тадез |-- 1пс1ех .Нгт1 |-- (ПУС |-- сопТгоПег |-- з1те11.]з // тус зИеИ |-- согтГтд |-- Кеэбте.тб |-- .дтПдпоге |-- раскаде.]зоп
Глава 85. РизН-уведомления Введение Если вы хотите создать уведомления для веб-приложения, мы рекомендуем использовать фреймворк РизЬ.)5 или ОпеЗт^па! для веб/мобильных приложений. Риз11.)8 — это самый быстрый способ начать работать с уведомлениями на |аеа8спр(. Довольно новое дополнение к официальной спецификации, А Р1 уве- домлений позволяет современным браузерам, таким как Сйгогпе, 8аГап, ЕтгеГох и 1Г 9г. отправлять уведомления на рабочий стол пользователя. Вам необходимо будет использовать ЗоскеЫо и какой-либо Ьаскепй фрейм- ворк. В этом примере мы задействуем Ехргезз. Параметры Моду ль,'Фреймворк Описание пойе.)8/ехрге88 Простой Ьаскепй-фреймворк для приложении на Пойе.]8, очень простой в использовании и чрезвычайно мощный. Зоскеыо ЗоскеМо обеспечивает двунаправленную событийную коммуникацию в реальном времени. Работает на всех платформах, браузерах и устройствах, уделяя равное внимание надежности и скорости. Ри811.)8 Самый универсальный фреймворк для уведомлений на рабочий стол. ОпеЗтдпа! Еще одна форма риьй-уведомлений для устройств Арр1е. НтеЬазе Мобильная платформа Соо§1е, которая помогает быстро разрабатывать высококачественные приложения.
Примеры Уеб-уведомлеиие Сначала вам нужно установить модуль Ризй.^з: $ прт юзСаП риз1т.]з -зауе ...или импортируйте его в ваше фронт енд-приложение через СОМ: <зспр1 згс=" ./ризп.т1п.]з"></8сг1р'1> <!-- СОМ ссылка После этого вы можете начать работать. Вот как это может выглядеть, если вы хотите сделать простое уведомление: РизП.сгеаСе( ’НеПо ’Лог1б') Мы предполагаем, что вы знаете, как настроить 8оске(ло в вашем приложе- нии. Вот пример кода для нашего Ьаскепб-приложения на Ехргезз: уаг арр = гери!ге(’ехргезз')(); уаг зегуег = гери!ге('(тир') .Зегуег(арр); уаг ю = гери!ге(' зоске!:. хо') (зегуег); зегуег.11з1еп(60); арр дег('/’, -Гипспоо (гед, гез) { гез.зепсИ’11е(_____бггоате + '/тпбех ,Ы:тГ ); }); 1о.оп( 'соппесСюп', ТипсПоп (зоске!) { зоскеС,ет11:( 'ризИМоННсаТюп', { зиссезз: Сгие, тзд: 'ЬеПо' }); }); После того как ваш сервер настроен, можно переходить к фронтенд-части. Те- перь все, что нужно сделать — это импортировать ЗоскеЫо СОМ и добавить этот код в файл юбех.Ы т1: <зсг1рС згс="../зоскеС.1о.]3 ></8Сг1рС> <!-- СЭМ ссылка --> <зспрг> уаг зоскет = 1о.соопесС( ‘Ыто://ТосаИтозТ'); 8оске1.оп('ризНМопПсасюп', ТипсСюп (ба!а) { сопзо1е.1од(ба!а); Ризб.сгеаСе('Не11о иог1б!", { бобу: баса.тзд, // это должно вывести Ье11е 1соп: '/лсоп.рпд , ПтеоиС: 4ОЙ0, опСИск: Типе Пог () { уппбоюИосизО ;
ТЬтз ,с1озе(); }); }); </5СГ1р1> Теперь вы должны отобразить ваше уведомление. Это также работает на лю- бом устройстве с А1к1го1б. Если вы хотите использовать ПгеЬазе С1оий Мезза^шд, вы можете использовать его с этим модулем Вот ссылка на пример, написанный Ником (создателем Ризй.]8): йЦр8://рсЬиЬ.сот/М1скет8ОЙ:/ри8Ь Гст р1и$рп. Арр1е Имейте в виду, что это не будет работать на устройствах Арр1е, но если вы хо- тите создать ризй-уведомления, проверьте платин ОпеЗц’па! Ссылка на докумен- тацию Опебтдпа! йпрз://опе81дпа1.сот/.
Глава 86 РеасШпе Синтаксис • соп51 геасШпе = гери1ге(' геасШпе') • геасШпе. с1озе() • геасШпе. раизе() • геасШпе. ргогррТ ([ргезегуеСигзог]) • геасШпе.рие8Г1оп(чиегу, саПЬаск) • геасШпе. гезип1е() • геасШпе зеТРготр1:(рготр1:) • геасШпе.йГ1Ье(Ьа1а[, кеу]) • геасШпе. с1еаг11пе(81геат, сНг) • геасШпе .с1еаг8сгееп0ойп(зггеап1) • геасШпе. с геа1е1п1егТасе( орг юпз) • геасШпе.сигзогТо(з1геэп1, х, у) • геаЫ]пс.еттЛКсургеззЕуегтЩз!геат[, хпЬегЕасе]) • геасИ1пе.пюуеСиг8ог(81геап, ах, бу) Примеры Построчное чтение файла сопзг Ез = гери1ге('Ез'); сопзЕ геаЛхпе = гери!ге('геасПхпе ); сопзГ г1 = геасШпе.сгеа1е!п1:егТасе({ хприЬ. Ез .сгеаЬеКеэс18(:геат(1 Тех! ЛхЕ') });
// Каждая новая сорока вызывает событие - каждый раз, когда поток по- лучает \г, \п или \г\п г1 .оп(' Ипе', (1±пе) => { сопзо1е.1од(11пе); }); г1.оп(‘сХозе1, () -> { сопзо1е.1од( Оопе геас11пд ТХХе ); // Файл поочитан }); Запрос ввода от пользователя через С1_1 соп81 геасШпе = геди1ге(' геасШпе') ; сопз! г1 = геас111пе.сгеаге1пгег'(:асе( { 1ПР1Л : ргосезз.5ГС11П, оиХриХ: ргосезз.зХдоиХ }); г1.диезгюп('иНат 1з уоиг пап^е?', (папе) => { солзоХе.Ход( НеХХо ${пате}!'); г!.с1озе(); });
Глава 87. Удаленная отладка в Мос1е.]$ Примеры Конфигурация запуска Модема Чтобы настроить удаленную отладку Мойера, просто запустите процесс побе с флагом -беЬид. Вы можете указать порт, на котором должен работать отладчик, используя --беЬид =<рогГ>. Когда ваш процесс Ыойе.р запустится, вы увидите сообщение: ОеЬоддег ИзГептд оп рогГ <рог!:> Это означает, что все настроено правильно. Затем насгройте цель удаленной отладки в вашем конкретном ЮЕ. Конфигурация 1пге11|Э/УУеЬ8(огт 1. Убедитесь, что плагин Мос1е.]з включен. 2. Выберите конфигурации запуска (скриншот). А Опп Тем? ж ► Ш* Гу ЕбК СопНдига(1оп$... * Кппатес! ь • Цпк Теиз ® ЗКеша се$<$ ЦТ иппатес! (е? Кетоге 3. Выберите + > Хос1е.]з КетоГе БеЬи§.
+ - а г - ▼ о А40 №» СопЛдигапоп Т Арр1е( « АррПсаиоп «1 Иа1П «В Спгопиит Кетой О Ооскег Оерюутет О ПгеГох Кетой * Сгип1.)$ * Си1р.)1 П Нсгоки 0ер1оутет 11 ,|АК Лрр1ю1<оп ЧкЯкаЬспр' ОеЬид О Махеп «а Мегеог * Мое На Моае-И . 1Чос1».л Кется» Оерид .Й ВоЗеипи |ЧЛ.]5 » йидт р Кето1е 9 5ру-^ А 5РУ-|5 Гог Мобе.л 4. Убедитесь, что вы указали выбранный выше порт, а также правильный хост. Когда все будет настроено, запустите цель отладки, как обычно, и она остано- вится на ваших точках останова. Кате Кетой V 5паге 5тд1е тиапсе оп(у Но1( 127 0 1 Рол 5859 ; Использование прокси для отладки через порт в Ыпих Если вы запускаете ваше приложение на Ыпих, используйте прокси для от- ладки через порт, например: зоеа! ТСР-И8ТЕМ :9958, Тогк ТСР:127.0.0.1 :5858 & Используйте порт 9958 для удаленной отладки.
Глава 88. Редшге() Введение В данной главе рассматривается использование оператора геритгеО, кото- рый включен в П'обе.)8. Рериэге представляет собой импорт определенных файлов или пакетов, ис- пользуемых с модулями Моберз. Он применяется для улучшения структуры кода и его использования серо 1геО применяется к файлам, которые установлены ло- кально, с прямым маршрутом ог файла, который использует героХгеО. Синтаксис • тойо1е ехрогЕз = {'Сез'СГопсгюп : СезсЕопсИоп}; • уаг 1ез1_Т11е = гери!ге(1 ./1ез1Р11е. ]з’); //Предположим, у нас есть файл с именем ТезТГПе • 1:ез1_1:11е.сезтсипсг1сп(оиг_баса); // Пусть в тезЕЕтХе есть функция 1ез1Еипс1топ Примечания Использование гери!геО позволяет структурировать код аналогично ис- пользованию классов и публичных методов в ]ауа. Если функция экспортирует- ся с помощью .ехрогтз, ее можно использовать в другом файле через гери!геО- Если файл не экспортируется, его нельзя использовать в другом файле. Примеры Начало использования гецшгеО с функцией и файлом Ре-риХге — это оператор, который Побе интерпретирует в некотором смысле как функцию получения (денег). Например, предположим, что у вас есть файл с именем апаТузтз. ] з. и втгутри этого файла содержится следующий код:
ГипсГюп апа1у7е1ЛеаГпег(йеаГГ|ег_с1эса) { сопзо1е.1од('ЙеаГбег 1пТогтаГ1оп Тог + леаГНег_баГа. Ггте + ': '); сопзо1е.1од( 'Ратп^аИ: ' + «еагбег_баГа ргесгр); сопзо1е.1од('ТетрегаГиге: ' + «еаГбег_баГа.Гетр), // Дополнительный анализ/вывод леагбег.баГа } Этот файл содержит только метод апе1у7е'ЛеаГЬег(иеатЬег_бата). Если мы хотим использовать данную функцию, ее необходимо либо использовать внутри этого файла, либо скопировать в файл, в котором она должна быть ис- пользована. Однако Хобе.)з предоставляет очень полезный инструмент для орга- низации кода и файлов — модули. Чтобы использовать нашу функцию, мы должны сначала экспортировать ее с помощью оператора в начале файла. Наш новый файл выглядит так: пюаи1е.ехрогГ8 = { апа]у/ейеаГ11ег: апа1у/ейеаГ1зег } ТипсГтоп апа1у2еИеаГ1зег(йеаГ(|ег_0а1а) { сопзо1е.1од( 'Меагбег тпГогтаГюп Гог + и1еаГ1зег_с1аГа .Гтте + '); сопзо1е.1од( Вахп-ГаП: + леаГИег_баГа.ргес!р;; сопзо1е.1од('ТетрегаГиге: ' + леа1Ьег_баГа.Гетр); // Дополнительный анализ/вывод леаГЬег.баГа.. } С этим небольшим оператором той и 1 е. ехрогГз наша функция теперь готова к использованию за пределами файла. Осталось только использовать геци1ге(). Когда используется гедыгеО для функции или файла, синтаксис очень схож. Обычно это делается в начале файла и присваивается переменным или констан- там для использования в течение всего файла. Например, у нас есть другой файл (на том же уровне, что и апа1уге ] з) с именем ЬапсТеИеаГЬег. ]з. который вы- глядит так: сопзГ апа1уз1з = гедо1ге('./апаТузтз.]з’); <меаГЬег_баГа = { Пше : 01 /01 /2001 ', ргесГр; 0.75, Гетр’ 78 // Дополнительные данные о погоде... }; апа1уз!з .апа1у2еИеаГпег(у/еаГ1зег_баГа); В этом файле мы используем гедиГгеО для захвата нашего файла апаТузтз. ] з. При использовании мы просто вызываем переменную или константу, при- своенную этому гедигге, и используем любую функцию внутри, которая была экспортирована.
Начало использования гецшге() с МРМ-пакетом Рейенге также очень полезен при использовании вместе с ^М-пакетом. Предположим, например, что вы хотите использовать КРМ-пакет в файле с име- нем детйеаПзег.]з. После установки вашего пакета через командную строку (прт 1пз1а1] гедаезТ) вы сможете его использовать. Ваш файл деПЛеаПзег . ] з может выглядеть так: уаг ГйТрз = гедитге('гедоез! ); // Сконструируйте переменную иг1... ИХТрз,деТ(ог1, ТипсЧоп(еггог, гезропзе, ЬоРу) { 1Т (еггог) { сопзо1е.1од(еггог); } е1зе { сопзо1е.1сд( Резропзе => ' + гезропзе); сопзо1е.1од(’Вору => ' + ЬоРу); } }); Когда этот файл выполняется, сначала используется геди!ге() (импортирует- ся) пакет, который вы только что установили, под названием гедиез!. Внутри файла гедиезТ есть множество функций, к которым теперь у вас есть доступ, одна из которых называется §еЕ В следующих нескольких строках эта функция используется для выполнения НТТР СЕТ-запроса.
Глава 89. РЕ8ТТи1 АР1: лучшие практики Примеры Обработка ошибок: ОЕТ всех ресурсов Как обрабатывать ошибки, а не просто локировать их в консоль? Плохой способ: Роихег.гоиТе('/') .деТ((геа, гез) => { Редиез1.ТХпс1((егг, г) => { 1Г(егг){ сопзоХе.Хсд(егг) } е1зе { гез.]зоп(г) } }) }) роз1((гед, гез) => { сопзХ гедиез! = пей Редиез1(( "Суре: гед.Ьос!у.1уре, ХпТо: гед.бобу.ХпТо }); гедиезб.ХпТо.изег = гед.изег._1б; сопзоХе.1од( АВООТ ТО 8АУЕ РЕ0ОЕ8Т", гедиезХ); гедиезб.зауе((егг, г) => { ХТ (егг) { гез.]зоп({ теззаде: 'Тбеге «аз ап еггог зауХпд уоиг г }); } е1зе { гез.}зоп(г);
} }); }); Лучший способ: РоиСег.гои!е('/') .де!((гед, гез, пехГ) => { РедиезС.Ггпб^егг, г) => { 1Т(егг){ соп8о1е.1од(егг) ) е1зе { геГигп пехГ(егг) ) }) В рсз!:((гед, гез, пех!) => { сопз! гедиезт = пел Редиезг({ Гуре: гед.Ообу.Гуре, 1пГо: гед.Ьобу.1пГо В; гедиезг.шГо.изег = гед. изег. _1с1; сопзо1е.1од("А80иТ 70 8АУЕ РЕ011Е87", гедиезС); гедиезГ.зауе((егг, г) => { 1Г (егг) { геГигп пехС(егг) } е!зе { гез.]зоп(г); } }); });
Глава 90. Структура Нои1е-СогПго11ег-8етсе для Ехрге§8.]$ Примеры Структура директорий Мо<1е18 КогНез-СопггоИегз-Зеплсез |—тоае1з | |—изег.тобе1.]з |—гои1ез | |--изег.гои1е.]з |—зегу!сез I I—изег.зегУ1се.]з |—сопггоИегз | |—и8ег.сопгго11ег.]5 Для модульной структуры кода логика должна быть разделена на следующие директории и файлы. • Мос!е18 — определение схемы модели. * РоиГез — АРЬмаршруты, которые «мапятся» на контроллеры. • СопТго 11е гз контроллеры, которыеобрабатываютвсюлогику, связанную с валидацией параметров запроса, отправкой ответов с правильными кодами. • Зегуьсез — сервисьг, которые содержат запросы к базе данных, возврат объектов или выброс ошибок. Такой подход требует написания большего объема кода. Но в конечном итоге код будет гораздо более поддерживаемым и разделенным.
Пример структуры кода Мос1е1-НоиГе5-Соп1го11ег8-8еплсе8 ияег.то(1е1.]8 уаг топдоозе = гедц!ге( 'топдоозе') сопз! ИзегЗсЬета = пе« топдоозе 8сЬета({ пате: 8!г1пд }) сопз! 11зег = топдоозе.тобе1(‘бзег', изегЗсЬ.ета) тоби]е.ехрог!з = изег; и8ег,гоше8.]8 уаг ехргезз = геди1ге( ехргезз’); уаг гои!ег = ехргезз.йои!ег(); уаг изегСоп!го11ег = геди1ге(' ../сопГгоПегз/изег ,соп!го11ег ’) гои!ег.де!( ’ , изегСопГгоПег.деЮзегз) тосЫе. ехрогГз = гои!ег; и8ег.сопгго11ег8.]8 уаг ПзегЗегу1се = геди!ге('../зегу!сез/изег.зегу!се’) ехрогГз.деШзегз = азупс ГипсТюп (гед. гез, пех!) { // УаХюате гедиез! рагатесегз, диегъез изтд ехргезз-уа11ба!ог уаг раде = гед.рагатз.раде 9 гео.рагатз.раде : 1; уаг Ит!! = гед. рагатз.11т1! ? гед.рагатз 11т1! : 10; Ггу { уаг изегз = а«а1! 11зе,г8егу!се.де!1!зегз({}, раде, Ипи!) ге!игп гез.з!а!из(2Й0),]зоп({ з!а!из: 200, Оа!а. изегз, теззаде: ЗиссезГиПу изегз Кегпеуед }); } са!сН (е) { гетит гез.зтагиз(400).]зоп({ зхатиз: 400, теззаде: е.теззаде }); } } и8ег,8еп>1се8.]8 уаг изег - геди1ге(/тосе1з/изег.побеГ) ехрсгТз.деТи.зегз = азупс ТипсПоп (оиегу, раде, 11т1Т) {
1гу { уаг изегз = аиаИ 11зег.Т1пд(диегу) гекигп изегз; } саксЬ (е) { // код Еггогз хНгол Еггог(‘ Еггог лИНе РадХпагюд Озегз') } }
Глава 91. Маршрутизация а]ах-запросов с помощью Ехргез8.]з Примеры Простая реализация АДАХ Для начала вам нужно использовать базовый шаблон ехргезз-депегаДог. В файле арр добавьте (можно добавить в любом месте после уз г арр = ехргезз.арр()): арр.розЧДТипсХюгДгед, гез, пех1:){ пех1() ; }); Теперь в вашем файле Апбех. ] з (или его соответствии) добавьте: гоигег.де1('/а]ах', Типспэп(^ед, гез){ г ез. гелс!е г (' а з ах ’, {Гй1е Ап Азах ЕхатрАе', дио1е: А.)АХ Аз дгеаГ!"}) ; }); гоиГег.розГ('/адах', ТипсГАогД гед, гез){ гез.гегкАег( 'адах1, {1АЛ1е: Аг А]ах Ехатр1е', диете: гед.Ьобу. диоЧе}); }); Создайте файл а]ах. ]абе / э)ах.род или а]ах.едз в каталоге /утеиз, до- бавьте: Для }асАе,Ри§]5: ехЧюпбз 1ауои1 зсгАрС(згс=1НГХр://сосе.]диегу.соп7)диегу-3.1.0.т1п.)з' ) зсг1рх(згс='/тадАс.]з ) Ы ОиоСе: !{диоге} Тогт(те10ос1= роз!" 10= сЬапдеОиоГе 1)
ториЦТуре=' Тех!', р1асеГю1Рег= ’ 8ет риосе оГ тИе аау', гате=’риоте') 1ПриТ('Туре="зиЬп11'Т , уа1ие= '8ауе") Для Е)8: <5сг1рс згс= ТтсТо://соРе.3риегу.сот/3риегу-3.1 .0.т1п.]5' ></зсг1рТ> <5СГ1р1 8ГС="/тад1С.]5 ></8СГ1рТ> ^Н1>0ио1е: <%=риосе%> </Н1> <Тогт теТЬоР- розТ" 1с1= с1запде0ио1е"> <1при1 гуре^ЧехТ р1асеЬо10ег="8е1: риоТе оТ гЬе Рау' пате="риоТе '/> <1при! Туре- зиЬтгт уа1ие=''8ауе"> </Тогт> Теперь создайте файл в каталоге /риЬИс с названием тадТс. ]з: $(РоситепТ).геаИу(Типе!Топ(){ $("ГогтЯсПапдеЗиоТе"),сп('зиЬттТ', ГипсТ1оп(е){ е р^еVеп^^е^:аи1(.(); уаг РэТа = $(' 1при1[пате=рио1:е] ).уа!() ; З.а]ах({ Туре: 'розТ', иг1: '/азах', РаТа: РэТа, РаТаТуре: ЧехТ’ }) . Ропе (ТипсИ оп (РаТа) { }); $( 'ЬГ ) .НТп11(Ра1:а.риоТе) ; }); }): Когда вы нажмете «Зауе». цитата изменится!
Глава 92. Запуск 1Чос1е.]8 как сервиса Введение В отличие ог многих веб-серверов, Мобе не установлен как служба по умол- чанию. Но в рабочей среде лучше запускать его как йаетоп, управляемый систе- мой инициализации. Примеры Моде .]8 как дзетой зуз^етд зу81 епй является стандартной системой инициализации в большинстве дис- трибутивов 1лпих. После настройки Мойе для работы с зузГетб можно использо- вать команду зегу!се для управления им. Прежде всего необходим конфигурационный файл, давайте создадим его. Для дистрибутивов на базе ВеЫап он будет находиться в /е1с/зуз1етй/зуз1:ет/побе. зегутсе [ОпИ] Оезсг1р11оп=Му зирег пойе]з арр | Зегуюе] # установить рабочий каталог для согласованности относительных путей 1,<огк1пдй1гесгогу=/уаг/,ллм7арр # запуск файла сервера (файл относительно Могк1пд01гес1:огу) Ехес81аг1=/изг/Ып/поое зегуегСйизГег.]з # если процесс аваэийно завершится, всегда пытаться перезапустить Резсатг=а1«уауз # задержка в 503 мс между аварийным завершением и перезапуском Рез1:агс8ес=500,п8 # отправка лога в зуз1од (не конфликтует с другими настрсйками логов в самом приложении)
51апбагбОитри1:=зуз1од ЗТапбагбЕггог-зузТод # имя процесса побе]з а зузЗод 8уз1од!с1еп1111ег=пос1е]з # пользователь и группа, запускающие приложение 11зег-мет.-с1аса 6гоир=»*и Рага # установка окружения (сем, ргоб_) Епу1гоптеп'1=1М0Е _ЕМУ=ргос1исНоп [1пз1а11] # запуск пос!е на уровне мультипользсвательской системы (= зузУтпИ гип1еуе1 3) УУап1:ес1Ву=ти1±1- изег ,1а г де! Теперь можно, соответственно, запускать, останавливать и перезапускать при- ложение с помощью: зегуюе побе зТаг! зегуюе пойе зТор зегуюе поое гезТаг! Чтобы указать зузТета автоматически запускать Хойе при загрузке, просто введите: зуз1еп1с1;1 елаЫе собе Теперь Мобе запускается как баетоп.
Глава 93. Обеспечение безопасности приложений Ыос1е.]8 Примеры Предотвращение межсайтовой подделки запроса (С8ПЕ) С8ВГ — это атака, при которой конечный пользователь вынужден выполнять нежелательные действия в веб-приложении, в котором оп в данный момент аутентифицирован. Это может произойти из-за того, что соокте отправляются с каждым запросом к веб-сайгу, даже если эти запросы поступают с другого сайта. Мы можем использовать модуль сзигТ для создания С5КЕ-токена и его вали- дации. Пример таг ехргезз = горитге( ехргезз') уаг соок!еРагзег = геси1ге(’соокте-рагзег') // для разбооа соокте уаг сзг! = геритге('сзигГ') // модуль сзгЕ уаг ЬобуРэгзег = геди1ге('Ьобу-рагзег') // для разбора тела запроса // настройка промежуточных маршрутов уаг сзгГРгоСесСтоп = сзгГ({ соокте Тгие }) уаг рагзеЕогт = ЬобуРагзег. иг!епсобеб( •{ ехГепбеР. ТаЕзе }) // создание приложения ехргезз уаг эрр = ехргезз() // разбор соокте арр.изе(соок1еРагзег()) арр д°1( ’/Гогт’, сзгЕРго^есиюп, Еипстюп(гер, гез) { // генерация и передача сзгГТокеп в представление
гез.гепбег('зегИ ’, { сзгТТокеп: гед.сзгГГокеп() }) }) арр.розГ('/ргосезз’, рэгзеЕогт, сзг^РготесТиоп, Тигс1:1оп(гер. гез) { гез.зепЩ ’баЕа 1з Ьетпд ргосеззеб) }) Таким образом, когда мы обращаемся к 6ЕТ /Тогт, это передаст СЗКЕ-токен сзгГГокеп в представление. Теперь, внутри представления установите значение сзгТТокеп как значение скрытого поля ввода с именем _сзгЕ. Пример для шаблонов НашПеЬагз: «Гост аст 1оп="/ргосезз тес1тэб="Р08Т"> <1приХ 1уре= Н1с1с!еп пате="_сзгЕ" уа1ое="{{сзг-(:Токеп)} > Иате : <1приС 1уре= СехТ пате= пате'> <ЬаССоп 1уре="зиРпи1: >8иЬт11:</Ьи1:1оп> </Гогт> Пример для шаблонов ]ас!е: Тогт(асГюп="/ргосезз” теМтоб=' роз!”) 1поиг(1'уре="К1с1с1еп , пате=”_сзгТ", \<а1ие=сзг Покеп) зрап Мате: 1поиГ(1уре="1ех1 , пате="пате”, гедотгеб=1гие) Ьг 1приС(1уре="зиЬт11: ) Пример для шаблонов Е]8: <Еогт асНоп= /ргосезз те1:Поб="Р08Т"> <1при1: Гуре= ПкТбеп пате="_сзгГ" уа!ое- <%= сзгГТокеп %> > Иаше: <1при1 1уре='1ех1: пате= пате > «ЬоИоп 1уре="зиЬтдЛ">8иЬт11</Ьи11оп> </Еогт> 58Ь/ТЬ8 в Мос1е.]8 Если вы хотите иметь возможность управлять $81/11,8 в вашем приложении на 1Чос1е.]8, примите во внимание, что вы также песете ответственность за пре- дотвращение атак 88Е/ТЕ5 на этом этапе. В многих архитектурах «клиент — сер- вер» 88ЦТЕ8 завершается на обратном прокси-сервере, чтобы уменьшить слож- ность приложения и снизить объем настроек безопасности. Если ваше приложение на Хо(1е.]8 должно обрабатывать 88Е/ТЕ8, его можно обезопасить, загрузив файлы ключей и сертификатов.
Если ваш провайдер сертификатов требует цепочку сертификатов удостоверя- ющего центра (СА), она может быть добавлена в параметр СЛ как массив. Цепоч- ка с несколькими заштсями в одном файле должна быть разделена на несколь- ко файлов и введена в том же порядке в массиве, поскольку Х’о(1е.)з в настоящее время не поддерживает несколько записей СА в одном файле. Пример приведен в коде ниже для файлов 1_са.сгс и 2_са.сгЕ Если массив СА требуется и не настро- ен правильно, браузеры клиентов могут отображать сообщения о невозможно- сти проверки подлинности сертификата. Пример сопзЕ ГтЕЕрз = геро1ге( КЕгрз ); сопзЕ Ез = геди!ге('Тз’); сопзЕ орЕтопз = { кеу: Ез.геабЕ11е8упс('ргг7асекеу рет'), сегЕ: Ез. геабЕПе8упс( ’сегЕтЕтсаЕе.рет'), са: [Ез.геабЕ11е8упс( 1_са.сгЕ’), Ез.геабЕт1е8упс('2_са.сгЕ') ] }; ЬГЕрз.сгеаЕе8егуег(эрЕ1опз, (гед, гез) => { гез.иг1ЕеНеаб(200); гез.епб('Не11о ‘лог1б\п’); }) ,118Ееп(е000); Использование НТТР8 Минимальная настройка НТТР8-сервера в Гч’одецз выглядит следующим об- разом: сопзЕ ИЕЕрз = геритге( ИЕтрз'); сопзЕ Ез = гедихге('Ез'); сопзЕ ЬЕЕрзОрЕтопз = { кеу: Ез.геабЕ11е8упс('раЕН/Ео/зегуег-кеу рет'), сегЕ: Ез. геабЕИе8упс( раЕб/Еэ/зегеег-сгЕ рет') }; сопзЕ арр = ЕипсЕюп (гед, гез) { гез.иг1ЕеНеаб(200); гез.епб(1бе11о *ог!б\п"); } бТЕрз.сгеаЕеЗег л/ег(бЕЕрзОрЕтопз, арр).11зЕеп(4433) ; Если вы также хотите поддерживать НТТР-запросы, вам нужно внести не- большое изменение: сопзЕ бЕЕр = геди1ге('бТЕр'); сопзЕ бЕтрз = гери1ге( бтсрз'); сопзЕ Ез = геди!ге( Ез');
сопз! ИНрзСрГюпз = { кеу Гз. геас1Р11е5упс( 'ратб/бо/зегуег-кеу.рет'), сегС: Тз геасЕ11е8упс( ра1:п/1о/зегУег-сгГ.рет') У; сопз! арр = ТипсТиог. (гея, гез) { гез .лг1СеНеас1(200); гез.епЩ Пе11о лог1с1\п 1); } ИЩр.сгеа!е8ег\/ег(арр). 11згеп(8886); ЬИрз.сгеа1е8егуег(Ы1:рз0р1:1опб, арр) .1лз!еп(4433); Настройка НТТРЗ-сервера Как только вы установите Мос1е.]8, выполните следующую процедуру, чтобы запустить базовый веб-сервер с поддержкой как НТТР, так и НТТР8. Шаг 1. Создайте центр сертификации Создайте папку, где вы будете хранить ключ и сертификат: шксНг сопЕ Перейдите в этот каталог: сб сопГ Скачайте файл са. сгтЕ для использования в качестве кон фиту рационного ша- блона: \«де! ИПоз: / /гаи.дтЛИибизегсогйепС .сот/апбегз94/ГП!:рз- асйбопгес!- сИегйз/тазСег/кеуз/са .спТ Создайте новый центр сертификации с использованием этой конфигурации: орепзз! гед -пе’л -х509 -бауз 9999 -сопСтд са.спС -кеуои! са-кеу.реш -ой! са-сегТ.реш Теперь, когда у нас есть центр сертификации в файлах са-кеу. рет и са-сегС. рет, давайте создадим приватный ключ для сервера. орепзз! депгза -ои! кеу.рет 4096 Скачайте файл зегуег .спТ для использования в качестве конфигурационно- го шаблона; лде! Шрз ://га«.д1П1оЬизегсоп1еп1:.сот/апдегз94/Ы1:р8-аи'111ог17ед- сИепСз/тазСег/кеуз/зегуег .спТ
Создайте запрос на подпись сертификата, используя эту конфшурацию: ореп551 гец -пем -соп(1д зегуег.спТ -кеу кеу.рет -оит саг рет Подпишите запрос орепзз! х5й9 -гед -ехТТПе зегуег.спТ -бауз 999 -раззш "раззграззтогсГ -1п сзг.рет -СА са-сегТ оет -САкеу са-кеу рет -САсгеаТезепа! -оиС сегг рет Шаг 2. Установите свой сертификат в качестве корневого Скопируйте ваш сертификат в папку' с корневыми сертификатами: зис1с ср са-сегт.рет /езг/ТосаТ/зпаге/са-сегЩТТсаСез/са-сегТ.рет Обновите хранилище сертификатов СА: зибо ирбаТе-са-сегТ1Г1саТез Защита приложения на ехргезз. )з 3 Конфигурация для создания защищенного соединения с использованием ехргезз.]’з (с версии 3): уаг Тз - геди1ге(’Тз’); уаг Кттр = гедихге( бТСр); уаг КтТрз = геаи!ге(‘бттрз ’); уаг ргТуабеКеу = Тз.геабЕ11е8упс('зз1сег1/зегуег.кеу , 'о1Т8'); уаг сегНТтсаТе = Тз. геас1Р11е8упс(' зз1сегТ/зегуег .сП ’, 'иСТ8'); // Определите ваш ключ и сертификат уаг сгес1епт1а1з = {кеу: рг1уасеКеу, сегТ: сегпТюате}; уаг ехргезз = гедитге('ехргезз'); уаг арр = ехргезз(); // ваша конфигурация ехргезз здесь уаг ЬТТрЗегуег = бТТр.сгеаТе8егуег(арр); уаг ЫЛрзЗегуег = бтсрз.сгеа1е8егуег(сгебепТ1а1з, арр); // Использование порта 8080 для КСср и 8443 для МТТрз бттрЗегуег.11зтеп(8380); бСсрз8егуег.11зТеп(8443) ; Таким образом вы обеспечиваете работу ттбЛеиаге ехргезз на нативных серверах ЫТр/ЫТрз. Если вы хотите, чтобы ваше приложение работало на портах ниже 1024, вам нужно использовать команду зш1о (не рекомендуется) или обратный прокси-сер- вер (например, пдшх, Картоху).
Глава 94. Отправка веб-уведомлений Примеры Отправка веб-уведомления с использованием БСМ (6оод1е С1оиб Меззадтд 5уз!ет) Такой пример широко известен среди РША (прогрессивных веб-приложений), и в этом примере мы собираемся отправить простое уведомление с помощью Ыос1е.]8 и Е86. 1. Установите модуль Ыобе-ССМ: прт 1пе1а11 побе дет 2. Установите Зоскейю: прт 1пЫа11 зоскей.ю 3. Создайте приложение с поддержкой ССМ, используя Соо^1е Сопчо1е. 4. Получите ваш ССМ АррПсайоп Ш (он понадобится позже). 5. Получите ваш секретный код приложения ССМ. б. Откройте ваш любимый редактор кода и добавьте следующий код: 'озе 81Г1С1'; сопзй ехргезз = гедс1ге('ехргезз’); сопз! аор = ехргезз(); сопзй дет = гедо1ге( побе-дет'); арр.ю = гедо1ге( зоскеС.ю')(); // [*] Настраиваем наш бСМ-канал. сопз! зепбег = пел дст.3епбег( Ргодес! Зесгей'); сопзй гедТокепз = []; 1ег теззаде = пей дст.Меззаде({ баса: { кеу1: 'тзд1
) }); // [*] Настраиваем статические файлы. арр озе(ехргезз. зга11с('роЫю/')); // [*] Настраиваем маршруты. аор.дет('/', (гер, гее) => { гез.зепбЕ11е(__сНглате + '/риЫ1С/1пс1ех .КТтГ ); }); // [»] Настраиваем соединение через Зоскет. арр.ю.оп('соппесНоп', зоске! => { сопзо1е.1од( ’ле Пахе а пел соппесЕюп ...’); зоскеС,оп('пел_изег', (гед_1б) => { // [*] Добавляем регистрационный токен уведомлений пользовате- ля в наш список, обычно // скрытый в безопасном месте. 1Т (гедТокепз.1пбехОТ(гед„1с1) === -1) { гедТокепз.ризб(гед_1б); // [*] Отправляем розб-уведомления зепбег.зепсЦтеззаде, { гед1зЕга11опТокепз гедТокепз }, (егг, гезропзе) => { 1Т (егг) сопзо1е.еггог('егг', егг); е1зе сопзо1е.1од(гезропзе); }); } }) }); тобиЗе.ехрсгЕз = арр; Р5: Здесь мы использовали специальный хак, чтобы ЗсскеС. 1о работал с Ехргезз, потому чго просто так он не работает. Теперь создайте дзоп-файл и назовите его МаптЕезД.дзоп. откройте его и вставьте следующее: { пате1: Арр11саЕюп Мате", дст_зепс1ег_10 1 : ССМ РгодесТ Ю } Закройте файл и сохраните его в корневом каталоге вашего приложения. Р8: Файл МапТТезт. дзоп должен находиться в корневом каталоге, иначе он не будет работать. В приведенном выше коде мы сделали следующее:
1. Настроили и отправили обычную страницу 1паех. Н1т1, которая также будет использовать зоскеТЛо Слушали событие подключения, которое запускается с фронтенда, то есть с нашей страницы тпбех.бтт! (оно будет запущено, как только новый клиент успешно подключится к нашему предопределенному адресу). 2. Отправили специальный токен, известный как регистрационный токен, с нашей страницы дпбех ЬТт! через событие зоскег.то пем_изег. Этот токен будет уникальным кодом доступа пользователя, и каждый код обычно генерируется поддерживающим браузером для АР1 веб-уведомлений (читайте больше здесь: Ьпр?://с1есе1орег.то7Ша.ог§,'еп-и8/с1ос5/\УеЬ/АР!/ Моййсайоп). 3. Использовали модуль побе-дст для отправки нашею уведомления, которое будет обработано и показано позже с использованием Зеплсе \Уогкег8. Р8: Полный рабочий пример вы можете найти здесь: Ьпр8:,7ргйиЬ.сот/ йои88ет-уай1аои1.'ргойге8МУе-мгеЬ-арр-81агГег-кй.
Глава 95. Отправка файлового потока клиенту Примеры Использование Тз и р!ре для потоковой передачи статических файлов с сервера Хороший сервис УОО (У1с1ео Оп Бетапй) должен начинаться с основ. Допу- стим, у вас есть каталог на сервере, кот орый не доступен публично, но через не- который портал или платный доступ вы хотите разрешить пользователям до- ступ к вашим медиафайлам: уаг тоуТе = ратИ. гезо1уе( ‘ ./роЫтс/' + гед.рагатз.ТНепате); Ез.зТаЦтоухе, 10001100 (егг зсасз) { уаг гаоде = гед. Ьеас1егз. гапде; 1Г (! гаоде) { геТшгп гез.зепс!81:аЮз(416); } // Логика для фрагментов (чанков) уаг розхМопз = гапде.гер1асе(/Ьу1ез=/, "").зр11Т("-"); уаг зТагТ = рагзе1пГ(роз111спз[0] 10); уаг Со1:а1 = зТаТз.зтге; уаг епб = роз11юпз[1] ? рагзеТп1:(роз1Г1олз|'1 ], 10) : 1с1а1 - 1; уаг сЬоокзтге - (еоб - зСагх) + 1; гез.иг11еНеас1(206, { 'ТгаозТег-Еособтпд' : с1типкес1', 'СооТепТ-Папде : "ЬуСез ' + зТагТ + + епб + ' /" + 1оТа1, 'АссерТ-Рапдез : "ЬуТез", "СооТепКеодИт': сЬопкзтге, "СооТепГ Туре : пите 1оскор(гед.рагатз. ТПепате) }); уаг з^геат = Тз.сгеаТеРеабЗТгеапДтоуте, { зЬаги: зТагТ, епс1: еоб, аиТоСТозе: Сгие }) .оо('епсГ, ТипсТтоп () {
сопзоТе 1од('81геат Соте ); }) .оп( еггог1, ТипсЕюп (егг) { гез.епс1(егг); }) ,Р1ре(гез, ( епд: Тгие }); }); Приведенный выше пример — это базовый план, как можно передавать ви- део клиенту. Логика для фрагментов зависит от множества факторов, включая сетевой график и задержки. Важно сбалансировать размер фрагментов и их ко- личество. Наконец, вызов ргре дает понят]. Мобе.)з. что необходимо поддерживать соеди- нение с сервером открытым и отправлять дополнительные фрагменты по мере необходимости. Потоковая передача с использованием ПиепТ-Итред Вы также можете использовать ПиепМТшре§ для конвертации файлов ,шр4 в .Пу или другие форматы: гез.соп1:еп4Туре( 'Ну' ) ; уаг ра(±ТоМоу1е = './риЬИс/' + гед.рагатз. Н1егате; уаг ргос = ТТтред(раСЬТоМоУзе) .ргезе-Ц 'Т1азЬу1бес') ,оп('епб , ГипсИоп () { сопзо1е.1од( Зтгеат Сопе'); }) .оп('еггог', ТипсНоп (егг) { сопзо1е.]од( ап еггог баррелей: +• егг.теззаде); гез.зепсЦегг.теззаде); }) .р1ре(гез, { епб: Ггие })•
Глава 96. 8едие1|2е.]8 Примеры Установка Убедитесь, что у вас установлены Мос1е.)8 и МРМ. Затем установите зедие112е.]з с помощью : прт 1пз1а11 --зауе зериеНге Также вам нужно установить модули Мо(1е.]'з для поддерживаемых баз дан- ных. Вам следует установить только тот модуль, который вы используете. Для Му8фЬ и МапаВВ: прт тпзСаИ --зауе тузр1 Для РозГ§ге8рЬ: прт тпзСаИ --зауе рд рд-Рзсоге Для 891.йе: прт тпзТаН --зауе здИ^е Для М88(Д: прт тпзТаП --зауе СеРхоиз Как только вы установили все необходимое, вы можете подключить и создать новый экземпляр Зерпсйге следующим образом. Синтаксис Е85: уаг ЗериеИге = гедо!ге(' зедиеПге ); уаг зерие112е = пей 8ерие112с('РаТабазе’, 'изегпате', ’раззиогсГ); Синтаксис Е86 с ВаЬе1 зтаде-О: ттрсгС ЗедиеИге Тгот ‘зедиеИге ,
сопзС зеяие117е = пел 8ерие112е('сатаЬазе', изегпате', 'раззлогсГ ); Теперь у вас есть экземп.тяр ЗециеП/е, доступный для использования. Вы мо- жете назвать его по-другому, если хотите. например: уаг оЬ = пе« Зерое112е('баТабазе’, изегпаше , ’раззиогсГ ); или уаг батаЬазе = пел 8ерое112е(’оагаоазе', озегпгте , 'раззиога’); Эта часть — на ваше усмотрение. После установки вы можете использовать его в своем приложении в соответствии с документацией АР1 (1Шрз://зецие112е. от^/уЗ/арь'зедиейге/). Следующий шаг после установки — создание вашей собственной модели. Подробнее об этом можно узнать, перейдя по ссылке: йПр://бос8.8едие112е|8.сот/ еп/\'3/(1ос8/2еГйп§-81аг1е(1/'#уоиг-йг81-то(1е1. Определение моделей Существует два способа определения моделей в Зециейге: с помощью зерие112е . беГ1пе(...) или зериеНге. 1трогс (.. .). Обе функции возвраща- ют объект модели ЗедиеИге.
1. 8е^1^е^^7,е.с^ерпе(то(^еI^ате, аОгИлИез, [орИопз]) Этот способ подходит, если вы хотите определить все свои модели в одном файле или иметь дополнительный контроль над определением модели. /* Инициализация 5едие11ге */ сопз! сопТ1д = { изегпате: багаЬазе изегпате", раззиогб: ба!аЬазе разз'логб", багайэзе' багаОазе пате , Ьоз1; басаЬазе'з НозС ОРИ", бгаХесг: тузд1 // Другие варианты: розГдгез, зд1л1е, тагтабЬ, тззд1. } 9аг 8едие11ге = гедигге("зедиеНге"); уаг зедиеНге = пей 8едие1лхе(сопТ1д); /* Определение моделей */ 5едие11хе.беНпе('МуМобе!", { пате: 8едие11хе.37К1М6, соттепг: ЗедиеИхе .ТЕХТ, баге: { Туре: ЗедиеИхе. ОАТЕ, аИолМиП. Та1зе } }); Дополнительную информацию и другие примеры можно найти в документа- ции по бос1е(з: 1шр8://бос1ец.1о/ или в документации зедпеПге.сот: йЦрз^/зедиейге.огй/уЗ/босз/тобе^- бе&пйоп/.
2. 5едиеИгелтрог1(рагИ) Если ваши определения моделей разбиты на отдельные файлы, то ме- тод 1трог1: будет вам чрезвычайно полезен. В файле, где вы инициализируете ЗеоиеИге, вызовите ппрог! следующим образом: /* Инициализация ЗедоеНге */ //См предыдущий примео кода для инициализации /* Определение моделей */ зедиеИгеЛтрогЦ '. /тобе1з/ту_тобе1.]з ); // Путь может быть относи- тельным или абсолютным В ваших файлах определения модели код будет' выглядеть следующим образом’ пюс1и1е.ехрог1:8 = Типс1:1оп(зедие112е. ОаТаТурез) { геГогп зецие112е.беГ1пе("МуМоае1", { пате1 ОаГаТурез 8ТН1М6, сотшепт: ОаЕаТурез.ТЕХТ, с!а1е { Туре: ОаТэТурез.САТЕ, а11оиМи11: Га1зе } }); };
Глава 97. Простой СР1Ю АР1 на основе РЕ8Т Примеры РЕ8Т АР1 для СР1Ю в Ехргезз 3+ уаг ехргезз = гери!ге( ехргезз'), ЬэйуРагзег = гери1ге("Ьсйу-рэгзег ), зегуег = ехргезз(); // Ьос1у рагзег для парсинга тела запроса зегуег ,изе(Ьос1уРагзегзоп()); зегуег.изе(Ьос1уРаг5ег.иг1епсобес1({ ехТепс1ес1: Ние })); // временное хранилище для Нет в памяти уаг 1гет8соге = []; // Получение всех элементов зегуег,деТ('/Нет', ТипсТТоп (гед, гез) { гез. 1зоп(1Тет81оге); }); // Получение элемента с указанным 16 зегуег. деГ( ‘/Нет./: , Типе с зоп (гед, гез) { гез. 1 зоп (ИетЗТоге [ гер. ра гатз. Ю ]) ; }); // Добавление нового элемента зегуег.розТ('/Нет’, ТипсТюп (гед, гез) { НетЗТоге.риз1т( гес.ЬоСу); гез.]зоп(гер.Ьос1у); });
// Обновление элемента по указанному 16 зегуег.ри1( '/11еп/: 16' , ГипсИоп (гед, гез) { НетЗГоге!гед.рагатз.16] = гед.Ьооу гез.]зоп(гед.Ьо6у); }): // Удаление элемента с указанным 16 зегуег.6е1е1е('/11ет/:ю', Гипс1юп (гед, гез) { 11ет31оге.8р11се(гед.рагатз.16. 1) гез.]зоп(гед.Ьо6у); }); // Запуск сервера зегуег. 11зТеп(30й0, ТипсНоп () { сопзо1е.1од(, Зегуег гиппХпд"); })
Глава 98. Связь через 8оске1.ю Примеры «Не11о могМ!» с сообщениями через сокеты Установка модулей Ыобе^з: прт тпзТаП ехргезз прт хпзСаП зоскеС 1с Сервер на Ко(1е.)з сопз{ ехргезз = гедтге('ехргезз'); сопзС арр = ехргезз(); сопзг зегуег = арр.11зсеп(3000, сопзо1е.1од(1 8оске1.ю Не11о Йог1с1 зегуег зГагсесН")); сопзС 1о = геди!ге(' зоскеТ .ю') (зегуег); ю.оп('соппесгюп', (зоскеС) => { // сопзо]е.1од('СЗхепТ соппесСед!"); зоске-с.оп( теззаде-Сгот-сИепТ-ю-зегуег', (тзд) => { сопзо1е.1сд(тзд); }) зоскеС.етП:('теззаде-Тгот-зегуег-ио-сллепг , 'Не11о Йог1с1! ’); }); Браузерный клиент <1ООСТУРЕ Ып11> <Ьгт1 1апд=' еп > <1пеас1> <те!а сЬагзе1:= с1Тр-8'‘> <[111е>Не11о йог1о Л11П ЗоскеС. 10</Т11:1е> </Ьеас1> <Ьос1у>
<зсг1р! зге* Ит1рз://сйп.зоскег.1о/зоске1.1о-1 4.5.]3 "></8СГ1р1> <ЗСГ1р1> уаг зоске! = 1о(1 КИр://1оса1Ьоз1:3000 '); зоске! .оп( "теззаде-Ггоп-зегуег-Хо-сИеп! , 1ипс11оп(тзд) { йосипегл . дегЕ1етеп1Ву1<1( теззаде'). тпегнТМк. = тзд; }); зоске1.еп11( ‘ теззаде-^гот-сИепГ-Ю-зегуег', 'Не11о Йог1<1!'); </зсг!р1> <р>8оске1.ю НеИо У/ог1с1 с11еп1 З1аг1:ес11 </р> <р 1с1= теззаде"></р> < / Ьос1у > </Ыт1>
Глава 99. Синхронное и асинхронное программирование в Ыос1е.]8 Примеры Использованиеазупс Пакет азупс предоставляет функции для асинхронного кода. С помощью функции аиго можно определить асинхронные отношения меж- ду двумя или более функциями: уаг азупс = геди!ге('азупс'); азупс.аи!о({ дет_с1а1а: Типе! юп(саПЬаск) { сопзо1е.1од('1п де!_Оа!а’), // асинхронный код для получения данных саПЬаск(пи11, 'с1ата , ' сопуегтес! то аггау ); }. гчаке_То1с1ег: Типс!1оп(саПЬаск) { сопзо1е . 1од(' 1п таке_То1с1ег ’); // асинхронный код для создания директории для хранения файла // выполняется одновременно с получением данных саНЬаск(па11, 'То1с1ег'); }, *г1Те_ТПе: [1дег.ЬаТа', таке_То1с!ег', ТипсТ1оп(гези1Тз, саНЬаск) { сопзо1е. 1од(' 1п иг1Те_Т11е', ^04.зТг1пд1Ту(гезиНз)); // как только данные будут получены и директория будет создана, // записываем данные в файл в директории саНЬасЦпиН, ТНепате'); И, етаН-Ипк: ['иг1!е_Т11е , Типс!юг( гезиИз, саНЬаск) { сопзо1е. 1од(' 1П ешаН_Нпк', ^СИ.зТг1пд1Ту(гезиНз));
// после того как файл записан, отправим ссылку на него пс электронной почте... // гезиИз.лгхте.ТПе содержит имя файла, -озвращаемое функ- цией «1Г11:е_Т’11е. са11Ьаск(пи11, {’Т1]е' : гезиИз .йГ11е_Т11е, енат!1 : 'изег@ ехатр1е.сот'}); }] }, Гипс1юп(егг, гезаПз) { сопзо1е.1од('егг = ', егг); сопзо1е.1од( гези1тз = ', гезиПз); }); Этот код мог бы быть выполнен синхронно. просто путем вызова де!_с1а1а, таке_То!с1ег, игПе.ГПе и ета11_11пк в правильном порядке. Азупс отслежи- вает результаты за вас. и если произошла ошибка (первый параметр саПЬаск не равен пи! 1), выполнение остальных функций прекращается.
Глава 100. ТСР-сокеты Примеры Простой ТСР-сервер // Подключение модуля пе! Исс1е ]з сопзТ Мег = геди1ге('пе!'); // Порт, на котором сервер прослушивает. сопзТ рог! = 8080 // Используйте пет .сгеаТе8егуег() в вашем коде. Зто тслькс для гримера. // Создание нового ТСр-сервера. сопзТ зегуег = пей/ №1 8егуег(); // Сервер слушает сокет для получения запроса на подключение от клиента // Сокет можно представить как конечную точку. зегуег.11з1еп(рогТ, Гипс1:1оп() { сопзо1е.1од( Зегуег 11з1еп1пд Тог соппестюл гедиезтз оп зоскеТ 1оса1Ьозт:${рогт}.'); }); // Когда клиент запрашивает соединение с сервером, сервер создает новый // сокет, предназначенный для этого клиента зегуег.оп( 'соппестюп’, Типс1:1оп(зоске1:) { сопзо!е.1од( 'А пел соппесИоп Паз Ьееп ез1аЫ1з1лес1. '); // Теперь, когда ТСР-соединение установлено, сервер может отпра- вить данные // клиенту, записав их в его сокел. зоске!.иг11:е( 'Не11о, с11еп1.');
// Сервер также может получать данные от клиента, читая из его сокета, зоскег оп('оаСа', ГипсГ1оп(сЬипк) { соп8о1е.1сд( ОаГа гесегуеб Ггот с11еп! : ${сЬипк ,1:о8(.г1пд()}. ); }); // Когда клиент запрашивает завершение ТСР-соединения с сервером, сервер // завершает соединение. зоскеТ ,оп( 'епсГ , Типс1юп() { сопзо1е.1од( С1оз1пд соппесИоп лИЬ тНе с11еп1’); }); // Не забудьте обработать ошибки для вашего же блага. зоскеИ оп('еггог ГипсПсп(егг) { сопзоТе 1од(’Еггог' ${егг}‘); }); }); Простой ТСР-клиент // Подключение модуля пе! Мобе.]5 сопз! №1 = геди1ге( ‘пе1'); // Номер порта и имя хоста сервера. сопзГ рог! = 8080; сопз! ПозТ = ' 1оса11?о81: ‘ ; // Создание нового 7СР-клиента. сопз! с11еп1 = пел №1 .ЗоскеЦ); // Отправка запроса на соединение серверу. сИепС.соппес1({ рогГ: рог!, Козе: НозС }, Типс11оп() { // Если ошибки нет, сервер принял запрос и создал новый // сокет, предназначенный для нас. соп5о1е.1од( ’ТСР соппесИоп ез1аЫ18Ьеб т1?е зегуег.’); // Клиент теперь может отправить данные сеэверу, записав их в свой сокет. сИепС .иг1Се(' Не11о, зегуег.'); }); // Клиент также может получать данные от сервера, читая из своего сокета.
с11епг ,оп( 'ааГа', Гипсеюп(сЬипк) { сопзоХе.1од(’Оаеа гесегуес! Ггот ГЬе зегуег: ${сЬипк.1оЗгппд()}. '); // Запрос завершения соединения после получения данных. с11епГ .епЩ); }); с11епс.оп(’епс!’, ГипсМоп() { сопзо1е.1од( РедиезГео ап епа го гГ.е ТСР соппесгГоп‘; });
Глава 101. Шаблонные фреймворки Примеры Ыигуискз Серверный движок с поддержкой наследования блоков, автоматическим экранированием, макросами, асинхронным управлением и многим другим. Его создатели вдохновлялись )пца2, и он очень похож на Тууц* (рЬр). Документация — ЬПр://то2111а.81ГйиЬло/пип]искз/. Установка — прт 1 пип]искз. Ниже приведен пример базового использования с Ехргезз. арр.]8 уаг ехргезз = геси!ге('ехргезз'); уаг пипзискз = геди!ге('пипзискз'); уаг аро = ехргезз(); арр. изе(ехргезз. з1аР1с(' /риоИс')); // Применяем пипдискз и добавляем пользовательский фильтр и функцию (например).
уаг епу = пьп]искз.сопЕ1диге(['у!еиз/’ ], { // устанавливаем папки с ша- блонами аисоезсаре: ггие, ехргезз: арр }): епу.асИЕ111ег(' туГШег ’, Гипс11оп(оЬ], агд1, агд2) { сопзо1е.1од( 'туЕШег', оЬ], агд1, агд2); // Делать что-то с оЬд гетигп оЬ]; }); спу . ас!с1С1оЬа1 (' гпуЕипс , Гипс1иоп(оЬ], агд1) { сопео1е.1од('туЕипс', оЬ], агд1); // Делать что-то с оЬ] геРигп оР]; }); арр.дет('/', Типссюп( гед. гез){ гез.гелс1ег(' 1пс1ех .ЫтГ , {1111е: 'Матп раде'}), }); арр.дет('/Тоо', Типсгюп(гед, гез){ гез. 1оса1з. зпгсЬ^/аг = ТЕиз 1з ЗраПа!1, гез.гепс1ег( ^оо.ПЕго! , {ИИе: 'Роо раде'}); }); арр. 11з1еп(3000, ГипсИопО { сопзо1е.1од( 'ЕхапрТе арр Из^егапд оп рог1 3060 ..'); }); Ме«8/ш(1 ех.Ь (ш! <П1т1> <1пеаб> <1111е>Мип]искз ехатр1е</1111е> </1пеас1> <ооау> {% Ыоск сопгеп! %} {{Ш1е}} {% елбЫоск %} </Ьос1у>
Мип]иск5 419 Мемгз/Гоо.Мш! {% ех1епс15 "1пс1ех.Ы:т1" %} {# Это комментарий #} {% Ыоск соптепт %} <И1>{{Пг1е}}</Ь1> {# применяем пользовательскую функцию и затем встроенные и пользо- вательские фильтры #} {{ гоуЕипс(5т1:11Уаг) | 1о^ег | туЕ111ег(5, 'аЬс') }} {% епс!э1оск
Глава 102. Удаление Ыос1е.]§ Примеры Полное удаление Мос1е.]5 на Мас О8Х В терминале на операционной системе Мас введите следующие две команды: 1еЬст -Т -1 -8 -рТ /уаг/РЬ/гесегргз/огд.псйезз.ркд.Ьот | иЬ11е геас Т; ао зиРо гт /и8г/1оса1/${Т}; Ропе 8иРо гт -гГ /и8г/1оса1/11Ь/поОе /и8г71оса1/11Ь/поОе_тоРи1е8 /уаг/РЬ/ гесегр18/огд.побе]8.* Удаление Мос1е.]5 на Чтобы удалить Ыос1е.]8 на У/шс1оуу8, используйте «Установка и удаление про- грамм» следующим образом: 1. Откройте «Установка и удаление программ» через меню «Пуск». 2. Найдите Мойе.]8. АЛГтйои'810: 3. Нажмите на .\ойе.]8. 4. Нажмите -Удалить». 5. Нажмите новую кнопку «Удалить». МГшйоуув 7-8.1: 6. Нажмите кнопку «Удалить» под 1мос1е.]8.
Глава 103. Фреймворки для модульного тестирования Примеры МосНа синхронный (Зезсг1Ье(' 8и11е Мате’, Типс11оп() { с!езсг 1Ье(‘#тегЬос1 () ’, Типс1юп() { ' зНоиЗб гип «ЗЛИои! ап еггог’, Типс11оп() { ехрес!([ 1, 2, 3 ] ,1епд1:Ь) .10 .Ье.едиа3.(3) }) }) }) МосНа асинхронный (саПЬаск) уаг ехрес! = геди3.ге( "сНаЗ").ехрес!; с1езспЬе( '8иПе Иате' Типс11сп() { сЗезсг 1Ье( '#тетНос1 ()', ТипсГюпО { 31(' зПоиЮ гип у/11Пои1 ап еггог', 1ипсНоп(с1опе) { Еез18о,пе1Н1пд(егг => { ехресЦегг) Ло.по! ,Ье едиа1(пи11) Оопе() }) }) }) }) МосНа асинхронный (Ргопизе) с1езсгЮе( 'Зите Мате’. Гипс11оп() { с1езспЬе( #те1Ьос1()', 1ипс11оп() {
и(' 51тои1с1 гип «ХтИоиХ ап еггог ТипсХюп() { геХигп Рс8отеХП1пд(),ХПеп(гези1Х => { ехресХ(гезиХХ). 1о.Ье.едиа1( 'ИеИо «уогХсГ ) }) }) }) }) МосЬа асинхронный (азупс/аиай) сопзХ { ехресХ } = геси!ге(’с1та1’) дезсг1Ье('8и1Хе Мате', ХипсХюп() { аезсг1Ье(‘#теХНос1() ’, Хипсхюп() { 1Х(’зЬои1с1 гип игХИоиХ ап еггог’, азупс ГипсХ1оп() { сопз! гези1Х = а^ахХ ап8«егТоТНе(Л11таХе0ие811оп() ехресЦгезиИ) ,то.Ье.еаиа1(42) }) }) })
Глава 104. Сценарии использования Мойере Примеры НТТР-сервер сопзХ Ы1р = гедихге( 'ЬтХр'); сопзоТе.1од('Згаг11рд зегуег...'); уаг солГхд = { рог!: 80. сопЧгепТТуре арр11сатюп/]зоп; сНагзе1=и1Т-8' }; // Й80М-АР1 сервер на порту 80 уаг зегуег = 1и1р,сгеаГе8егуег(); зегуег.11з1еп(сспГ1д.рег1); зегуег.оп( еггог', (егг) => { 1Г (егг.собе == 'ЕАООЧТГЧиЗЕ’) сопзо1е.еггог(' РогГ ' + сопНд.рогХ + ' 1з а1 геас!у хп изе’) ; е!зе сопзоХе.еггог(егг.теззаде); }); зегуег.оп(’гедиезГ’, (гедиезГ, гез) => { уаг гетоГеАййгезз = гедиезГ.ЬеаРегз[‘х-Гоглагйей-Гог'] || гедиез!.соппесГюп. гетоГеАййгезз; // Адрес клиента сопзо1е.1од(гетоГеАййгезз + ' ' + гедиез!.теГЬой + ' ' + гедиезГ. иг1); уаг оиГ = {}; // Здесь можно изменить вывод в зависимости от гедиезГ.иг!' оиГЛезХ = гедиез!.иг1: гез.йГ11еНеай(200 { 'СопТепТ-Гуре : сспГхд.сопТепТ!уре }); гез .епс!(080К зГг1пд1Гу(ои1:)); });
зегуег.оп( Изтепшд', () => { с. 1пТо( Зегуег 1з ауа11аЫе : ЬПр // 1оса1 Ьоз!: ’ + сопТ1д рог1); }); Коне оль с командной строкой сопзг ргосезз = геди!ге(‘ргосезз'); сопзг г1 = геди!ге(' геасП1пе’) .сгеа1е1п1:ег(гасе(ргосе83.8(:с1ап, ргосезз. з!бои Г); г1.раизе() ; сопзоТе 1од('ЗопеРГипд 1опд тз Наррегигд Ьеге...’); уаг сИСопНд = { рготэТРгсНх: ' > } /* Распознавание команд НАЧАЛО */ уаг соттапбз = { еуа1‘ +ипс'11оп(агд) { // Попробуйте ввести в консоли еуа1 2 * 10 А 3 + 2 А 4 агд = агд.]01п(‘ '); Ггу { сопзо1е 1од(.еуа1(агд)); } саТсЬ (е) { соп8о1е.1од(е), } }, ех11: Гипстюп(агд) { ргосезз.ех!1(); } }; г1.оп('11пе , (81г) => { г1.раизе(); уаг агд = 81г.1г1ш().паРсЩ/([А"] + )|("(?:[А 1 \\]|\\.)+")/д); // Применение регулярного выражения для удаления всех пробелов, кроме гех, что между двойными кавычками: 11!:Iр://81аскоуегТ]ол. сот/а/14540319/2396907 1^ (агд) { Гог (1е1 п 1п агд) { агд[п] = агд[п].гер1асе(/А\"|\"$/д, ''); } уаг сошгпапаМате = агд[й]: уаг соттапс! = сотпапс1з[соттапс1Мате] : 1Г (соттапс!) {
Консоль с командной строкой 425 агд гЬ 1-Гг() ; со1гтапй(агд); } е1зе соп5о1е.1од( 'Соттапд ’ + соттапсМате + ' с!оезп\'X еххз!'); } г1.рготрг(); }); /* КОНЕЦ распознавания команд */ г1. зеТРготр'ЦсИСопТтд. рготрЕРгеНх); г1.рготрХ();
Глава 105. Использование ВгошзегИу для устранения ошибки гедшгесГ в браузерах Примеры Пример — Л1е.]8 В этом примере у нас есть файл под названием ТИе. ] 5. Предположим, вам нужно разобрать ПК! с использованием модуля доегузбгтпд в ]ауа8спр( и Мос1е.]8. Для этого достаточно вставить в файл следую- щий оператор: сопз! доегузТгТпд = гедо1-е('доегузТгтпд'); уаг геТ = диегузтппд .рагзе( Тоо-Ьаг&аЬс=хуг&аЬс=123 1); Что делает этот фрагмент кода? Во-первых, мы создаем модуль оиегузТгт пд, который предоставляет утилиты для разбора и форматирования строк запроса ПК!. Доступ к нему можно полу- чить с помощью: сопз! доегузГгхпд = гедо1ге(‘доегузТгтпд’); Затем мы разбираем ПК! с использованием мет ода ра гзе(). Этот метод разби- рает строку запроса ПК! (з1г) в коллекцию пар «ключ-значение». Например, строка запроса ,Тоо=Ьаг&гЬс=ху2&аЬс=123’ разбирается в { Тео: баг', абс: [’хух , '123'] } К сожалению, в браузерах метод гедоьге не определен, но он доступен в Ыойедз. Установка Вгом>зеп]у С помощью ВтоуузепТу вы можете писать код, который использует гедоТге так же, как это делается в Ыо(1е. Как решить проблему? Это просто.
1. Сначала установите Мобедз, который поставляется с ХРМ. Затем выполните: прт 1пе1а11 -д Ь гои/зе г 1Ту 2. Перейдите в каталог, в котором находится ваш Т11е.]3, и установите модуль диегуз1г1пд с помощью прт. прт гпзтаИ даегуз1г1пд Примечание: если вы не перейдете в конкретный каталог, команда не выпол- нится, потому что не удастся найти файл, содержащий модуль. 3. Теперь рекурсивно объедините все необходимые модули, начиная с Й1е.)8, в один файл под названием ЬипсПе. } з (или любое другое название) с помощью команды Ьготузегйу: ЬгоизегИу Т11е.]з -о ЬипЛе.]з Вгомзсгйу анализирует абстрактное синтаксическое дерево для вызовов гедиггеО и проходит по всему графу зависимостей вашего проекта. 4. Наконец, добавьте единственный тег в ваш НТМЬ, и все готово! «зсгхрт згс="Ьипо1е.]з ^</зогхрг> Что происходит? Вы получаете комбинацию вашего старого . ]з-файла (то есть Т11е. ] з) и вашего вновь созданного файла ЬипсПе. ] з. Эти два файла объе- диняются в один. Важно Имейте в виду, чго если вы хотите внести какие-либо изменения в Т11е. ] з, это не повлияет на поведение вашей программы. Ваши изменения вступят в силу только в том случае, если вы отредактируете вновь созданный ЬипсПе. ] з. Что это значит? Это означает, что если по какой-либо причине вы хотите отредактировать Г11е.]’з, изменения не будут иметь эффекта Вам действительно придется ре- дактировать ЬипсПе. ] з, так как он представляет собой объединение ЬипсПе ] з и Г11е. ] з.
Глава 106. Использование П8Мос1е для размещения веб-приложений 1Чос1е.]8 в 118 Примечания Проблема с виртуальным каталогом / вложенным приложением с представлениями Если вы собираетесь использовать Ехргезз для рендеринга представлений с по- мощью движка представлений, вам нужно передать значение уЕгЕиаЮтгРаЕб в ваши представления: гез гепс!ег( 1пс1ех', { у!г1иаЮ1 гРаЕН- утгТиаЗЫг РаЕГт }); Суть этого заключается в том, чтобы ваши гиперссылки на другие представле- ния, размещенные вашим приложением, и пути к статическим ресурсам знали, где размещен сайт, без необходимости изменять все представления после развер тывания. Это одна из наиболее неприятных и трудоемких проблем при использо- вании виртуальных каталогов с П8Гч1 оде. Версии Все приведенные выше примеры работают с: • Ехргезз у4.х • П8 7.Х/8.Х • Зоскешо VI 3.x или выше Примеры Начало работы П8Ыос1е позволяет размещать веб-приложения \ос1е.]8 на 115 7/8 так же, как и приложение .МЕТ. Конечно, вы можете самостоятельно разместить процесс
поое.ехе на М/шбошк, но зачем это делать, если можно просто запустить ваше приложение в П8? 1181ч обе будет управлять масштабированием на несколько ядер, процессом побе ехе и автоматической перезагрузкой вашего 118-приложения при обновле- нии вашего приложения, и эго лишь некоторые из его преимуществ. Требования ПЫм ойе предъявит вам несколько требований перед тем, как вы сможете раз- местить ваше Мойедз-приложение в 118. 1. Мобедз должен быть установлен на хосте 118 32-битной или 64-битной версии — обе поддерживаются. 2. ИЗМобе должен быть установлен х8Ь или х64, это должно соответствовать разрядности вашего хоста 118. 3. Модуль М1СГО8ОЙ ИКЬ-КеутШ для П8 должен быть установлен па вашем хосте 118. Это важно, штаче запросы к вашему приложению Койедз не будут работать должным образом. 4. Файл ИеЬ.согтГхд должен находиться в корневой папке вашего приложения Моск.р. 5. Конфигурация ПЗМобе через файл 11зпобе . ут! или элемент <115побе> в вашем ИеЬ соггГзд. Простой пример НеНо Мог1с1 с использованием Ехргезз Чтобы этот пример работал, вам нужно создать приложение 118 7/8 на вашем хосте 118 и добавить каталог, содержащий веб-приложение Мобедз, как физиче- ский каталог. Убедитесь, что учетная запись АррИсайоп/АррНсапоп Роо! ШепГйу имеет доступ к установленному Койедз. В этом примере используется 64-битная установка Кобедз. Структура проекта Эго базовая структура проекта веб-приложения П8Ко(1е/Мос1ед8. Она почти идентична любой веб-программе, не использующей П8Чобе, за исключением до- бавления файла Л'ео. согтГтд. -/арр_гоо1: -раскаде. дзоп -зегуег.дз - 'ЛеЬ.сопНд
8ег\>ег.]$-приложение на Ехргехз сопзГ ехргезз = гедитге('ехргезз’); сопз! зегуег = ехргезз(); // Нам нужно получить порт, который 1181№с1е передает нам, // используя переменную окружения РОРТ, если она не установлена, ис- пользуйте значение пс умолчанию сопет рогт = ргосезз.епу.РОЙТ || 3000; // Настройка маршрута в корне нашего приложения зегуег.деТ(‘Г , (гед, гез) => { геТигп гез З1а1из(200) ,зепс1( ’НеПо Иог1сГ); }); зегуег. 1±з1еп(рогр, () => { сопзоТе 1од( Ызтепюд ог ${рог!} ); }); Конфигурация и \УеЬ.сопф% Файл йеЬ.соп+тд точно такой же, как и любой другой ИеЬ.сопТтд для 118, за исключением того, что должны присутствовать следующие два элемента: ПК1, <ге\уп(е><ги1ез> и ПЗМобе <Ьапс11ег> Оба этих элемента являются дочерними для <5узГет.ууеЬ8егует>. Конфигурация Вы можете настроить ПЗЫойе с помощью файла Изпос1е.ут1 или добавив элемент <11зпос1е> как дочерний элемент <зуз(:ет.йеЬ8егуег> в вашем йеЬ. сопТтд. Оба этих конфигурационных файла можно использовать одновременно. Однако в этом случае Йео. сопТьд должен указывать на файл Изпобе ут1, и лю- бые конфликты конфигураций будут взяты из файла изпобе.уп,! Такое перео- пределение конфигурации не может происходить в обратном порядке. Обработчик НЗМосДе Чтобы 118 знал, что файл зегуег.уз содержит наше веб-приложение Мойе.р, нам нужно явно указать это. Мы можем сделать это, добавив обработчик П8Мос1е <1тагк11 ег> в элемент <МапЛегз>. <Ьапс11ег5> <абс| паше=’Изпобе ра1И= зегуег.уз" уегЬ=“*" тобо1ез="ттзпобе'/> </Ьапб1егз>
Правила ЦВ1-йеуяйе 11оследнии этап конфигурации заключается в том, чтобы убедиться, что тра фик, предназначенный для нашего Иос1е.]8-приложения, поступающий в экзем- пляр 115, перенаправляется на П5Мос1е. Без правил переписываштя ЪГКЬ нам при- шлось бы обращаться к нашему приложению по адресу Ы1р: //<1позг>/зегуег. ]з, и что еще хуже, при попытке запроса ресурса, предоставляемого зегуег. ]з, вы получите ошибку 104. Именно поэтому переписывание ИКЬ необходимо для веб-нриложений ПЗЫобе. <гейг11:е> <ги1ез> <!-- Сначала проверяем, соответствует ли входящий ОКЬ физиче скому файлу в папке /рибИс --> <ги1е папе= 51 аИсСопТеп! ра11егп5уп1ах=' йНбсагб ’> <ас11оп 1:уре=' Че«г11е" иг1= 'риЫ1с/•!Р:0" 1одРе«г 1Г1:еп11г1= "1:гие"/> <СОП0111ОПЗ> <абб 1приТ=' {РЕ0иЕ51_г1ЬЕМАМЕ}" п,а1сКТуре= 1зЕ11е" педаТе-'Чгие /> </С0'Пб1'110п8> <та1сб иг1= *.*"/> </ги1е> <!-- Все остальные 0Р1_ перенаправляются на почку входа прило- жения 1Мобе.]5 --> <ги1е папе= ОупаписСоптепт > <сопа11:1опз> <абб 1при1=' {РЕ00Е5Т_ЕПЕМАМЕ}" та1сПТуре="1зЕПе" педаге="7 гие"/> < /сопр11;1опз> <ас1юп 1уре='КеюгзЛе пг1=' зегуег. ]з /> </го!е> </го1ез> < / г еигИе* Это рабочий файл й'ео. сопГ 1д для данною примера, настроенный для 64-бит- ной установки Исбе.]8. Вот и все, теперь откройте свой сайт 115 и убедитесь, что ваше приложение Ыос1е.)8 работает. Использование виртуального каталога 118 или вложенного приложения Использование виртуального каталога или вложенного приложения в 115 — это обычный сценарий, и, скорее всего, вы захотите применить его, используя пвиойе.
ЦЗЫойе не предоставляет прямую поддержку виртуальных каталогов или вложенных приложений через конфигурацию, поэтому для достижения этого мы должны воспользоваться функцией ПЗМобе, которая не является ча- стью конфигурации и гораздо менее известна. Все дочерние элементы элемен- та <арр8есТ1пдз> в йеЬ.сопГтд добавляются в объект ргосезз епу в качестве свойств с использованием ключа аррЗеТМпд, Создадим виртуальный каталог в наших <арр8еНш§з>: <арр8еП1пдз> <абб кеу="у1гСиаЮ1гРа1Н уа1ие= /Тоо /> </арр8еСГ:1пдз> В нашем приложении Мос1е.]8 мы можем получить доступ к настройке утггиаЮтгРаСН сопяо1е.1од(ргосезз.епу.У1г1:иа101гРа11т); // выводит /Тоо Теперь, когда мы можем использовать элемент <аро8еШ1пдз> для конфигура- ции, давайте воспользуемся этим в нашем серверном коде: // Доступ к настройкам утггиаЮтгРа'Ит и присвоение значения по умол- чанию уаг У1гСиаЮ1гРас1т = ргосезз епу .утгсиаЮтгРасН || // Также мы хотим убедиться, что утгСиаЮтгРаСК // всегда начинается с косой черты 1Т (1 у1г1иаЮ1г Ра11т.зСагСзИт 11т(' / ', 3)) У1г1иаЮ1гРа1:Н = '/’ + утПиаЮьгРаСЬ; // Настройка маршрута в корне нашего приложения зегуег.де1(у1Г'СиаЮ1гРа'!:Ь, (гед гез) => { гегигп гез.з1:а1:из(20е) ,зепб('Не11о Иог1сГ); }); Мы можем использовать уДгСиаЮтгРаСЬ и для наших статических ресурсов // Публичный каталог зегуег. озе(ехргезз.з1а!1с(раСН. ]О1п(у1г1иаЮтгРа1:Н, 'риЬИс'))); // Вои/ег зегуег.изе( /Ьоиег-СотоопепДз’, ехргезз. зСа11с(ра111. ]О1п(У1г1;иа101гРа1:Н, ‘Ьои/ег-СотропепТз’))); Соединим все это вместе: сопзГ ехргезз = геоо1ге('ехргезз’); сопзС зегуег = ехргезз();
сопз! рог1 = ргосезз. епу.РСРТ || 3090: // Доступ к настройкам утгСоаЮтгРаТп и присвоение значения по умол- чанию '/' //в случае, если оно не существует или не установлено уаг утгСиаЮтгРасб = ргосезз.епу.утгбиаЮхгРаИт || // Также мы хотим убедиться, что утгСиаЮтгРаТб // всегда начинается с косой черты 1Т (! у1гСиа1бт гРаИт. зТагТзУ/ИТц ' /', 0)) VI гТиаЮхсРаГИ = '/ + УтгГоаЮтгРабН; // Публичный каталог зегуег .изе(ехргез8.зСат1с(ра1:б. ]01п(У1г1иа1С1гРэ1:Т|, ’риЫтс’))); // Воиег зегуег.изе('/Ьолег_сотропеп1з’, ехргезз.з!а11с(раНЬ. ]О1п(У1Г'Сиа101гРа1:К, 'Ьолег_сопропепГз'))); // Настройка маршрута в корне нашего приложения зегуег .дет:(у1гсиа1С1гРаг1т (гед, гез) => { гесигп гез.з'1агиз/'200) зепЩ ’НеПо 1Л'ог1сГ ); }); зегуег .ПзТеп^огТ, () => { сопзо1е.1од( ИзТептпд оп $<рог1} ); }); Здесь вы найдете рабочий файл МеЬ сопТТд для данного примера, настро- енный для установки 64-разрядной версии Мос1е.]8: ййр5://818Г.§ШтиЬ.сот/рЬа1о/ Й53918181с18(17Е8ее1с12. Вот и все. теперь посетите свой сайт 118 и посмотрите, как работает ваше Мойе.]’ з-приложение.
Использование ЗоскеМо с П81Чос!е Для работы 8оскег.1о с П8Мос!е единственные изменения, необходимые при от- сутствии использования виртуального каталога/вложенпого приложения, за- ключаются в файле йео. сопбгд. Поскольку 8оскеЕ1о отправляет запросы, начинающиеся с / зоскеб, то, П8Ыос1е должен сообщить П8. что эти запросы также должны обрабатываться П8Хос1е, а не просто как запросы на статические файлы или другой трафик. Для этого тре- буется другой <Капб1ег>, чем для стандартных приложений ПЗЫойе. <Напс11е г з> <абб пате=' Изпобе-зоскеНо раТК="зегуег.]з ' уегЬ="*" тос1и1 ез=" 11 зпобе' /> </НапсИе г з> Помимо изменений в <Ьапс11е гз> нам также нужно добавить дополнительное правило переписывания ЕКЬ. Это правило отправляет весь график /зоскеЕ. 1о в наш серверный файл, где запущен сервер ЗоскеЕю. <ги1е пате='ЗоскетЮ" ра1легг5уп'(ах="ЕСМА8сг1р-1"> <таСсГ| иг1="зоске'Г.ю.+ /> <ас!1оп 1уре="Чеиг11е" иг1="зегуег.]з"/> </ги1е> Если вы используете 118 8. вам ну жно отключить нас тройку ие Ь8о с к еС з в ва шем ИеЬ. сопГтд в дополнение к добавлению указанною выше обработчика и правил переписывания. Это не требуется в 118 7. так как там нет поддержки иеЬЗоскеС. <иеЬ8оске1: епаЫеб= ЕаТзе" />
Глава 107. Использование потоков Параметры Параметр Определение Кеас1ап1е Тип потока, из которого можно считывать данные. ТУгИаЫе Тип потока, в который можно записывать данные. Пир1ех Тип потока, который является как читаемым, так и записываемым. 1 гапзГопп Тип дуплексного потока, который может преобразовывать данные во время их считывания и последующей записи. Примеры Считывание данных из текстового файла с использованием потоков Ввод/вывод (1/0) в Мос1е.]8 является асинхронным, поэтому взаимодействие с диском и сетью включает передачу обратных вызовов (саПЬаск) функциям. Вы можете написать код, который обслуживает файл с диска следующим об- разом. уаг Ншр = гери1ге('йттр'); уаг Тз = гери!ге('Тз'); уаг зегуег = НПо.сгеатеЗегуеЦТипсТюп (гео. гез) { Гз. геас!Г11е(_сИгпате + '/оата.Дх! ', ТипсЫоп (егг, ЬаТа) { гез.епб(саТа); }); }); зегуег.11зТеп(8С0Э);
Этот код работает, но он громоздкий и буферизует весь файл бага. 6x1 в па- мять для каждого запроса перед тем, как от править результат обратно клиен- там. Если файл баба.6x6 очень большой, ваша программа может начать по- треблять много памяти, обслуживая множество пользователей одновременно, особенно пользователей с медленным подключением. Пользователям нужно бу- дет ждать, пока весь файл не будет загружен в память на вашем сервере, прежде чем они начну] получать его содержимое. К счастью, оба аргумента (г ед, гез) являются потоками, а это означает, что дан- ный код можно написать гораздо лучше, используя Тз сгеабеРеаб8тгеат() вместо Тз. геабЕНеО: уаг ИСгр = гедихге( И66р'); уаг Тз = геди!ге('Тз’); уаг зегуег = Г|ббр.сгеабе8егуег(Типс61ог (гед, гез) { уаг з1 геат = Тз .сгеа1еРеаб86геап1(_бхгпате + 'Лбаба.6x6'); збгеат.рхре(гез); }); зегуег.11зТеп(6000); Здесь метод .р1ре() сам заботится о прослушивании событий ‘баба’ и ‘епб’ от Тз.сгеа1еРеаб86геат(). Этот код не только более чистый, но и теперь файл бага. Тхб будет отправляться клиентам по частям (чанкам) сразу же, как только эти части будут считаны с диска. Перенаправление потоков (Р)ртд збгеатз) Читаемые потоки могут быть перенаправлены (ргреб) или соединены с запи- сываемыми потоками. Эю позволяет данным перемещаться от исходного потока к целевому без особых усилий: уаг Тз = гедихге(’Тз’) уаг геабэЫе = Тз. сгеабеРеаб86геагг( 'Т11е1 .тхб') уаг игИаЫе = Тз .сгеаТеИгхбе86геап1( ‘ Тх1е? .6x6 ’) геаоаЫе р1ре(у/г1баЫе) // возвращает «гхбаЫе Когда записываемые потоки также являются читаемыми, то есть когда они являются дуплексными потоками, вы можете продолжать перенаправлять их на другие записываемые потоки: уаг 21хЬ = гедихге( 21хЬ ) Тз. сгеабеРеаб8(:геап( ’збую.езз’) .р1ре(21хЬ.сгеэбеб2хр()) // Возвращаемый объект, 2116.Сир, явля- ется дуплексным потоком. рсре(Тз.сгеабейг1бе8бгеапц 'збу1е.сз.з.дг')) Читаемые потоки также могут быть перенаправлены в несколько потоков.
уаг геабао1е - Тз.сгеатеРеаб8тгеат( зоигсе.сзз ) геасаэ1е.р1ре(211Ь . сгеасеб21р()) р1ре(Тз . сгеа1еИгТ1:е81:геат('оиТрис. сзз.дз1)) геабаЫе. рТре(Тз.сгеаТеИг1Те8Тгеап1( 'оибриб.сзз )) Обратите внимание, что вы должны перенаправлять на выходные потоки синхронно (одновременно) до того, как любые данные начнут «течь». Несоблю- дение этого правила может привести к неполному потоку данных. Также обратите внимание, что объекты потоков могут генерировать события ошибок; убедитесь, что вы ответственно обрабатываете эти события для каждого потока по мере необходимости: уаг геабаР1е = Тз .сгеат:еРеаб81:геэт( 'Т11еЗ .1x1:') уаг 1лп1аЬ1е = Тз.сгеатейп1:е81:геат('ТИеД.ТхС ) геабаЫе. р1ре(игТТаЫе) геабаЫе.оп( 'еггог', сопзсТе.еггог) игТбаЫе .оп( 'еггог', сспзоТе.еггог) Создание собственного читаемого/записываемого потока Мы часто видим, как объекты потоков возвращаются модулями, такими как Тз и т. д., но что если мы хотим создать свой собственный объект потока? Для создания объекта потока необходимо использовать модуль зТгеат, пре- доставляемый Нойе.)з: уаг Тз = гецитге( 'Те ) ; уаг збгеап = геди!ге( "зТгеат") ЛгИаЫе; /* * Реализация функции записи в классе записываемого потока. * Это функция, которая будет использоваться, когда другой поток будет перенаправлен в этот * записываемый поток, */ збгеат.рго1обуре._1лг1Те = Типе!Топ(сНипк, баТа) { сопзо1е.1од(саТа); } уаг сизюпЗсгеат = геи збгеат(); Тз сгеа1еРеаа8ггеат1( ат! ]з ) .рТре(сизбоп15сгеат); Это даст нам наш собственный пользовательский записываемый поток. Мы можем реализовать что угодно в пределах функции _«гТТе. Вышеописан-
ный метод работает в Хобе.)8 версии 4.х.х, но в Мойе.]8 6.x были введены классы Е86, поэтому синтаксис изменился. Ниже приведен код для версии Мобе.)8 6.x: сопз! Игиао1е = геди1ге(' зТгеат') .Иг11:аЫе ; с1азз Муй/гзЛаЫе ехСепбз ИгИаЫе { сопзСгисСоЦорГАопз) { зиреЦорТюпз); } _йГ1се(сбипк, епсобтпд, саПоаск) { сопзо1е.1од(с1типк); ) } Зачем нужны потоки? Рассмотрим следующие два примера чтештя содержимого файла. Первый пример использует асинхронный метод чтения файла и предоставля- ет функцию обратного вызова, которая вызывается, как только файл полностью загружается в память: Ез. геас!Е11е( ${__бт гпэте}/и'(:1]з. ]з , (егг, бата) => { 1? (егг) { ПапсНеЕ г го г(егг); } е1зе { сопзо!е. 1од( ба ГаЛоЗСг 1пд()); } }) И второй пример, который использует потоки для чтения содержимою фай- ла по частям: уаг ТПеЗТгеат = Тз .сгеа1сРеаб81:геап1( ’${_б1гпате}/’Г11е ); уаг ЕНеСоптепт = '' ; ’Г11е81:геап1.оп( ’баТа’, баТа => { ЕНеСопсепт +- бага.гоЗтпдО; }) Г11е81геап1.оп( 'епб', () -> { сопзо1е. 1од (Т11еСол1:епГ); }) Т11е8тгеэп'.оп('еггог', егг => { ЬапЛеЕггог(егг) })
Стоит упомянуть, что оба примера выполняю! одно и то же действие. В чем же тотда разница? • Первый пример короче и выглядит элегантнее. • Второй позволяет вам обрабатывать файл, пока он читается (!). Когда файлы, с которыми вы работаете, малы, то использование потоков не оказывает значительного .эффекта, но что происходит, когда файл большой (настолько большой, что его чтение в память заштмает 10 секунд)? Без потоков вам придется ждать, ничего не делая (если только ваш процесс не выполняет другие задачи), пока пройдут эти 10 секунд и файл полностью за- грузится в память, и только после этого вы сможете начать его обработку. С потоками вы получаете содержимое файла по частям, как только они стано- вятся доступны, и это позволяет вам обрабатывать файл, пока он читается. Пример выше не показывает, как потоки могут быть использованы для задач, которые сложно выполнить, используя функшзи обратного вызова, поэтому да- вайте рассмотрим другой пример. допустим, вам необходимо скача 1ъ файл в формате дгтр, распаковать его и со- хранить содержимое на диск. Имея ПКБ файла, нужно сделать следующее: • Скачать файл • Распаковать файл • Сохранить его на диск Предположим, что у нас имеется небольшой файл, который хранится в 83-хра- нилище. Следующий код выполняет описанную выше последовательность дей- ствий с использованием функций обратного вызова: уаг зСагСТьте = 0а1:е .поу/( ) 53 деЮЬ]есС((Виске!: 'зоте-Ьискет', Кеу: ’гиееГз.дг'}, (егг, баса) => { // здесь загружается весь файл 211Р.дип21р(Сата.Боау (егг, сага) => { // здесь весь файл распакован Тз .иг11:еР11е( ${_сНгпатерСйееСз.]зоп , даСа, егг => { тС (егг) сопзс1е.еггог(егг) // здесь весь файл записан на диск уаг епсПьте = РаСе.по«() сопзо1е.1од( 5{епбТ1ч1е - зСагШте) тППзесопбз ) // 1339 тПИзесопбз }) }) }) // 1339 тШхзесопбз
Вот как это выглядит при использовании зтгеашз: з3.деГ0Ь]ес1({Вискег: зоше-Ьискег1, Кеу: '1«ее1з.дг'}) .сгеагеКеаб81:геат() ртре(г11Ь сгеаге6ип21р()) ртре(Тз.сгеа1ейг1Се81:геат( ${_.б1гпате)/1у»ееГз )зоп )); // 1234 тПИзесопбз Да, это не быстрее при работе с небольшими файлами — тестируемый файл «весит» 80 КВ. Тестирование на большем файле, 71 МВ в формате дгьр (382 МВ в распакованном виде), показывает, что версия с потоками значительно быстрее. • Сиспользованиемфункцийобратного вызова это заняло 20925 миллисекунд для загрузки 71 МВ, распаковки и записи 382 МВ на диск. • Для сравнения, с использованием потоков эго заняло 13 434 миллисекунды (на 35% быстрее).
Глава 108. Использование \Л/еЬЗоске1 с Ыос1е.]8 Примеры Установка УУеЬЗоске! Есть несколько способов установки ШеЬЗоскег в ваш проект. Вот некоторые примеры: прт 1пз1а11 --зауе из или внутри вашего раскаде. ] зоп, используя: с1ерепс1епс1ез : { "из": } Добавление МеЬЗоске! в ваши файлы Чтобы добавить \МеЬ8оске1 в ваши файлы, просто используйте: уаг из = геди!ге('из'); Использование \МеЬ8оске1 и 'Л/еЬ8оске! Зегуег Чтобы открыть новый ^еЬЗоскет, просто добавьте такой код: уаг ЛеоЗоскет = геао1ге('из ); уаг из = пей МеоЗоскеЦ пз://боз1: .808О/Ор1юпа1Ра1:бМате ); // Продолжайте с вашим кодом Или, чтобы открыть сервер, используйте: уаг Л'еоЗоскеДЗегуег = геди!ге( из').Зегуег; уаг из = пей ИеЬЗоскеЕЗегуег({рогб: 8080 раДб: ОрИопаЕРаДРМате'});
Простой пример МеЬ5оске1-сервера уаг ’ЛеЬЗоске! Зегуег = геди1ге('йз’).Зегуег, изз = пей йеЬ8оске18егуег({ рог1: 8080 }); // Если хотите добавить путь, используйте раГЬ: "РатГ^ате йзз.оп( ‘соппесиюп’, ТипсИол ссппес11оп(«з) { йз.оп('теззаде , ^ипстюг 1псот1пд(теззаде) { сопзо1е.1одРгесехуей: %з ’, теззаде); }); йз.зепс!( 'зоте1Ыпд‘) ; });
Глава 109. Веб-приложения с Ехргезз Введение Ехргезз — это минималистичный и гибкий фреймворк для веб приложе- ний на Хо(1е.)8, предоставляющий мощный набор возможностей для создания веб-приложений. Официальный сайт Ехргезз — кПрз://ехргезз]8.сот/. Исходный код можно найти на СпНий, перейдя по ссылке Ьйрз^ййиЬ.сот/ ехргез8)8/ехргез8.
Синтаксис • арр.де!(ратп [, ппссИеиаге], саПЬаск], саПЬаск...]) • арр.риЩ'ратЬ [, пибсНешаге], саПЬаск], саПЬаск...]) • арр.розНраТЬ [, тЮсНеиаге], саПЬаск], саПЬаск .]) • арр] 'с1е1еТе ] (раТН [, тлбЫеиаге] саПЬаск], саПЬаск.. ]) • арр .изе(рагп [, ппсШеиаге], саПЬаск], саПЬаск...]) • арр.и5е(саНЬаск) Параметры Параметр Детали расЬ Указывает часть пути или ЦКЕ. который будет обрабатываться указанным саПЬаск. гшйШеу.-аге Одна или несколько функций, которые будут вызваны перед саПЬаск. Полезно для более специфичной обработки, например, .для авторизации или обработки ошибок. саПЬаск Функция, которая будет использоваться для обработки запросов к указанному пути. Она будет вызываться как саПЬаск (гериезТ, гезропзе, пехС). гециезт Объект, инкапсулирующий детали НТТР запроса, который необходимо обработать. гезропзе Объект, который используется для указания того, как сервер должен ответить на запрос пех( Функция, которая передает управление следующему подходящему маршруту. Принимает необязательный объект ошибки. Примеры Начало работы Сначала вам нужно создать директорию, перейти в нее через оболочку и уста- новить Ехргезз с помощью прт, выполнив команду: прт тпзТаП ехргезз -зауе Создайте файл и назовите его арр. ] з, добавив в него следующий код, который создает новый сервер Ехргезз и добавляет одну конечную точку (/р 1 пд) с исполь- зованием метода арр.деС:
сопз! ехргезз = гедо1ге( 'ехргезз') ; сопз! арр = ехргеззС); арр.де!('/ртпд ’, (гедоез! гезропзе) => { гезропзе зепб('ропд'); }); арр.1Х8!ег(8680, '1оса1Поз! ); Чтобы запустить ваш скрипт, используйте следующую команду’ в оболочке: > побе арр.^з Ваше приложение будет принимать подключения на 1осаИюз1 порта 8080. Если аргумент ЬозТпате в арр 11з1еп опущен, то сервер будет принимать под- ключения как на )Р-адрес машины, так и на 1оса] Коз! Если значение порта рав- но 0. операционная система назначит доступный порт. После запуска скрипта вы можете протестировать его в оболочке, чтобы убе- диться, что вы получаете ожидаемый ответ «ропд» от сервера: > сог1 ИКр ://1оса1Но5! 8080/ртпд ропд Вы также можете открыть веб-браузер и перейти по ПК!-адресу ЫТр:// 1оса1Ноз(.8080;ршд, чтобы увидеть вывод. Основное маршрутизирование Сначала создайте приложение Ехргезз: сопз! ехргезз = гедо!ге(’ехогезз’); сопз! арр = ехргезз(); Затем вы можете определить маршруты следующим образом- арр.де!('/зоте1)г1’, ГипсНоп (гед, гез, пех!) {}) Такая структура работает для всех НТТР-методов и ожидает путь в качестве первого аргумента и обработчик для этого пути, который получает объекты гедоезС и гезропзе. Таким образом, дтя основных НТТР-методов маршруты бу- дут следующими: // БЕТ ««и.ботатп.сот/туРа!б арр.де!('/туРатЬ', Топсгтсп (гед, гез, пех!) {}) // Р08Т отл«.бо<па1п.сот/туРа!Ь арр.роз!('/туРаСб’, ЕипсТтоп (гед, гез, пех!) {})
// РОТ тлм.аотатп.сот/гпуРаТН арр.ри1( /туРаЕп', Гипс-Поп (гер. гез, пех!) {}) // ИЕ1ЕТЕ т, с1огга 1 п. сот/туРа! И арр с1е!ете(' /туРаСЬ', ТипсНоп (гер, гез, пех!) {}) Вы можете проверить полный список поддерживаемых глаголов здесь: Ийр8://ехрге88]8.сот/еп/4х/ар1.йшг1#арр.МЕТНОВ. Если вы хотите определить одинаковое поведение для маршрута и всех НТТР-методоъ, вы можете использовать: арр.а11( /туРасН', ГипсПоп (гер, гез, пехГ) {}) или арр.изе( '/шуРаГИ', Гипстюп (гер, гез, пехГ) {}) или арр.изе('*', ГопсПоп (гер, гез, пехГ) {}) // * й110сагс1 будет маршрутизировать для всех путей Вы можете цеплять определения маршрутов для одного нуги: арр гои1е('/туРаГб') . реНГипсНоп (гер, гез, пехГ) {}) рсзНГипс'Сюп (гер, гез, пехс) {}) ри1(Еипс1юп (гео, гез, пех!) {}) Вы также можете добавлять функции к любому НТТР-методу. Они будут вы- полняться перед финальным саНЬаск и принимать параметры гер, гез, пех! в качестве аргументов. // 6ЕТ м.бошаЕп.сот/туРаМт арр дет ('/тура СП', туЕипсСюп, ГипсПоп (гер, гез, пехС) {})
Ваши финальные саИоаск-функции могут быть сохранены во внешнем фай- ле, чтобы избежать перенасыщения кода в одном файле: // оббег.]з ехрогбз бо8отебб1пд = бипсбюп( гед, гез, пехб) {/* выполняем что-то */}; ...а затем в файле, содержащем ваши маршруты: сопзб оббег = геаи!ге('./оббег.]з’); арр. цеб('/зотеОп’, туЕипстюп, оббег .доЗотеИипд); Это сделает ваш код гораздо более удобным для чтения Получение информации из запроса Допустим, вам необходимо получить информацию из ИК],-запроса (обрати- те внимание, что гео— это объект запроса в обработчике маршрутов). Рассмо- трим это определение маршрута /зебббпдз/:изег_ю и следующий пример /зе(б1пдз/32135?Т1е]б-паше // получение полного пути гед .огтдгпаЮг! // => /зебб1пдз/32135?Т1е1б-пап1е // получение параметра изег_±б гед.рагашз.изег_1б // => 32135 // получение значения диегу параметра •бд.еЗ.с! гед.диегу,Т1е]б // => 'пате Вы также можете получить заголовки запроса следующим образом: гед.деб('Сопбепб-Туре') // 'бехб/р1а1П" Для упрощения получения другой информации можно использовать тббЛелагез (промежуточные обработчики). Например, чтобы получить инфор- мацию из тела запроса, вы можете использовать т) бЛелаге Ьобу-рагзег. кото- рый преобразует «сырое» гело запроса в удобный формат: уаг арр = геци1ге('ехргезз')(); уаг ЬобуРагзег = геди!ге('Ьобу-рагзег'); арр.изе(ЬобуРагзег.]зоп()); // для парсинга эрр11саб1оп/]зоп арр.изе(ЬобуРагзег.иг1епссбеб( { ехбепееб: бгие })); // для парсинга аррИсаббоп/х-или-богт-игТепсобеб
Теперь предположим, что запрос выглядит так: РИТ /зеТТ1пдз/32135 { "паше": "РеТег1 } Вы можете получить доступ к переданному имени следующим образом’ гер бобу.пате // "Ретег1" Аналогично вы можете получить доступ к сооПез из запроса. Для этого также нужен ш1бй1еиаге, такой как ссокге-рагзег: гед.соокхез.пате Модульное принижение на Ехргезз Чтобы сделать веб-приложение на Ехргезз модульным, используйте фабрики роутеров Модуль: // дгееб.]з сопз! ехргезз - гедихге('ехргезз'); тос1и1е.ехрсгГз = ЕипсГхоп^ртхопз = {}) { // Фабрика роутера сопз!: гоитег = ехргезз.Роитег(); гоитег.де1:('/дгееТ , (гед, гез пехг) => { гез.епс1(ор11опз.дгеет1пд); }); геТигп гоитег; }; Приложение: // арр.]з сопзТ ехргезз = гедихге('ехргезз; сопз! дгее1М1с1б1ейаге = гедихге( ./дгееТ . ] з '); ехргезз() ,изе('/ар!/у1/‘, дгеетМ1бб1еиаге({ дгеетхпд: ’НеПо «ог!с1 ’ })) ,11зтеп(8030); Это сделает ваше приложение модульным, настраиваемым, а ваш код — пе- реиспользуемым.
При обращении по адресу р //<позСпате->:8080/арХ/у1/дгеет вывод бу- дет «Не11о логХс!». Более сложный пример Рассмотрим пример с сервисами, который демонстрирует преимущества ппйсНеууаге-фабрики. Модуль: // дгеет дз сопзТ ехргезз = гедиХге('ехргезз'); тоаи 1е.ехрогТз = ТипсТХогцорТюпз = {}) { // Фабрика роутера сопат гоиТег = ехргезз.АоиТег(); // Получаем кон[роллер сопзТ {зегугсе} = орТХопз гоиТег.деТ:('/дгеет', (гед, гез, пехт) => { гез.епс!( зегуХсе.сгеаТе6гееТХпд(гед.диегу.паше || ’ЗТгапдег') }); Л геТигп гоитег; }; Приложение: // арр.дз сопзТ ехргезз = геди1ге('ехргезз'); сопзТ дгееТМХсИ1еиаге = геди1ге(' ./дгеет.дз'); сХазз СгееТХпдЗегуХсе { сопзТгисТог(дгееТ1пд = НеХХо ) { ТИХз.дгееТХпд = дгееТХпд; } сгеатебгееТ1пд(пате) { геТогп ${ТЬхз.дгееТХпд}, З/паше}1’; } } ехргезз() . изе(' /арХ/V1 /зегутсе!', дгееТМ1сШе\уаге( { зегухсе: пек 5гееТ1пд8егу1се(‘НеНо '), })) .изе('/арХ/у1/зегу1се2 , дгееТМ1бС1еиаге({ зегуХсе: пел 2гееТ1пд5егуХсе('НХ'), })) .1ХзТеп(808О);
При обращении по адресу 1г1гр://<1гэзСпате>:9080/ар1/у1/зе,'У1се1/ дгеег?пате=М/ог14 вывод будет «Не11о. Йог1б», а при обращении по адресу НГ Ср://<Коз1пате>,8080/ар1/у1/зегу1се2/дгее1?пагге=Иог1Р вывод будет «Нт, Уюг1с1». Использование шаблонизатора Следующий код настроит Забе в качестве шаблонизатора (Примечание: с де- кабря 2015 года бабе был переименован в Рид). сопз! ехргезз = геди!ге('ехргезз’); // Импортируем модуль ехргезз сопз! арр = ехргезз(); // Создаем экземпляр модуля ехргезз сопзг Н0Р1 = 3000; // Случайно выбранный порт арр.зет('утек епдтпе', ‘дас!е ); // Устанавливаем даОе в качестве ша- блонизатора арр.8е1('утеиз , 'згс/утелз '); // Устанавливаем каталог, где хранятся нее представления (.]абе-файлы) // Создаем корневой маршрут арр.де!(' /', ТипсПоп( гец, гез) { гез. гепбег(' хпбех ); // рендерим файл тпбех дас!е в ЬГт1 и возвра- щаем как ответ. // Функция гепбег опционально принимает данные для передачи в пред- ставление . }); // Запускаем сервер Ехргезз с обратным вызовом арр. 1181еп(Р0КТ, Типс1юп(егг) { 1Т (!егг) { сопзэ1е1од('Зегуег 1з гиппЕпд а! рог!', РОРТ); } е1зе { сопзо1е. 1од( 180М. 51г1од1'Гу(егг)); } }); Аналогичным образом могут использоваться и другие шаблонизаторы. такие как НапЛеЬагз (1тЬз) или Е)8. Не забудьте установить соответствующий пакет с помощью прпг Для НалсПеЬагз используйте пакет 1тЬз, для бабе — пакет дабе, а для Е|8 — пакет ед з. Пример с шаблоном Е]8 С помощью Е}8 (как и других шаблонизаюров Ехргезз) вы можете выполнять серверный код и получать доступ к переменным сервера из НТМЬ.
В Е}8 эго делается с использованием «<%» в качестве начального тега и «%>» в качестве конечного тега, переменные, переданные как параметры рендера, можно получить с помощью <%=уаг_пате%> Например, если у вас есть массив зиррИез в серверном коде, вы можете ите- рировать по нему следующим образом: <Ы><%= Ш1е <о1> <% Еог(уаг 1 = 0; 1 < зорр11ез. 1епд1Ь; 1++) { %> <11> <а Ьге'Г-'зирр11ез/<%= зорр1аез[1] %>'> <%- зирр11ез[1] %> </а> </11> <% } %> </о1> Как видно из примера, каждый раз, когда вы переключаетесь между сервер- ным кодом и НТМЬ, вам нужно закрыть текущий тег Е]8 и позже открыть но- вый. В этом примере мы хот ели создать 11 внутри пикта Гог, поэтому нам нуж- но было закрыть тег Е]8 в конце Есг и создать новый тет только для фигурных скобок. Еще один пример: если мы хотим установить значение по умолчанию для эле- мента пари! в качестве переменной с сервера, мы используем <%=: Меззаде:<Ьг> <1приС 1уре="1:ех1:" уа1ие-"<%= теззаде %>" пате-"теззаде1 геди!гес1> Здесь переменная теззаде. переданная с сервера, будет значением по умолча нию для вашего 1про1. Обратите внимание, что если вы не передадите перемен- ную теззаде с сервера, Е}8 вызовет исключение. Вы можете передать параметры с помощью гез.гепбег('Дпбех’, {теззаде. теззаде}), (для файла Е},8 под на- званием 1пбех .е]з). В тегах Е}8 вы также можете использовать 1Т, лб11е или любую другую ко- манду }ауа8спрЕ 38ОЫ АР1 с Ехргезз.]з уаг ехргезз = гедо1ге('ехргезз'); уаг согз = геди!ге('согз'); // Используем модуль согз для включения Сгозз-ог1д1п гезоигсе збаппд уаг аро = ехргезз(); арр.изе(согз()); // для всех маршрутов
уаг рог! = ргосезз.епу.РОЗТ || 808В; арр де1(, Типе 1юп(гер, гез) { уаг 1пТо = { згг1пд.уа1ие : '8таск0уегТ1ол’, ‘ пипоег_уа1ие : 8476 } гез.]зоп(1пТо): // или ./* гез. зепб(830М. зтг1пд1'(:у( { З1г1пд_уа1ие: ЗЬаскОуегЛои’, питЬег_уа1ие 8476 })) */ // можно добавить статус-код к ззоп-ответу /* г ез.зГа1:из(?.90) .]зоп(1пТс) */ }); арр.11зТеп(рог1:, ТипсГ1оп() { сопзо1е.1од( 'Мос1е. ]3 Хтзсептпд оп рог! ' + рог!); }); При обращении по адресу 1щр:/Лоса1Ъоз1:8080/ выводится следующий объект: { "з1г1пд_уа1ие' . ’81 аскОуегПои", 'пит0ег_уа1ие’ : 8476 } Обслуживание статических файлов При создании веб сервера с помощью Ехргезз часто требуется обслуживать со четание динамического контента и статических файлов. Например, у вас могут быть файлы 1пс1ех.1т1т1 и зспрТ . ] з, которые являют ся статическими и хранятся в файловой системе. Обычно для хранения статиче- ских файлов используется папка с именем «риЫДс». В этом случае структура па- пок может выглядеть следующим образом рго]есТ гооТ |— зегуег.]з |— раскаде.]зоо 1— риЬИс |— 1пс1ех. Мт1 1— 8СГ1р1 ]3 Настроить Ехргезз для обс-туживания статических файлов можно следующим образом:
сопз! ехргезз = геритге('ехргезз'); согз! арр = ехргезз(); арр.изе(ехргез8.з1:а1:1с( ‘риЬИс’)); Примечание: после настройки папки 1пс1ех.Ы:п11 зсгтрг.^з и все фай- лы в папке рио11с будут доступны по корневому пути (не нужно указывать УроЫтс/ е ЭРЕ). Это связано с тем, что Ехргезз ищет файлы относительно на строенной статической папки. Вы можете указать виртуальный префикс пути, как показано ниже: арр. изе('/згаТю’, ехргезз з1а1:1с( риР11с’)); Это сделает ресурсы доступными по префиксу /зЕаТтс/. Несколько папок Можно определить несколько папок одновременно: арр. изе(ехргезз. зга1:1с( риЫьс )); арр.изе(ехргезз.з1а1:1с( '1тадез')); арр.изе(ехргезз.з1а1тс( Шез')); При обслуживании ресурсов Ехргезз будет просматривать папки в порядке их определения. В случае наличия файлов с одинаковыми именами будет обслужи- ваться файл из первой совпавшей папки. Именованные маршруты в стиле О)апдо Одной из основных проблем является то, что поддержка именованных марш- рутов не реализована в Ехргезз «из коробки». Решением является установка сто- роннего пакета, например ехргезз-геуегзе: прт ХпзЕаП ехргезз-геуегзе Подключите его в ваш проект: уаг арэ = геаитге('ехргезз')(); гератге('ехргезз-геуегзе')(арр); Затем используйте его следующим образом. арр. деТ (' СезТ ’, ’/НеПо', Еипс1:1оп( гер, гез) { гез .еп<1(' Не1 ] о'); });
Недостатком этого подхода является го, что вы не можете использовать мо- дуль маршрутов Ехргезз. Обходным решением может стать передача вашего приложения в качестве параметра фабрике роутера: гедиьге(' . /т1бЛе«/агез/гои11пд') (арр); ...и использование его следующим образом: тобоЕе.ехрогТз = (арр) => { арр.де!('1ез1', ’/НеПо', Типсиоп(гед, гез) { гез.епЩ 6е11о'); }); Дальше вы сможете самостоятельно разобраться, как определять функции для их объединения с заданными пользовательскими пространствами имен и указывать на соответствующие контроллеры Обработка ошибок Основная обработка ошибок По умолчанию Ехргезз будет искать представление ‘еггог’ в директории / утеиз для рендеринга. Просто создайте представление ‘еггог’ и поместите его ь директорию У1е*з для обработки ошибок. Ошибки записываются с сообщени- ем об ошибке, статусом и трассировкой стека, например: V / е г го г. род Ыт1 бобу Ы= теззаде 62= еггог.зСэЮз р= еггог,з!аск Расширенная обработка ошибок Определите свои функции промежуточной обработки ошибок в самом конце стека функций промежуточной обработки. Эти функции принимают четыре ар- гумента вместо трех (егг, гед, гез, пех!), например: арр.уз // Обработка ошибки 404 и передача ее обработчику ошибок арр.изе(Гопс11оп(гед, гез, пех!) { уаг егг = пей Еггог('Мо1 Еоопб );
егг.згагиз = 404; II передаем ошибку на следующий соответствующий маршрут пехт(егг); }); // Обработка ошибок и вывод трассировки стека арр. изе(Типссюп(егг, гер. гез, пех!) { гез.зЬабиз^гг.збабиз || 5ЙЭ); гез.гепбег('еггог', { теззаде: егг.теззаде, еггог: егг }); }); Вы можете определить несколько функций промежуточной обработки оши- бок, так же, как и с обычными функциями промежуточной обработки. Использование промежуточного ПО и обратного вызова пех! Ехргезз передает обратный вызов пех! каждому обработчику маршру- тов и функции промежуточной обработки, который может быть использован для разделения логики одного маршрута на несколько обработчиков. Вызов пехЦ) без аргументов указывает Ехргезз продолжить выполнение следующей соответствующей функции промежуточной обработки или обработчика марш- рутов. Вызов пехГ(егг) с ошибкой приведет к запуску любого промежуз очного ПО для обработки ошибок. Вызов пех! (' гоибе ’) пропустит любое последую- щее промежуточное ПО на текущем маршруте и перейдет к следующему соот- ветствующему маршруту. Это позволяет разделить доменную логику на переис пользуемые компоненты, которые являются автономными, проще тестируются и легче поддерживаются и изменяются. Множественные соответствующие маршруты Запросы к /арз /боо или /ар!/Ьаг будут запускать начальный обработчик для поиска участника, а затем передавать управление фактическому обработчи- ку для каждого маршрута: арр.деб('/ар!’, Типе Стоп(гед, гез, пехб) { // И /арт/боо, и /ар1/Ьаг будут запускать это 1оокирМетЬег(Типс(:1оп(егг, тетоег) { 1Т (егг) ге1игп пехб(егг); гед.тетЬег = тепЬег; пехт(); }); });
аор.де!('/ар!/Гоо', Типе!:1оп(гед, гез, пех!) { // Только /ар1/^оо будет запускать это йоЗотеГНтпдйКпМегтюег(гед .тепЬег); }); арр.деТ('/ар1/Ьаг', ТипсПоп(гер, гез пехГ) { // Только /ар1/Ьаг будет запускать это боботеТЫпдЭК'Гегеп'СЙЫбМетЬег ( гед .тетЬег); }); Обработчик ошибок Обработчики ошибок являются функциями промежуточной обработки с сиг- натурой Гипс1:1оп(егг, гед, гез, пех с). Они могут быть установлены для кон- кретного маршрута (например, арр де1( /Гоо , Типс1:1оп(егг, гер, гез, пех1)), но, как правило, достат очно одного обрабо тчика ошибок, который ренде- рит страшщу ошибки: арр.деГ(‘/Тоо’, Топс1:1оп( гед, гез, пех!) { бо8оте'СИ1пдАзупс(ТипсТ]ол(егг, аата) { 1Т (егг) геСогп пехт(егг); гепс1егРаде(баТа); }); }); // В случае если аоЗотеТЫпдАзупс возвращает ошибку, этот специальный // обработчик ошибок промежуточного ЛО будет вызван с ошибкой в каче- стве // первого параметра. арр.озе(Гипс11оп(егг, гед. гез, пехТ) { гепс!егЕггогРадс(егг) ; }); Промежуточное ПО Каждая из вышеуказанных функций фактически является функцией проме- жуточного ПО, которая запускается всякий раз, когда запрос соответствует опре- деленному маршруту, но любое количество функций промежуточною ПО может быть определено на одном маршруте. Это позволяет определить промежуточное ПО в отдельных файлах и использовать общую логику повторно в нескольких маршрутах: арр.дет('/Ьапапаз’, Типе!1оп(гед, гез, пех!) { де1МетЬег(ТипсТ1оп(егг, теггЬег) { (егг) геСигп пехт(егг); // Если участника нет, не пытайтесь искать дачные. // Просто перейдите к рендерингу страницы. 1Т (!петЬег) геТо-п пехТ(1гоиТе’); // В противном случае вызовите следующее промежуточное ЛО и по- лучите
// данные участника. гед.тетЬег = тетЬег; пехг(); }); }, Мпс1:1оп( гед, гее, пехЛ:) { деПМетЬегБаСа(гед тетЬег, ГипсИоп(егг, даИг) { 1Т (егг} геСогп пехс(егг); II Если у этого участника нет данных, не утруждайтесь // их разбором. Просто перейдите к рендерингу страницы. 1Т (Мата) геСогп пехС(' готе'); // В противном случае вызовите следующее промежуточное ПО и раз- берите // данные участника. Затем отрендерьте страницу. гец.тетЬег.ЬэТа = ОаСа; пехС() ; }); }, СипсЫоп(гед, гез, пехт) { гед.тетЬег.рагзесЮаСа = рагзеМетЬег0а1а(гер.тетЬег.ба1а) ; пех1(); }); арр,деС('/Ьапапаз', СипсС1оп(гед, гез, пехС) { гепбег Вапапаз(гед.тетЬег); }); В этом примере каждая функция промежуточного ПО будет находиться либо в своем собственном файле, либо в переменной в другом месте файла, чтобы ее можно было использовать повторно в других маршрутах. Обработка ошибок Основную документацию можно найти здесь: Ьир8://ехрге88]8.сопт/еп/$шс1е/ еггог-йапсШп&Мт!.
аор.детД'/ра1Н/:1с1(\\б+)', ГипсХюп (гео, гез, пехб) { // обратите внимание: пех!" передается 16 (гед рагатз.16 == 0) // проверка параметра гебигп пех1;(пей Еггог(’16 1з 0’)); // перейти к первому обра- ботчику ошибок, см. ниже // Обработка ошибок при синхронной операции уаг баба; Игу { баба = 080И. рагзе('/ТПе.]зоп’) ; } сассб (егг) { гебигп пехб(егг); } // Если возникла критическая ошибка, остановите приложение 16 (!баСа) СКгой пей Еггог( '8тГ1т игопд'); // Если необходимо передать дополнительную информацию в обработ- чик ошибок, // отправьте пользовательскую сшибку (см Приложение В) 16 (зт1:Н) пехЦпел МуЕггог( ' злтСН игопд ’, агд!, агд2)); // Завершите запрос с помощью гез.гепбег или гез.епб гез зтаниз(200),епб('ОК1); }); Будьте уверены: порядок использования арр. чзе имеет значение. // Обработчик ошибок арр.изе(бипсб1оп(егг, гед, гез пехб) ( 16 (згобЬ-сИеск, е.д. гед.иг1 != ‘ Р08Т') геТигп пехб(егг); // перейти к обработчику ошибок 2. сопзо1е.1од(гед.иг1, егг.теззаде); 16 (гед.хИг) // если запрос через адах, то отправить ]зоп, иначе отрендерьте страницу ошибки гез.]зоп(егг); е1зе гез.гепбег('еггог.1г1т1', {еггог: егг.теззаде}); });
Как выполнить код перед любым запросом и после любого ответа 459 // Обработчик ошибок 2 арр.изе(Типс11оп(егг, гед гез, пех!) { // Ввшолниге что-нибудо здесь, например проверьте, является ли ошибка МуЕггог 11 (егг 1пз1апсео^ МуЕггог) { сопзо1е.1од(егг.теззаде, егг.агд!, егг.егд2); } гез. епсЦ ); }); Приложение А // "В Ехргезз ответы с кодом -104 не являются результатом ошибки, // поэтому промежуточное ПО для обработки ошибок их не захватит." //Вы можете изменить это. арр. изе(1ипс11оп( гед, гез, пех!) { пехТ(пеи Еггог(404)); }); Приложение В // Как определить пользовательскую ошибку уаг и(11 = гедитге('и!11'); ГопсРюп МуЕггог(теззаде, агд1, агд2) { 11т1з .теззаде = теззаде; 1Ыз .агд1 = агд1 ; 1(113 агд2 = агд2; Еггог,сартиге51аск7 гасе(11из, МуЕггог); } 0111.1п(1егИз(МуЕггог, Еггог); МуЕггог.ргоЮ1уре.пате = МуЕггог'; Как выполнить код перед любым запросом и после любого ответа арр. озе() и промежуточное ПО (ппНсПемгаге) могут использоваться для выпол- нения кода «перед», а комбинация событий с1озе и Т1п1з(1 может использовать- ся для выполнения кода «после». арр.изе(ГипсПоп (гед. гез, пех!) { ТипсИоп а'*:1егРезропзе() {
гез, ге:по7е1_1згепег('Г1п1зЬ', аГ^егРезропзе); гез гетоуеЕ1з1епег('с1озе', а<ЧегРезропзе); // действия после ответа } гез.оп('Т1п1з11', аТТегРезроп8е); тез .оп( ‘ с!озе ’, аНегРезропзе), // действия перед запросом //в конце вызов пехЕ() пех1(); }); арр.изе(арр.гооЕег); Примером этого является промежуточное ПО 1о§§ег, которое по умолчанию добавляет запись в лог после ответа. Просто убедитесь, что это промежуточное ПО используется перед арр гооЕег, так как порядок имеет значение. Оригинальный пост находится здесь: Ъйрз^/ЫаскоуегЯоту.сот/ диезПоп8/20175806,'ЬеГоге-апб-аЙег-11оок5-Гог-а-гедие81-т-ехрге83-(о-Ье-ехеси1ес1- ЬеГоге-апу гец а. Обработка РО8Т-запросов Точно так же, как вы обрабатываете СЕТ-запросы в Ехргезз с помощью ме- тода арр. деЕ, вы можете использовать метод арр. роз! для обработки РО8Т-за- просов. По прежде чем вы сможете обрабатывать РО8Т-запросы, вам нужно будет ис- пользовать промежуточное ПО Ьобу-рагзег. Оно просто разбирает тело РО8Т, РИТ, ПЕЕЕТЕ и других запросов. Промежуточное ПО Ьобу-рагзег разбирает тело запроса и превращает его в объект, доступный в гед. ЬоОу
уаг ЬобуРагзег = гедлге('Ьобу-рагзег'); сопз! ехргезз = гедиХге('ехргезз'); сопз! арр = ехргезз(); // Разбивает тело для Р08Т, Р1)Т, ОЕ1ЕТЕ и т д. арр, изе(ЬобуРагзег. ]зг>п()); арр . изеСЬобуРагзег .иг1епсобес!({ ехХепбеб' Хгие })); арр. роз!(' /розХ-баХа-Реге’, Гипс1Хоп(гед, гез, пех!){ сопзоХе.1од(гед.Роду); // гед.Роду содержит разобранное тело за- проса . }): арр.1Хз1еп(8080, ' 1оса1РозХ’) ; Установка соок!ез с использованием соок!е рагзег Ниже приведен пример установки и чтения соокаез с использованием модуля соок се-рагзег уаг ехргезз = геди1ге('ехргезз'); уаг соокХеРагзег = гедиХге('соокхе-рагзег’); // модуль для разбора соокхез уаг арр = ехргезз(); арр.изе(соокхеРагзег()); арр.дес('/зессоокъе', Гипстхоп(гед, гез) { // установка соокхез гез.соокхе( изегпате’, ’)оРп бое', ( тахдде: 900000, РххрОпХу: Хгае }); геХигп гез.зепсЦ СсокХе Раз Ьееп зет); }); арр.де1('/де!соокХе , Гипс!Хоп(гео, гез) { уаг изегпате = гед.соскаез['изегпате ]; 1Г (изегпате) { геХигп гез.зепсЦизегпате); }
гегигп гез.зепсЦ Ио соокье Еоипа'); }); арр.11з1еп(3000); Пользовательское тгйсНешаге (промежуточное ПО) в Ехргезз В Ехргезз вы можете определясь ггцйсИеууаге, которое может использоваться для проверки запросов или установки некоторых заголовков в ответе: арр.изе(ГипсС1оп(гед, гез, пехТ){ }); // сигнатура Пример Следующий код добавляет пользователя в обьект запроса и передает управле- ние следующему соответствующему маршруту: уаг ехргезз = гедитге( ехргезз’); уаг арр = ехргезз(); // каждый запрос пройдет через это т1бс1еиаге арр изе(1ипс11оп(гед, гез, пехр){ гед.изег = 'ТезТизег ; пех1:(); // передаст управление следующему соответствующему маршруту }); арр деТ('/', ТипсСюп( гед, гез){ уаг изег = гед.изег; сопзо1е.1од(изег); // ТезТизег геТигп гез. зепб(изег); »; арр.11з1еп(3000); Обработка ошибок в Ехргезз В Ехргезз вы можете определить единый обработчик ошибок для обработки ошибок, возникших в приложении. Определите этот обработчик в конце всех маршрутов и логического кода. Пример уаг ехргезз = гедитге( ехргезз'); уаг арр = ехргезз(); // 6ЕТ /пашен/]01тп
арр.дес('/патез/:пате', Типс1юп(гед, гез, пехг) { 1Т (гед.рагапз гате == ]Ок1п'){ геЮгп гез. зепб(' Уа11а Мате’); } е]зе{ пех1(пе« Еггог( ЫсС уа11с1 пате’)); // передать в обработчик ошибок } }); // обработчик ошибок арр.изе(Типс1доп(егг, гед, гез, пех1) { соп8о1е.1од(егг.81аск); // например, Мо1 уэИд пате геСигп гсз.з1:а-сиз(500).зепсЦ ТпСегпа! Зегуег Оссигеб’); В; арр. 1±з1сеп (3000); Добавление промежуточного ПО (гтнбсИеууаге) Функции тмбсПеъуаге — это функции, которые имеют доступ к объекту за- проса (гед), объекту ответа (гез) и следующей функции тМеиаге в цикле «запрос-ответ» приложения. Функции пйбсЦесуаге могут выполнять любой код, изменять объекты гез и гед, завершать цикл ответа и вызывать следую- щее ппс!с11е\уаге. Распространенным примером пйсШ1е\уаге является модуль согз. Чтобы до- бавить поддержку СОК8, просто установите его, подключите и добавьте эту строку: арр.изе(согз()); перед любыми роугерами или функциями маршрутизации. Не11о УУог1с1 Здесь мы создаем простой сервер Не11о Иог1б с использованием Гхргезз. Маршруты: ♦ '/’ • '/И1к1
Для остальных маршрутов будет возвращено «404», т.е. «страница не най- дена». ' озе зТгтсТ', сопз! рогТ = ргосезз.еп7.РОЙТ || 3000; </аг арр = геди!ге('ехргезз')(); арр 11з1еп(рогТ); арр.деТ('/’, (гер гез) => гез ,зепб( НеИоИогЮ 1 ')); арр де1('/к1к1 , (гед, гез) => гез.зепб('ТЬ1з тз «1к1 раде.')); арр.изс((гед, гез) => гез.зепЩ'40^-РадеМотЕоипсГ )); Примечание: мы разместили маршрут 404 в качестве последнего, так как Ехргезз обрабатывает маршруты по порядку и последовательно обрабатыва- ет их для каждого запроса.
Глава 110. Мпс1о\л/8-аутентификация в Москва Примечания Существуют и другие АР1 для Ас1п;е 1)1гес(огу, такие как асТ17ес11гес1огу2 и ас11с1 а р. Примеры Использование ас11УеШгес1огу Пример ниже взят из полной документации, доступной па СйНпЬ: Ьггря:// й1Й1иЬ.сот/^йееге8/по(1е-асЙУе(11гесгогу ...или ИРМ: йПр8://пртс1ос.§ййиЬло/'по(1е-прт(1ос-асйуеШгесГогу.'ЬиП(1/ар1г1ос. Ытп1.
Установка прт ФпзТаИ --зауе асТтуеСтгесТсгу Использование // Инициализация уаг АспуеОтгесЮгу = гсци1ге( 'аспуесНгесгогу') ; уаг сопТ1д = { иг1: '1аар ://с1с.с1ота1п.сот', ЬазеОМ: ' с!с=с1огпат.п,с!с-ссп1' }; уаг ас! = пей АсГ1уе01гес1:огу(соп'(:1д); уаг изегпате = ' ]о1т.зт11:Ь®'с1ота1п.сот' ; уаг раззиога = 'разз^/огс! // Аутентификация ас1.аи1Неп11сате(изегпате1 раззлогс!. Гипс11оп(егг, аиТК) { 1Т (егг) { сопзо1е.1од( ЕККОЧ: +05СМ. З1:г1пд11’у(егг)) ; геТигп; } 1Т (аиФН) { сопзо1е.1од('АиТЬепИсаТес!! ‘; } е1зе { оопзо1е.1сд(' АиХкептхсатюп Та11ес11 ’); });
Глава 111. Менеджер пакетов Уагп Введение Уагп — это менеджер пакетов для Но(1е.]8, аналогичный ХРМ. Несмотря на сходство, между Уагп и ИРМ есть некоторые ключевые различия. Установка Уагп В этом примере объясняются различные методы установки Уагп для вашей операционной системы. тас08 НотеЬгеиг Ьге« ирбаСе Ьгел тзтаИ уагп МасРоПв аисЮ рог! 1пзСа11 уагп Добавление Уагп в РАТН Добавьте следующую строку в профиль вашей оболочки (например, . ргоС11е, . ЬазНгс, . хзНгсит. д.): ехрог! РАТН= $РАТН: уагп д!оЬа1 Ып'" (МпдОУ/З Установщик Сначала установите Ыос1е.]8, если он еще не установлен. Затем скачайте уста- новщик Уагп в формате ,тз1 с сайта Уагп: Ьпр8://с1а881с.уагпркй.сош/еп/бос8/ шз1а11#тап(10Ал;8-81аЫе.
Скосо1аГеу сбосо ХпзТаП уагп Опих УеЫап / иЬипги. Убедитесь, что Ыобе.]з установлен для вашей дистрибуции, или выполните следующую команду: сиг! -$|_ ЬПрз ://беЬ. побезоигсе. сот/зе1:ир_6 .х | зибо -Е ЬазИ - зибо арТ-де! 1пз1а11 -у побе]з Настройка репозитория УагпРкд: сиг1 -зЗ Гй1:р5://б1.уатркд.сот/с1еЫап/р1|Ькеу.дрд | зисо арт-кеу аоб - есГю "беЬ ГпТрз://61.уагпркд сот/беЫап/ зсаЫе та!п | зибс Тее / еХс/арХ/зоигсез.1181.6/уагп. 1151 Установка Уагп: зибо арТ-деС ирбаТе && зиао арТ-де! 1пзРа11 уагп Сеш08 / Гейога /ПНЕк Установите Мобе.^з, если он еще не установлен: сиг1 --511еп1 --Хосатюп ИГГрз ://грт.побезоигсе.сот/зеюр-б. х | Ьазб - Установка Уагп: зобе идет ШДрз://61 уагпркд сот/грт/уагп геро -0 /е1:с/уип1.геро5.6/ уагп.геро зобе уит тпзХаП уагп Дгсй Установите Уагп через АНН. Пример с использованием уаоигт: уаоиг! -3 уагп
зибо еоркд 1пзСа11 уагп Все дистрибутивы Добавьте следующую строку в профиль вашей оболочки (например,. р гоТПе, .Ьазбгс, .хзбгс ит.д.): ехрогС РАТН="$РАТН: уагп д1оба1 Ып'" Альтернативный метод установки Скрипт оболочки сиг1 -о- -I Ы1рз://уагпркд сот/юзгаН. зб | Ьазб или укажите версию для установки: сиг1 -о- -I Ытрз://уагпркд соп/тпзТаП.зп | ЬазЬ -з -- --уегзхоп | уегьюп] ТагЬаИ сб /орг <мде1 ЫТрз : //уагпркд .сстЛаСезС .тэг.д? Саг хухС ХаДезс.{аг,дх ьтрм Если у вас уже установлен МРМ, просто выполните: прт 1пз1а11 -д уагп После установки Проверьте установленную версию Уагп, выполнив: уагп -уегзтоп Создание базового пакета Команда уагп ХпЫ проведет вас через процесс создания файла раскаде. ] зоп, чтобы настроить информацию о вашем пакете. Это похоже на команду прт 1п1Д в КРМ. Создайте новую директорию для вашего пакета и перейдите в нее, затем вы- полните уагп 1п1Л:
тксНг ту-раскаде && ей ту-раскаде уагп 1пИ Ответьте на вопросы в интерфейсе командной строки: доезНоп папе (ту-оаскаде): ту-раскаде диезНоп уегз!оп (1.0.0): диезТюп йезсгтр-Сюп А Хезе раскаде диезТюп епТгу рохпЕ (1пс1ех.]з): диезЕгоп герозКогу иг1 диезНоп аиТЬог: 8СаскОуегГ]ом Роситеп1:а11оп диезИоп Исепзе (М1Т): зиссезз 8ауес1 раскаде.дзоп Попе 1п 27.315. Это создаст файл раскаде. ] зоп, похожий на следующий: { 'пате": ту-раскаде", "уегзюп 1: 1.0.0 , "йезсгюГюп" : 'А Гез1: раскаде1, "таю": 1пс1ех.]з , аиНюг ' 8гаскОуегТ1ол’ РоситепГаИоп , 'Исепзе : МП" } Теперь попробуем добавить зависимость. Базовый синтаксис для этого — уагп абб [раскаде-папе]. Для начала добавим Ехргезз|8. Выполните для этого следующую команду: уагп абб ехргезз При помощи этого вы добавите раздел берегбепсюз в ваш раскаде . ] зоп и добавите Ехргезз}8: "берепбепстез : { "ехргезз1: А4.15.2" } Установка пакета с помощью Уагп Уагп использует тот же реестр, что и ЫРМ. Это означает, что каждый пакет, до- ступный в МРМ, доступен и в Уагп.
Установка пакета с помощью Уагп 471 Чтобы установить пакет, выполните: уагп абб раскаде Если вам нужна конкретная версия пакета, используйте: уагп асЮ раскаде^уегзхоп Если версия, которую вы хотите установить, была помечена тегом, исполь- зуйте: уагп ас!с1 раскаде®1ад ,
Благодарности Ни Название главы Участники 4444, АЬйсйшх МокЬпасЬе, АЬЮзйек }аш. 1 Начало работы с Нобе.)8 Айат. АеоПпдатепГе!. А1еззапйго Тппса Топййог, АЦозсйа Меуег, Атйа ЗатраОз, Апкй Сотка1е, Алкиг Апапй,... 2 Взаимодействие Агйшпо с Гчос1е.]8 зВапйа Вау1й Ктре, йеупи!169, ВгакаЗАМ, 3 а$упс.]8 Г. Каийег. ]еггу, катраю, Зйщапезй Ко1Ье, 8ку, игаНй Сапп Койгщиег, Сойу С., суапЬеат, Вауе, 4 Азупс/А\уай Вау1й Хи, Вот Утуагй, т_са11еп8, Мапие!, потапЫпЬиззет, Топ! УШепа А1а Еййте )ЕВА1Л, суапЬеат, Попап Асинхронное НгйптеНе, Н. Раи\уе1уп, ]оЬп, Магек и программирование 8к1Ьа, К'айуе Сойег, от^тапегй, 81оадйеай10()7 6 Автоматическая перезагрузка при изменениях сЬ4пй4п, Веап КаГЬег, )опаз 8, }озЬиа Юееегег, МтезЬ, Запкесй Капа, хигГух 7 Избегайте ада функций об- ратного вызова (саПЬаск НеП) ГуеЬ1а В1иеЬ1Г(1 Ргоппзез (промисы) Васпй Хи
Преобразование С1етеш ]АСОВ. МхсЬае! Виеп, 8апкеШ функций обратного вызова Кайа 10 Инт еграция с Саззанйга Узеуо1о<1 Со1оу12П1п 11 Интерфейс командной стро- ки (СЫ) /е киЬепз 12 Взаимодействие клиент-сервер ХоИап 8с1шш11 Веп}атш, Попал НаттеНе, К1с1 13 Модуль С1пз1ег Втагу, МауогМопГу. Микезй 8Ьагта, пуаййаГпиг, Узеуо1ос1 Оо1о\Т2пт 14 Подключение к Моп^оПВ ГаЫапСоок, ИатезЬ Кауа1, 8Ьп§апезЬ КоШе 15 Создание библиотеки Мос1е.]8, поддерживающей как РГ0Ш1808 (промисы), так и функции обратною вызо- ва с первым ар1ументом- ошибкой Пауе 16 Создание АР1 с помощью Мос1е.]8 Микезй 8Ьагта 17 Парсер С8У в Ьюс1е.]5 а1зйас439 18 Работа с базой данных (Моп^оПВ с Мопдоозе) гигГух 19 Отладка Иобе.]8 приложения 4444, АИзГег Ыогпз, Апкиг АпапД, Н Раииге1уп, МайЬето 8Ьап1еу 20 Доставка НГМЬ или других типов файлов Штат А§гаига1, КатепСкеГ, изег2314737 21 Внедрение зависимостей Мгозйап Капарайн Развертывание 22 приложения Мос1е.]8 без про- ^епйер стоя
23 Развертывание приложении Койе.)5 в про дакшепе Артйсйоий, Всей уаскзоп, СопипппИу. Спьнап Воатш. бипсапкаП, Попал Наштейе, §и)епа, каукат, К1ит(5тяй, Май ЗаелйзГ, МаШпеиЬетоте, Микезк Зкагта, ... 24 ЕСМАЗспр! 2015 (Е86) с Ходе.]з ВауШ Хи, Попал Наттейе, Озата Ваг! 25 Окружение Скпз, ГгебсНе Со1етаи. К1ипП8т§й, Еошз Ваггалциехго, М1ккаП, зВапба 26 Источники событий ВгакаЗАИ, Ви1у Ктзку, Попал Натпгейе {атезсозПап, МтсиеззКап^ег, МоШтап 27 Еуепйоор (цикл событий) Кекпп Зелапауаке 28 Обработка исключений К1\упГ8т2к, Муезк, пуайка1лиг, зВапаа, 8]'гпаг8ку, юркетап 29 Выполнение файлов или ко- манд с помощью дочерних процессов §и1епа, кехасуаптбе, 18коге 30 Экспорт и использование модулей Апплабау, Ста)# Ауте, суалЬеап1, с!еупи1169: ВгакаЗАХ, Ееп1оп, Попал Наттейе, Ьехасуатйе, }азоп, )с!гус111, ЬоиГу1оиГ, I ошз Ваггалдиепо,... 31 Экспорт и импорт модулей в Хойе.]8 Апс1геууЕеопагсН. ВкагаГ. соттолЗелзеСойе, /атлез ВШтдкат, ОНусг, ькагйло, Зкоды 32 Затрузка файлов А1коп Мо^мац 1сетап, МтккаП, ууаИб 33 Файловый ввод/вывод (ЕНезузГетл 1/0) 4444, АссерЩб Алзтусг, АсоИп^атепЕе!, Скпзюрйе Маго18. Ста)# Ауте, ВгакаЗАЫ. Ви1у Ктзку. Пойал Напплейе. кпеткиз, Натзка] Вкатаге, йехасуаптйе,... 34 Начало работы с профилированием Мос1е.]8 йат1Г)07
35 Хороший стиль кодирования А)йе] КаизЫк. КатспСкеГ 36 Сгасейй ЗкиШошп КатепСкеГ. ЗаШтзк 37 ^гипг К'аеет ЗкаПск, 1Л/атег8СГ011 38 Наск — 39 Обработка РОЗТ запросов в К обе.]§ Мапаз ]ауатк 40 Как загружаются модули КатепСкеГ. итеяк 41 НТТР АЬтек МеЬлгаПу, АИзГег Иогпз, Аттакау, Апк Сао, азкегЬаг, Ваьи, Ви/иГ, Скапсе Зпош. Скеггчлтгг, Птйг1у Вопзоу, Нопап Наттег1е, 6112, »и1епа,... 42 Установка Ыоскф Назкнп, 51(1Вкаг(к 8пуаз1уа, ЗуегаГит, (апйгешискок, Н8ег2314737, изег6939352, VIРЗК, укТогкок! 43 Взаимодействие с консолью 8с1епйаЕ1Уегйа5> 44 Постоянное выполнение \’011е.]8 приложения А1ех Ьодап, ВеагнцЦоп, суапЬеат. Штат Аягазда!, Мтккай. тзсбех. орктиз, р1е1гоУ18тага, КатепСкеГ, Затеет Зпуа81ауа, ьотеЬойу, Тау1ог Зтпзоп 45 Фреймворк Коа у2 Баттс! Хи 16 ЬобазЬ М1кз!иг 47 ЬоорЬаск — КЕ5Т соединитель Коорезк 48 теСаЕтйЬ КатепСкеГ, У8)п3290ск]пао1]2]1кпс1ск]Ь 49 Интеграция с МопроПВ суапЬеат, ГаЫапсоок, пнсйй^ксзутах
50 Интеграция МопдоОВ для Мобе.)8/Ехрге88.]8 МП Пат Саггоп 51 Библиотека Мопдоозе А1ех Бодал, тапиегитх, М1кНаП, Маеет 8Ьа1кН, Оюпд Ши, 81тр1ап8, ШШ 52 Интеграция М88(Д с!атй]07 53 Многопоточность агс8 54 Пул соединений Му8рь К1\уп(8шдЬ 55 Интеграция Му8фБ Аттайау, Апбгёь Епсагпасюп, Попал Наттег1е, кап 8сНшагх, ]с1гус1п, ]оЬппуСос1ег, КарП Уа(з, ЮуупГБшдЬ, Магек 8к1Ьа, Ка1ае1 Оас1о(п Васкоуаз,... 56 М-АР1 РагНат А1уат 57 Локализация Мойе.]8 Озата Вап 58 Сервер Мойе без фреймворка Назап А УоизеГ, Тау1ог Аск1еу 59 М'ос1е.]8 (ехрге88.]8) с Ап8и1аг.]8 з^йтес! 60 Ыос1е.]8 и МопдоИВ пибпцтЬЬугйах, КатепСНе!, 8а(уат 8 61 Архитектура и внутренняя работа Койе.]8 кап НпзГоу 62 Код Мойе.]8 для 8ТПШ и 8Т1ЮПТ без использования библиотек 8уат Ргабеер 63 Основы проектирования Кобе.]8 Апкиг Апаш!, р^коуьтага 64 Управление ошибками в Ыос1е.]8 Каг1еп 65 Производительность Койе.)8 Попал Напгтег1е, 1лапс Ситиз
66 Новые функции и улучшения Хойе.]з у6 сгеуИ. Витт!сУа1епс1апа, К11лт!81п§й 67 Мос1е.)8 с СОК8 Виги! 68 Мос1е.]8 с Е86 1папс (Зитиз, хат, утг, гигГух 69 Мойе.]з с Огас1е □11011011 Руководство 70 для начинающих ПО МоЙ0.]8 МгозЬап Капарайи 71 Фреймворки 1мойе.]8 йгкгее 72 История Хойе.]'з Ке1ит Зелапауаке 73 Маршрутизация в Хойе.^з раг1ай пеирапе еуакоске), АЫизкек ]ат, Л]8, Лтгеезк 74 Ыос1е.]8 с Кей1з Гуар. Апкиг Апапс!. Аза!'Мапа ззеп. ЛГез Нога!, сспокез, СВ., Спзйап СауаШ, Паук! С., ВгакаЗАМ, Епс Гогйп,... 5огапруа1а АЬЬэзаН, 8Й11_1еагшпр зиЬЬи, 75 прт !Ье12, Йо, ИпЗдиа!, игай, У1айМеасзи, Узеуо1ой Сокпйгпт, ХУазаЫ Еап, Уегко Ра1та суапЬеат. §и1епа, }окп Утсеш 1агсИп. 76 птт — Мойе Уегзюп Мападег Ьшз СтОП7.а1е7, ргапзрасЬ, 81ю#9, Тизкаг Сирга 77 0 А и 111 2.0 1уеЫа Апкиг Апапа, Аза! Мапаззеп, Скапсе 8пои’, еГейег, Епс Зтекепз, Р1опап 78 раска§е.]зоп Наттег1е, |ау1ет СкаийЪап, Коте], 1аипуз, теггобе, ОгЛУ. КатепСкеГ, КоЬЫе.... 79 Разбор ар1уменюв командной строки угГнпП) 80 Интеграция РаззроП Лпк11 капа. Соттиппу, Еёо МагГт, М. А Соп!е1го, Кира11 Ретаге, з!ик!1аг Ьапза! 81 раз8рогГ.)з Ней
82 Проблемы производительности Ап(епка, ЗСетеЬаеу 83 Интеграция с РозГдгеЗр!. Мйозкап Капара(к1 84 Структура проекта батН)07 85 Рпзк-уведомления Мано Когк 86 КеасШпе 4444, Сга1§ Ауте, Нонан Напнпейе, регеЬ 87 Удаленная отладка в Иойе.]8 Ккк, УооУоо 88 КецшгеО РкШр Согпейиз С1оуег 89 Дизайн КЕ8ТГи1 АР1: Лучшие практики Ггезк5447, шккашка зшдк бео 90 Структура Коше-СотгоИег- Зеппсе для Ехрге88.)8 потапЬшкиззет Маршрутизация 91 а]ах-запросов с помощью Ехргезз .]8 КатепСкеГ, ЗупарзеТеск 92 Запуск Иос1е.]8 как сервиса Ви/Ш Обеспечение актдйе, Деупи1169, Нонан Наттейе, 93 безопасности ]о1лп 31едег8, Микезк Зкагта, Раи)у Сагс1а, приложений Ио(1е.]8 РеГег С, ргапзраск, КатепСкеГ, 51тр1апз 94 Отправка веб-уведомлений Ноиззет Уак1аош 95 Отправка файлового потока клиенту Везкоу Наппа 96 5едие112е.]8 Нкга, Нкозкап Капарайй, хат 97 Простой СКИБ АР1 на основе КЕ8Т 1сетап 98 Связь через Зоскекю Роттп, К.).))ауузоп Синхронное 99 и асинхронное программирование в Мойе.] 8 Сга1§ Ауге, Уедет 100 ТСР-сокеты В Ткну
101 Шаблонные фреймворки А1коп Мо^-ат 102 Удаление Мо<1е.)8 }о!ш УшсеШ }агйш. КатепСйеГ, 8пи$§1е808, Тгеуог С1агке 103 Фреймворки для модульного тестирования Пахйй Хи, Е1опав Наштег1е, зкп1аа 104 Сценарии использования Мойе.)8 упПр гоук! 103 Использование Вгои'зегйу для устранения ошибки ‘гецшгей’ в браузерах В1& Иийе 106 Использование П5Хо(1е для размещения веб-приложений Мойе.р в 118 реСеЬ 107 Использование потоков суапЬеат. Ви1у Ктзку, еГейег, щИт, К1тот81п§Ь, Мах, 7.е КиЬеиз 108 Использование УУеЬЗоске! с Мойе ]8 Котуап Наг1еу 109 Веб-приложения с Ехргезз А1коп Мо^хузт, Мех Ъо^ап, а1ех12. Апйгез С. Утезса, АрЬ, АзаЕМапаззеп, Ва1зи, Ьексе. Ьпаптеагпз, Соттиппу, Сгащ Луге, Баше! Уегет, Йеупи1169, ЕуегеПзз,. 110 Аутентификация Шшйомге в Мойе.]8 С} Нагпез 111 Менеджер пакетов Уагп Ап<1геуу Вгооке, зкп1аа
Справочное издание Аныцтамалык, басылым Серия «Быстрый старт в программирование» 1\100Е.]5 САМОЕ ПОЛНОЕ РУКОВОДСТВО ДЛЯ ВЕБ-РАЗРАБОТЧИКОВ В ПРИМЕРАХ ОТ СООБЩЕСТВА 5ТАСК ОУЕКЕЬОУУ СИветсгвенный за вьтуск И. Резько Ответственный редактор: А. Ходяковс. Оформление обложки: С.Дарсич Подписано в печать 13.10.2025 Формат 70х100’/16. Бумага офсетная Печать офсетная. Гар| :итура Мото 5епТБет|Сопс1еп5ес1. Усл. печ л. 39. Тираж 1500 экз. Заказ № Общероссийский классификатор продукции ОК-034-2014 (КПЕС 2С08); 58.11.1 — книги, брошюры печатные. Изготовлено в 2026 г Произведено в Российской Федерации. Изготовитель: ООО «Издательство АСТ». 129085, Российская Федерация, г. Москва, Звёздный бульвар, дом 21, строение 1, комната 705, пом. I, 7 этаж. Адрес места осуществления деятельности по изготовлению продукции: 123112, Российская Федерация, г. Москва, Пресненская набережная, д 6, стр. 2, Деловой комплекс «Империя», 14,15 этаж. Наш электронный адрес азк@а$1:.ги Наш сайт- и'мл/.азГ.ги Интернет-магазин: \л/и/от.Ьоок24.ги 0нд|рушг «Издательство АСТ» ЖШК, 129085, Ресей Федерациясы, Мэскеу, Звёздный бульвары, 21-уй, 1-к.урылыс, 705-болме, I уй-жай, 7-к,абат -’Н1м енд'ру кызмет1н жузеге асыру мекенжайы: 123112, Ресей Федерациясы, Маскеу, 11ресненская жаг., 5-уй, 2-к.ур, «Империя» ккерлж кешен!, 14,15-^абат. Б|зд!ц электрондык, мекенжаймыз: иад'л.азГ.ги Е-та||. азк@аз1.ги Интернет-магазин: \лллл/лосок24.ги Ингернет-дукен: у\лллл/.Ьоок24.кг Импортер в Республику Казахстан, дистрибьютор и представитель по приему претензий на продукцию в Республике Казахстан: ТОО «РДЦ-Алматы». г. Алматы ул. Домбровского, 3«а», литер Б офис 1. К,азак,стан Республикасына импорттаушы дистрибьютор жэне 1Саза1\стан Республикасында ен1мге шагымдар к,абылдау жен!ндеп ок1л: «РДЦ-Алматы» ЖШС. Алматы к,., Домбровский кеш., 3«а» Б литер!, офис 1. Тел.: 8(727) 2 51 59 90,91, факс: 8 (727) 251 59 92 Iшк; 107; Е-таП: Р0С-А1гпаТу@ек5ГП0.кг, штмЪоок24.к/ (Энд|рклген жылы: 2026. Он1мн1ц жарамдылык, мерз1м1 шектелме! ен. Сертификаттауга жатпайдо! Ресей Федерациясында 0нд!р1лген.
Перед вами нечто гораздо большее, чем просто пособие по веб-разработ- ке. Данное издание — это практическое руководство по работе в широко распространенной кроссплатформенной среде выполнения ЫоаеД, в основе которой лежит язык программирования ]ауа8спр1. Благодаря ему начинающие программисты смогут быстро поднять свой уровень профессиональных зна- ний в области создания серверов, АР1, разработки веб-приложений, работы с базами данных и менеджерами пакетов МРМ и Уагп, а также использования УУеЬБоскеб Мос1е.]5 — это универсальный и уникальный инструмент как РгогИепб-, так и Ьаскепб-разработки, позволяющий реализовывать масштабные веб-порталы с использованием единого стека технологий и применяемый крупнейшими мировыми 1Т-компаниями. А поскольку в книге, основанной на практических примерах ст экспертов международного сообщества Бтаск САегПож собрано буквально все — от основ работы с Мебель до последних профессиональных инноваций, она будет полезна как начинающим, так и опытным программи- стам, которые стремятся наиболее продуктивно реализовать свой потенциал в сфере веб-разработки. КНИГИ ДЛЯ ЛЮБОГО НАСТРОЕНИЯ ЗДЕСЬ: «'л»7.а=1.ги / л«л.Ьсок2/'.ги Я ук.сот/|2с!а1е151уоа51 0 ок.ги/|7^а1е151уоа51 ИЗДАТЕЛЬСКАЯ ГРУППА АСТ 13ВЫ 978-5-17-162197-1 9 7851 71 621 971