Что за файл index js
Эта вторая статья в нашем учебнике Express показывает, как создать каркас проекта веб-сайта, который позже можно будет заполнить с помощью путей сайта, шаблонов представлений и обращений к базе данных.
Необходимые знания: | Установить среду разработки Node. Просмотреть учебник Express. |
---|---|
Задача: | Научиться запускать свои проекты используя Express Application Generator. |
Обзор
В этой статье показано, как создать каркас сайта с помощью средства Express Application Generator. Каркас затем можно будет заполнить с помощью путей сайта, шаблонов/представлений и обращений к базе данных. Мы используем это средство для создания основы нашего сайта Local Library. К основе будет добавлен код, необходимый сайту. Создание каркаса чрезвычайно просто -- требуется только вызвать генератор в командной строке, указав имя нового проекта, дополнительно можно указать также движок шаблона сайта и генератор CSS.
Далее показано, как вызвать генератор приложений, и даётся небольшое пояснение различных вариантов представлений и CSS. Мы поясним структуру каркаса веб-сайта. В конце мы покажем, как запустить веб-сайт, чтобы убедиться, что он работает.
Замечание: Express Application Generator — не единственный генератор Express-приложений, и созданный проект --не единственный жизнеспособный способ организации ваших файлов и каталогов. Однако созданный сайт имеет модульную структуру, которую легко понять и расширить. О минимальном Express приложении смотрите Hello world example в документации Express.
Применение генератора приложений
Вы уже должны были установить express-generator , читая статью установка среды разработки Node. Напомним, что генератор установлен с помощью менеджера пакетов NPM, при выполнении команды:
E xpress-generator имеет ряд параметров, которые можно увидеть, выполнив команду express --help (или express -h):
Команда express создаст проект в текущем каталоге с использованием (устаревшего) движка представления Jade и обычного CSS. Если указать express name , проект будет создан в подкаталоге name текущего каталога.
Можно выбрать движок представления (шаблон), используя -- view; параметр -- css позволяет выбрать движок для создания CSS.
Примечание: Другие опции ( --hogan , --ejs , --hbs и пр.) для выбора шаблонизатора устарели. Используйте --view (или -v )!
Какой движок представлений следует использовать?
Express-generator даёт возможность сконфигурировать несколько популярных движков, включая EJS, Hbs, Pug (Jade), Twig, и Vash, но по умолчанию выбран Jade. Экспресс сразу после установки может поддерживать большое количество и других шаблонизаторов.
Примечание: При желании использовать шаблонизатор, который не поддерживается генератором, просмотрите документацию Using template engines with Express и документацию для нужного шаблонизатора.
Как правило, следует выбрать шаблонизатор, который имеет всю необходимую вам функциональность и обеспечивает вам высокую производительность - так же, как вы выбираете любой другой компонент! Некоторые критерии для сравнения шаблонизаторов:
- Время до получения результата — если ваша команда уже имела дело с шаблонизатором, то, скорее всего, продуктивнее будет использовать этот шаблонизатор. Если нет, тогда следует учесть все относительные сложности изучения кандидатов в шаблонизаторы.
- Популярность и активность — проверьте популярность движка, возможно, у него есть активное сообщество. Очень важно иметь поддержку для движка, если у вас возникнут проблемы в течении жизни веб-сайта.
- Стиль — некоторые шаблонизаторы используют особую разметку для отображения вставленного контента внутри "обычного" HTML, а другие строят HTML, используя специальный синтаксис (например, используя отступы или блочные имена).
- Производительность и время интерпретации.
- Особенности — следует выбирать движок с учётом таких особенностей:
- Наследование макета: позволяет определить базовый шаблон и затем наследовать только те части, которые отличаются для конкретной страницы. Это, как правило, лучший подход, чем создание шаблонов путём включения нескольких необходимых компонентов или создания шаблона с нуля каждый раз.
- Поддержка «Include»: позволяет создавать шаблоны, включая другие шаблоны.
- Краткий синтаксис управления переменными и циклами.
- Возможность фильтровать значения переменных на уровне шаблона (например, делать переменные в верхнем регистре или форматировать значение даты).
- Возможность создавать выходные форматы, отличные от HTML (например, JSON или XML).
- Поддержка асинхронных операций и потоковой передачи.
- Возможность использования как на клиенте, так и на сервере. Возможность применения движка шаблона на клиенте позволяет обслуживать данные и выполнять все действия или их большую часть на стороне клиента.
Совет: В интернете множество ресурсов, которые помогут сравнить различные варианты!
Для этого проекта мы используем шаблонизатор Pug (в прошлом назывался Jade) -- один из популярнейших Express/JavaScript шаблонизаторов, который поддерживается в Express-generator "из коробки".
Какие шаблонизаторы CSS следует использовать?
Express Application Generator позволяет создавать проекты, настроенные для применения шаблонизаторов CSS: LESS, SASS, Compass, Stylus.
Примечание: простой CSS имеет некоторые ограничения, затрудняющие выполнение задач. Шаблонизаторы CSS позволяют использовать более эффективный подход для создании таблиц стилей CSS, но требуют компиляции файлов таблиц стилей в стандартный CSS для применения в браузере.
Как и в случае с шаблонизаторами сайта, следует применять шаблонизатор, обеспечивающий высокую производительность работы. В этом проекте мы используем обычный CSS (по умолчанию), поскольку простота наших требований к CSS не оправдает применение чего-то более сложного.
Какую базу данных следует использовать?
Сгенерированный код не использует и не содержит в себе какой-либо базы данных. Express может использовать любой движок базы данных, который поддерживается Node (Express не предъявляет каких-либо особых требований к базе данных).
Мы обсудим взаимодействие с базой данных в следующей статье.
Создание проекта
Разрабатывая пример - приложение Local Library, мы построим проект с именем express-locallibrary-tutorial. Используем библиотеку шаблонов Pug, а движок CSS применять не будем.
Выберем место для нового проекта — каталог express-locallibrary-tutorial - и выполним команду:
Будет создан каталог express-locallibrary-tutorial и выведен список созданных внутри каталога проектных файлов .
После списка файлов генератор выведет инструкции для установки зависимостей (указанных в файле package.json) и запуска приложения (инструкции предназначены для Windows; для Linux/Mac OS X они могут слегка отличаться).
Запускаем каркас сайта
Сейчас у нас есть готовый каркас проекта. Сайт пока ничего не делает, но его стоит запустить, чтобы убедиться в его работоспособности.
-
Прежде всего установим зависимости (команда install запросит все пакеты зависимостей, указанные в файле package.json).
У нас получилось веб-приложение на базе Express, работающее по адресу localhost:3000.
Примечание: Можно также запустить приложение командой npm start . Переменная DEBUG, указанная в примере, включает логирование в консоль для дальнейшей отладки. Так, при посещении страницы веб-приложения, вы увидите похожий вывод в консоль:
Обеспечиваем
перезапуск сервера при изменении файловЛюбые изменения, внесённые на веб-сайт Express, не будут отображаться до перезапуска сервера. Остановка (Ctrl-C) и перезапуск сервера каждый раз после внесения изменений быстро становится раздражающей, поэтому стоит автоматизировать перезапуск.
Одно из самых простых средств для этого --
nodemon. Его обычно устанавливают глобально (так как это "инструмент"), но сейчас мы установим его и будем применять локально как зависимость разработки, так что любые разработчики проекта получат его автоматически при установке приложения. Выполним следующую команду (предполагаем, что мы находимся в корневом каталоге):Если вы предпочитаете установить nodemon глобально, не только для этого проекта, надо выполнить команду
В файле package.json проекта появится новый раздел с этой зависимостью (на вашей машине номер версии nodemon может быть другим) :
Поскольку nodemon не установлен глобально, его нельзя запустить из командной строки (пока мы не добавим его в путь), но его можно вызвать из сценария NPM, так как NPM знает все об установленных пакетах. Раздел scripts в файле package.json исходно будет содержать одну строку, которая начинается с "start" . Обновите его, поставив запятую в конце строки, и добавьте строку "devstart", показанную ниже:
Теперь можно запустить сервер почти так же, как и ранее, но командой npm run devstart:
Примечание: Сейчас после изменения любого файла проекта сервер будет перезапускаться (или можно самостоятельно перезапустить его, введя rs в командной строке). Вам всё равно придётся обновить страницу в браузере .
Теперь мы должны выполнять команду " npm run <scriptname>" а не просто npm start , поскольку "start", это, по сути, команда NPM, сопоставленная сценарию в файле package.json. Можно заменить команду в сценарии "start", но, так как мы хотим использовать nodemon только во время разработки, разумно создать новую команду сценария.
Созданный проект
Давайте посмотрим на созданный проект.
Структура каталогов
Далее файлы описаны более подробно.
package.json
Файл package.json указывает зависимости приложения и содержит другие данные:
Зависимости включают пакет express и пакет для выбранного движка представления (pug). Кроме того, указаны пакеты, полезные во многих веб-приложениях:
Раздел "scripts" определяет скрипт" start", выполняемый при запуске сервера командой npm start . Можно видеть, что самом деле выполняется команда node ./bin/www. Кроме того, определяется script "devstart", который вызывается командой npm run devstart . Запускается тот же файл ./bin/www ,но командой nodemon вместо node.
Файл www
Файл /bin/www – это входная точка приложения. Сначала в файле создаётся объект основного приложения, расположенного в app.js — выполняется app= require(./ app ).
Примечание: require() -- это глобальная функция node для импорта модулей в текущий файл. Для модуля app.js указан относительный путь, а расширение файла по умолчанию (.js) опущено.
Файл app.js
Этот файл создаёт объект приложения express (с именем app , по соглашению), настраивает приложение и промежуточное ПО, а затем экспортирует приложение из модуля. В приведённом ниже коде показаны только те части файла, которые создают и экспортируют объект приложения:
Рассмотрим детали файла app.js. Сначала при помощи require(. ) выполняется импорт некоторых полезных библиотек node: express, serve-favicon, morgan, cookie-parse, body-parser (они ранее были загружены для нашего приложения командой npm install), а также path из основной библиотеки node (применяется для разбора путей каталогов и файлов).
Затем require запрашивает модули из каталога путей route. Эти модули и файлы содержат код для обработки конкретного набора соответствующих путей (URL маршрутов). Если мы расширим каркас приложения, например, чтобы получить список книг библиотеки, нам следует добавить новый файл для обработки пути, связанного с книгами.
Примечание: Здесь мы только импортируем модули. В действительности эти пути ещё не используются — это произойдёт в файле несколько позже.
Далее, импортированные модули express применяются для создания объекта app, который потом устанавливает движки-шаблоны представления. Установка движков состоит их двух частей. В первой мы задаём значение 'view', указывая папку, в которой будут размещаться шаблоны (у нас это /views). Во второй мы задаём значение движка 'view engine', указывая на библиотеку шаблона (у нас — "pug").
Теперь, когда промежуточные библиотеки настроены, мы добавляем (импортированный ранее) код обработки путей в цепочку обработки запросов. Импортированный код будет задавать отдельные пути для разных частей сайта:
Примечание: . пути, указанные выше ('/' и ' /users' ) рассматриваются как префиксы путей, определённых в импортированных файлах. Так, например, если импортированный модуль users определяет путь для /profile, для доступа следует указать /users/profile. Мы поговорим подробнее о путях в последующей статье.
Объект app приложения Express теперь полностью настроен. Остался последний шаг - добавить его к экспортируемым элементам модуля (это позволит импортировать его в файле /bin/www).
Пути (Routes)
Файл путей /routes/users.js приведён ниже (файлы путей имеют сходную структуру, поэтому нет необходимости приводить также index.js). Сначала загружается модуль Express, затем он используется для получения объекта express.Router. После этого для этого объекта задаётся путь, и, наконец, объект-роутер экспортируется из модуля (именно это позволяет импортировать файл в app.js):.
Стоит отметить, что колбэк-функция имеет третий аргумент - ' next ', т. е. является не простой колбэк-функцией, а колбэк-функцией промежуточного модуля. Пока третий аргумент не используется, но будет полезен в дальнейшем, если мы захотим создать несколько обработчиков пути '/' .
Представления (шаблоны)
Файлы преставлений (шаблонов) хранятся в каталоге /views (это указано в app.js ) и имеют расширение .pug. Метод Response.render() выполняет указанный шаблон, передавая объекту значение именованной переменной, и затем посылает результат как ответ. В коде из /routes/index.js (приводится ниже) можно увидеть, что роут отвечает, используя шаблон "index" с переданным значением переменной "title" из шаблона.
Шаблон для пути '/' приведён ниже (файл index.pug). О синтаксисе мы поговорим позже. Сейчас важно знать, что переменная title со значением 'Express' помещена в определённое место шаблона.
Мини-тест
Итоги
Сейчас создан каркас проекта Local Library. Мы проверили, что он запускается с использованием Node. Но главное, что вы поняли структуру проекта, и знаете, где и как добавить пути и представления для нашей локальной библиотеки.
Browserify позволяет делать require («модули») в браузере, объединяя все ваши зависимости
Я не понял ни слова из предложения и стал разбираться, как это может помочь мне как разработчику.
Цель статьи — рассказать о контексте, в котором инструменты в JavaScript развивались вплоть до 2017-го. Начнём с самого начала и будем делать сайт, как это делали бы динозавры — безо всяких инструментов, на чистом HTML и JavaScript. Постепенно станем вводить разные инструменты, поочерёдно рассматривая решаемые ими проблемы. Благодаря историческому контексту вы сможете адаптироваться к постоянно меняющемуся ландшафту JavaScript и понять его.
Олдскульное использование JavaScript
Давайте сделаем «олдскульный» сайт, используя только HTML и JavaScript. В этом случае придётся вручную скачивать и связывать файлы. Вот простой index.html, ссылающийся на JavaScript-файл:
Строка <script src="https://habr.com/ru/company/vk/blog/340922/index.js"></script> ссылается на JavaScript-файл index.js, находящийся в той же директории:
Больше для создания сайта ничего не нужно! Допустим, вы хотите добавить стороннюю библиотеку moment.js (меняет формат дат для удобочитаемости). Можно, к примеру, использовать в JS функцию moment :
Но так вы всего лишь добавили moment.js на свой сайт! На главной странице moment.js приведены инструкции:
Мда, в разделе «Установка» много всего написано. Но пока это проигнорируем, потому что можно добавить moment.js на сайт, скачав файл moment.min.js в ту же директорию и включив его в наш файл index.html.
Обратите внимание, что moment.min.js загружается до index.js, поэтому в index.js вы можете использовать функцию moment :
Вот так мы создавали сайты с JS-библиотеками. Процедура была простой для понимания, но раздражала необходимость искать и скачивать новые версии библиотек при каждом их обновлении.
Использование диспетчера пакетов из JavaScript (npm)
Примерно с 2010-го развиваются несколько конкурирующих диспетчеров пакетов, помогающих автоматизировать скачивание и обновление библиотек из центрального репозитория. Bower был самым популярным в 2013-м, но к 2015-му уступил пальму первенства npm. Надо сказать, что с конца 2016-го yarn широко используется в качестве альтернативы интерфейсу npm, но под капотом он всё ещё работает с npm-пакетами.
Изначально npm создавался как диспетчер пакетов специально для node.js, среды исполнения JavaScript, предназначенной для серверов, а не фронтенда. Так что довольно странно применять его в качестве диспетчера пакетов для библиотек, запускаемых в браузерах.
Примечание: обычно диспетчеры пакетов подразумевают использование командной строки, что раньше никогда не требовалось при разработке фронтенда. Если вы никогда с ней не работали, то для начала можете почитать это руководство. Как бы там ни было, в современном JavaScript важно уметь пользоваться командной строкой (и это также открывает двери в другие области разработки).
Давайте посмотрим, как использовать npm для автоматической установки moment.js вместо скачивания вручную. Если у вас установлен node.js, то у вас уже есть и npm, так что можете в командной строке перейти в папку с файлом index.html и ввести:
Вам зададут несколько вопросов (можно просто жать Enter, оставляя ответы по умолчанию), а потом сгенерируется новый файл package.json. Это конфигурационный файл, в котором npm сохраняет всю информацию о проекте. По умолчанию содержимое package.json выглядит так:
Для установки JS-пакета moment.js можно воспользоваться инструкциями с сайта npm, введя в командной строке:
Эта команда делает две вещи:
- Скачивает весь код из пакета moment.js в папку под названием node_modules.
- Автоматически модифицирует файл package.json для отслеживания moment.js в качестве проектной зависимости.
Это полезно, когда вы станете работать над проектом совместно с другими разработчиками: вместо общего доступа к папке node_modules (которая может быть очень большой) достаточно открыть доступ к файлу package.json, и другие разработчики смогут автоматически устанавливать нужные пакеты с помощью команды npm install .
Теперь нам больше не нужно вручную скачивать moment.js с сайта, npm помогает скачивать и обновлять автоматически. Если посмотрим в папку node_modules, то в директории node_modules/moment/min увидим файл moment.min.js. Это означает, что в index.html можно сослаться на скачанную через npm версию moment.min.js:
Приятно, что теперь мы можем автоматически скачивать и обновлять наши пакеты с помощью npm и командной строки. Но теперь надо копаться в папке node_modules, чтобы узнать местонахождение каждого пакета и вручную прописать в HTML. Это довольно неудобно, так что давайте посмотрим, как можно автоматизировать этот процесс.
Использование бандлера (bundler) JavaScript-модулей (webpack)
В большинстве языков программирования есть возможность импортирования кода из одного файла в другой. Изначально в JS такой возможности не было, потому что этот язык разрабатывался только для исполнения в браузере, без доступа к файловой системе на клиентской машине (по причинам безопасности). Так что долгое время для организации JS-кода в нескольких файлах требовалось загружать каждый файл с глобально доступными переменными.
Именно это мы и делали в вышеописанном примере с moment.js example — весь файл moment.min.js загружается в HTML, где определяется глобальная переменная moment, которая потом становится доступна любому файлу, загруженному после moment.min.js (вне зависимости от того, нужна ли она для обращения к ним).
В 2009-м был запущен проект CommonJS, в рамках которого планировалось создать спецификации внебраузерной экосистемы для JavaScript. Большая часть CommonJS была посвящена спецификациям модулей, позволявших JS импортировать и экспортировать код между файлами как во многих других языках, без обращения к глобальным переменным. Самой известной реализацией модулей CommonJS стал node.js.
Как уже говорилось, node.js — это среда исполнения JavaScript, разработанная для запуска на серверах. Вот как сначала выглядело использование node.js-модулей: вместо загрузки всего moment.min.js в скриптовом теге HTML можно было грузить JS-файл напрямую:
Загрузка модулей работает прекрасно, поскольку node.js — это серверный язык с доступом к файловой системе. Также ему известно расположение всех npm-модулей, поэтому вместо require('./node_modules/moment/min/moment.min.js) можно писать просто require('moment') .
Всё это прекрасно, но если вы попробуете использовать приведённый код в браузере, то получите ошибку, в которой говорится, что require не определён. У браузера нет доступа к файловой системе, поэтому такая загрузка модулей реализована очень хитро: файлы нужно грузить динамически, синхронно (замедляет исполнение) или асинхронно (могут быть проблемы с синхронизацией).
И здесь появляется бандлер (bundler). Это инструмент для сборки модулей в единые пакеты, имеющий доступ к файловой системе. Получающиеся пакеты совместимы с браузером, которому не нужен доступ к файловой системе. В нашем случае бандлер нужен для поиска всех выражений require (имеющих ошибочный, с точки зрения браузера, JS-синтаксис) и замены на настоящее содержимое каждого требуемого файла. В финале мы получаем единый JS-файл без выражений require !
Самым популярным бандлером сначала был Browserify, выпущенный в 2011 г. Он был пионером в использовании node.js-выражений require во фронтенде (это позволило npm стать самым востребованным диспетчером пакетов). К 2015-му лидером стал webpack (ему помогла популярность фронтенд-фреймворка React, использующего все возможности этого бандлера).
Давайте посмотрим, как с помощью webpack заставить работать в браузере наш пример с require('moment') . Сначала установим бандлер в проект. Сам по себе webpack — это npm-пакет, так что введём в командной строке:
Обратите внимание на аргумент --save-dev — он сохраняет бандлер как зависимость среды разработки, так что она не понадобится на production-сервере. Это отразится в файле package.json, который обновится автоматически:
Теперь webpack установлен в качестве одного из пакетов в папке node_modules. Можно запускать его из командной строки:
Эта команда запускает webpack вместе с файлом index.js, находит все выражения require и заменяет соответствующим кодом, чтобы получился единый выходной файл bundle.js. Это означает, что нам больше не нужно использовать в браузере файл index.js, поскольку он содержит некорректные выражения require . Вместо него мы возьмём bundle.js, что должно быть учтено в index.html:
Если обновите браузер, то всё будет работать, как и прежде.
Обратите внимание, что нам нужно выполнять webpack-команду при каждом изменении index.js. Это утомительно, и чем более продвинутые возможности webpack мы будем использовать (вроде генерирования схемы источников для отладки исходного кода из транспилированного), тем больше станет утомлять постоянный ввод команд. Webpack может считывать опции из конфигурационного файла webpack.config.js в корневой директории проекта:
Теперь при каждом изменении index.js можно запускать webpack такой командой:
Больше не нужно определять опции index.js и bundle.js , потому что webpack загружает их из webpack.config.js. Так лучше, но всё равно утомительно вводить эту команду при каждом изменении кода. Надо ещё больше всё упростить.
Такой подход очень сильно повлиял на рабочий процесс. Мы уже не загружаем внешние скрипты с помощью глобальных переменных. Все новые JS-библиотеки будут добавлены в JavaScript с помощью выражений require , а не через теги <script> в HTML. Наличие единственного JS-пакета зачастую повышает производительность. А после добавления этапа сборки появилось несколько мощных возможностей, которые тоже можно использовать в процессе разработки.
Транспилирование кода ради новых возможностей языка (babel)
Транспилирование — это конвертация кода в другой, похожий язык. Это важная часть фронтенд-разработки: поскольку в браузерах медленно появляются новые фичи, были созданы языки с экспериментальными возможностями, которые транспилируются в совместимые с браузерами языки.
К примеру, для CSS есть Sass, Less и Stylus. Для JavaScript самым популярным транспилятором какое-то время был CoffeeScript (выпущен около 2010), а сегодня многие используют babel или TypeScript. CoffeeScript улучшает JavaScript за счёт серьёзного изменения языка — опциональное использование скобок, значимые отступы (whitespace) и т. д. Babel — это не новый язык, а транспилятор, который транспилирует JavaScript следующего поколения, имеющего возможности, пока недоступные во всех браузерах (ES2015 и выше), в старый и более совместимый JavaScript (ES5). Typescript — это язык, по существу аналогичный JavaScript следующего поколения, но с добавлением опциональной статичной типизации. Многие предпочитают babel, потому что он ближе к ванильному JavaScript.
Рассмотрим пример использования babel на этапе webpack-сборки. Сначала установим транспилятор (это npm-пакет) в проект:
Обратите внимание, что мы установили три отдельных пакета в качестве зависимостей среды разработки:
- babel-core — основная часть babel;
- babel-preset-env — пресет, определяющий, какие новые возможности JavaScript нужно транспилировать;
- babel-loader — пакет, позволяющий babel работать с webpack.
Сконфигурируем webpack для использования babel-loader , отредактировав файл webpack.config.js:
Синтаксис может вас запутать (к счастью, этот код не нужно часто редактировать). По сути, мы просим webpack найти все .js-файлы (за исключением лежащих в папке node_modules) и применить babel-транспилирование с помощью babel-loader и пресета babel-preset-env . Подробнее о синтаксисе конфигурирования webpack можно почитать здесь.
Всё настроено, можно использовать в нашем JavaScript возможности ES2015! Пример шаблонной строки (template string) ES2015 в файле index.js:
Для загрузки модулей можем воспользоваться выражением импортирования ES2015 вместо require , сегодня это встречается во многих кодовых базах:
В этом примере синтаксис import мало отличается от синтаксиса require , но import гибче в более сложных ситуациях. Раз мы изменили index.js, нужно снова запустить webpack:
Теперь обновим index.html в браузере. Когда я писал эту статью, большинство браузеров поддерживали все возможности ES2015, так что трудно сказать, заслуга ли это babel. Можете протестировать в старых браузерах вроде IE9 или поискать в bundle.js строку транспилированного кода:
Здесь babel транспилировал шаблонную строку ES2015 в обычное JavaScript-объединение строк, чтобы сохранить совместимость. Наверное, не самый впечатляющий пример, но транспилирование кода — очень мощный инструмент. В JavaScript можно добавить такие впечатляющие возможности, как async/await. И хотя транспилирование иногда бывает нудным и неприятным занятием, в последние годы оно помогло сильно улучшить язык, потому что многие разработчики сегодня тестируют возможности будущего.
Мы почти закончили, но в нашем рабочем процессе ещё остались шероховатости. Ради повышения производительности нужно минифицировать получившийся после сборки бандлером файл, но это довольно простая задача. Также нужно перезапускать webpack при каждом изменении JavaScript, который быстро устаревает. Рассмотрим инструменты для решения этих проблем.
Использование средства запуска задач (task runner) (npm-скрипты)
Раз мы используем сборку при работе с модулями, имеет смысл подумать о средстве запуска задач — инструменте автоматизации разных операций процесса сборки. Во фронтенд-разработке это минификация, оптимизация изображений, прогон тестов и т. д.
В 2013-м самым популярным инструментом был Grunt, но вскоре его место занял Gulp. Оба используют плагины, играющие роль обёртки для других инструментов, которым нужна командная строка. Сегодня чаще всего применяется скриптинг, встроенный в npm, который напрямую работает с упомянутыми инструментами.
Давайте напишем npm-скрипт для упрощения работы с webpack. Для этого просто изменим package.json:
Здесь мы добавили два новых скрипта — build и watch . Для запуска сборочного скрипта введите команду:
Команда запускает webpack (с использованием конфигурации из сделанного ранее webpack.config.js) с опцией --progress , которая включает отображение прогресса в процентах, и с опцией -p для минимизации кода. Запустим скрипт watch :
Здесь используется опция --watch для автоматического перезапуска webpack при каждом изменении JavaScript-файла, это очень удобно для разработки.
Обратите внимание, что package.json может запускать webpack без указания полного пути ./node_modules/.bin/webpack, потому что node.js знает расположение каждого npm-модуля. Удобно! Сделаем ещё удобнее, установив webpack-dev-server, отдельный простой веб-сервер с функцией горячей перезагрузки. Установим в качестве зависимости среды разработки:
Теперь добавим npm-скрипт в package.json:
Можно запускать сервер разработки:
Команда автоматически открывает index.html в браузере по адресу localhost:8080 (по умолчанию). При изменении JavaScript-кода в index.js webpack-dev-server будет пересобирать свой собранный в пакет JavaScript и автоматически обновлять браузер. Это действительно экономит время, потому что можно сосредоточиться на коде, а не постоянно переключать внимание с кода на браузер, чтобы просматривать изменения.
Есть много других опций для webpack и webpack-dev-server, мы лишь прошлись по самым верхушкам (подробнее тут). Также вы можете написать npm-скрипты для других задач вроде конвертирования Sass в CSS, сжатия изображений, запуска тестов — всего, что использует командную строку. Также много классных советов можно почерпнуть из выступления Кейт Хадсон:
Заключение
Мы вкратце рассмотрели современный JavaScript. Прошли от сочетания чистых HTML и JS до использования:
- диспетчера пакетов для автоматической загрузки сторонних пакетов;
- бандлера для создания единых файлов скриптов;
- транспилятора для использования будущих возможностей JS;
- и средства запуска задач для автоматизации разных операций в процессе сборки.
Конечно, здесь много куда можно двигаться, особенно новичкам. Для них веб-разработка раньше была прекрасной отправной точкой, потому что можно было легко начать и втянуться в дело. А сегодня это уже не такое простое занятие, в частности из-за разнообразия быстро сменяющих друг друга инструментов.
Но всё не так плохо, как может показаться. Ситуация устаканивается, node-экосистема всё больше воспринимается как жизнеспособный вариант работы с фронтендом. Удобство и согласованность в работе обеспечивается использованием npm в качестве диспетчера пакетов, node-выражений require или import для работы с модулями и npm-скриптов для запуска задач. И этот рабочий процесс гораздо проще, чем было год-два назад!
Фреймворки сегодня часто поставляются с инструментами, облегчающими начало веб-разработки. В Ember есть ember-cli , оказавший огромное влияние на angular-cli из Angular, create-react-app из React, vue-cli из Vue и т. д. Эти инструменты обеспечат ваш проект всем необходимым для того, чтобы начать писать код. Но они не волшебные палочки, они лишь правильно всё настраивают для комфортной работы. Нередко вам может понадобиться дополнительно настроить конфигурацию webpack, babel и т. д. И очень важно понимать, что делает каждый из инструментов.
С современным JavaScript может быть тяжело работать, потому что он продолжает быстро меняться и развиваться. Но даже если иногда это похоже на изобретение колеса, быстрая эволюция языка помогает продвигать инновации вроде горячей перезагрузки, линтинга в реальном времени и отладки в режиме «машины времени». Сегодня интересно быть разработчиком, и я надеюсь, что эта статья поможет вам спланировать свой собственный путь.
Чтобы создать приложение Node.js на JavaScript, которое создает, загружает и запрашивает индекс поиска, используйте пакет SDK для Javascript/Typscript для Когнитивного поиска Azure.
Здесь вы найдете пошаговое руководство по созданию приложения. Вы также можете скачать исходный код и данные и запустить приложение из командной строки.
Предварительные требования
Прежде чем начать работу, убедитесь, что у вас есть следующие средства и службы:
Учетная запись Azure с активной подпиской. Создайте учетную запись бесплатно.
Служба "Когнитивный поиск Azure". Создайте новую или найдите существующую службу. Вы можете использовать бесплатную службу для выполнения инструкций, описанных в этом кратком руководстве.
Visual Studio Code или другая интегрированная среда разработки
Настройка проекта
Начните с получения конечной точки и ключа для службы поиска. Затем создайте проект с NPM, как описано ниже.
Копирование ключа и конечной точки
Вызовы к службе требуют конечную точку URL-адреса и ключ доступа при каждом запросе. В первую очередь найдите ключ API и URL-адрес для добавления в проект. При создании клиента на более позднем этапе необходимо указать оба значения.
В разделе Параметры > Ключи получите ключ администратора с полным доступом к службе, требуемый для создания и удаления объектов. Существует две взаимозаменяемых пары первичного и вторичного ключей. Вы можете использовать любую из этих пар.
Для выполнения любого запроса к службе требуется использование ключа API. Если есть действительный ключ, для каждого запроса устанавливаются отношения доверия между приложением, которое отправляет запрос, и службой, которая его обрабатывает.
Создание проекта NPM
Откройте VS Code и его встроенный терминал или другой терминал, такой как командная строка Node.js.
Создайте каталог разработки и присвойте ему имя quickstart :
Инициализируйте пустой проект с помощью NPM, выполнив:
Примите значения по умолчанию, за исключением лицензии, которая должна иметь значение MIT.
Установите dotenv для импорта переменных среды, таких как имя службы и ключ API.
Убедитесь, что вы настроили проекты и зависимости. Файл package.json должен выглядеть примерно так:
Создайте файл ENV для хранения параметров службы поиска:
Замените значение <search-service-name> именем службы поиска. Замените <search-admin-key> значением ключа, которое вы записали ранее.
Создание файла index.js
Далее мы создадим файл index.js — основной файл, в котором будет размещен наш код.
В верхней части этого файла мы импортируем библиотеку @azure/search-documents :
Далее необходимо, чтобы пакет dotenv считал параметры из файла ENV следующим образом:
После импорта данных и переменных среды мы готовы определить функцию main.
Большинство функций в пакете SDK являются асинхронными, поэтому мы делаем функцию main async . Мы также включаем main().catch() ниже функции main для перехвата и записи в журнал всех обнаруженных ошибок:
После этого можно создать индекс.
1. Создание индекса
Создайте файл hotels_quickstart_index.json. Этот файл определяет, как Когнитивный поиск Azure будет работать с документами, которые вы отправите на следующем шаге. Каждое поле идентифицируется по свойству name , и для каждого поля указано значение type . У каждого поля также есть ряд атрибутов индекса, которые определяют, может ли Когнитивный поиск Azure применять это поле для поиска, фильтрации, сортировки и определения аспектов. Большинство полей имеют простой тип данных, но некоторые (например, AddressType ) являются сложными типами, что позволяет создавать сложные структуры данных в индексе. Вы можете подробнее изучить поддерживаемые типы данных и атрибуты индекса, описанные в статье Создание индекса (REST API службы "Когнитивный поиск Azure").
Добавьте следующий код в hotels_quickstart_index.json или скачайте готовый файл.
После определения индекса мы импортируем hotels_quickstart_index.json в верхней части файла index.js, чтобы функция main могла получить доступ к определению индекса.
В рамках функции main мы создадим класс SearchIndexClient , который используется для создания индексов и управления ими для службы "Когнитивный поиск Azure".
Затем нужно удалить индекс, если он уже существует. Это распространенная практика для тестового и демонстрационного кода.
Для этого нужно определить простую функцию, которая будет удалять индекс.
Чтобы запустить функцию, извлеките имя индекса из определения индекса и передайте indexName вместе с indexClient в функцию deleteIndexIfExists() .
После этого можно создать индекс с помощью метода createIndex() .
Запуск примера
Теперь все готово к запуску примера. Выполните следующие команды в окне терминала.
Если вы скачали исходный код и еще не установили необходимые пакеты, сначала запустите npm install .
Откройте обзорные сведения о службе Поиска Azure на портале Azure. Выберите вкладку Индексы. Вы должны увидеть нечто вроде этого:
На следующем шаге вы добавите данные в индекс.
2. Загрузка документов
Как и в случае с indexDefinition, нам также нужно импортировать hotels.json в верхней части index.js, чтобы к данным можно было получить доступ в нашей функции main.
Чтобы индексировать данные в индексе поиска, нужно создать SearchClient . Хотя SearchIndexClient используется для создания индекса и управления им, для отправки документов и запроса индекса используется SearchClient .
Есть два способа создания представления данных SearchClient . Первый вариант — создать SearchClient с нуля:
Кроме того, можно использовать метод getSearchClient() из SearchIndexClient для создания SearchClient :
Теперь, когда клиент определен, отправьте документы в индекс поиска. В этом случае мы используем метод mergeOrUploadDocuments() , который будет отправлять документы или объединять их с имеющимся документом, если документ с таким ключом уже есть.
Прежде чем выполнять запросы на следующем шаге, определите функцию, чтобы программа ожидала в течение одной секунды. Это делается только для целей тестирования и демонстрации, чтобы обеспечить завершение индексирования и доступность документов в индексе для запросов.
Чтобы программа ожидала в течение одной секунды, вызовите функцию sleep , как показано ниже:
3. Поиск в индексе
С помощью созданного индекса и отправленных документов можно отправлять запросы в индекс. В рамках этого раздела мы отправим пять различных запросов в индекс поиска, чтобы продемонстрировать различные доступные части функций запросов.
Запросы записываются в функцию sendQueries() , которую мы будем вызывать в функции main следующим образом:
Запросы отправляются с помощью метода search() объекта searchClient . Первым параметром является искомый текст, а вторым — дополнительные параметры поиска.
Первый запрос выполняет поиск * , что эквивалентно поиску по всем данным, и выбирает три поля в индексе. Рекомендуется использовать select только для нужных вам полей, так как извлечение ненужных данных приведет к задержкам в запросах.
searchOptions в этом запросе также имеет значение true для параметра includeTotalCount , возвращающего количество найденных результатов поиска.
Оставшиеся запросы, описанные ниже, также нужно добавить в функцию sendQueries() . Они разделены для удобства чтения.
В следующем запросе укажите условие поиска "wifi" , а также включите фильтр, который возвращает результаты только в том случае, если состояние равно 'FL' . Результаты также упорядочиваются по данным отелей Rating .
Далее поиск ограничивается одним полем, поддерживающим поиск, с помощью параметра searchFields . Это отличный вариант, чтобы сделать запрос более эффективным, если вам требуются определенные поля.
Еще один распространенный параметр, включаемый в запрос, — facets . С помощью аспектов можно создавать фильтры в пользовательском интерфейсе, чтобы пользователям было проще узнать, какие значения они могут фильтровать.
В последнем запросе используется метод getDocument() объекта searchClient . Это позволяет эффективно получать документ по ключу.
Запуск примера
Запустите программу командой node index.js . Теперь, помимо описанных выше шагов, будут отправлены запросы и выведены в консоль их результаты.
Очистка ресурсов
Если вы работаете в своей подписке, по окончании проекта рекомендуем решить, нужны ли вам созданные ресурсы. Работающие ресурсы могут означать лишние затраты. Можно удалить отдельные ресурсы или удалить группу ресурсов, что позволит удалить весь набор ресурсов.
Просматривать ресурсы и управлять ими можно на портале с помощью ссылок Все ресурсы или Группы ресурсов на панели навигации слева.
При работе с бесплатной версией службы помните о том, что вам доступно максимум три индекса, индексатора и источника данных. Вы можете удалить отдельные элементы на портале, чтобы не превысить лимит.
Дальнейшие действия
В рамках этого краткого руководства для JavaScript вы отработали ряд задач по созданию индекса, загрузке документов в него и выполнению запросов. Чтобы продолжить обучение, воспользуйтесь приведенным ниже руководством и примером как фундаментом для освоения работы со средствами подбора (запросами опережающего ввода или автозаполнения), фильтрами и фасетной навигацией.
При создании приложений, особенно клиентских, обязательно выполнять проверку на стороне сервера. Причина в том, что нельзя полагаться только на ввод пользователя; поскольку эти входные данные иногда содержат поддельные / вредоносные данные.
Проверка на стороне клиента - отличный способ отсеять большую часть входных данных, но вам все равно необходимо выполнить проверку на стороне сервера.
Есть много способов проверить данные в Node.js, и в этой статье мы рассмотрим экспресс-валидатор . Экспресс-валидатор - это библиотека, которая обертывает validator.js и представляет его функции как набор промежуточного программного обеспечения.
Настройка проекта
В этом руководстве мы создадим демонстрационный внутренний сервер для имитации регистрации пользователя и входа в систему с помощью Node.js. Эти поля будут обеспечивать соблюдение определенных правил, и мы будем проверять полученные данные.
Обратите внимание, что мы не будем обрабатывать фактическую регистрацию пользователя и логику входа в систему, то есть сохранять данные пользователя и внедрять аутентификацию, поскольку это выходит за рамки данной статьи.
Для начала создадим папку проекта, перейдем в нее и инициализируем:
Когда закончите, мы установим следующие зависимости, выполнив команду ниже:
Посмотрим, что мы установили:
- express: легкая структура веб-приложений для Node.js. Мы будем использовать это для обработки маршрутизации на нашем внутреннем сервере.
- body-parser: ПО промежуточного слоя, которое поможет нам анализировать входящие запросы ( req.body пользователем данные) к объекту req.body.
- экспресс-валидатор: библиотека, которую мы будем использовать для обработки входящей проверки ввода.
Наконец, мы создадим index.js каталоге нашего проекта для размещения стандартного кода для создания экземпляра приложения / сервера Express:
Теперь давайте запустим это приложение с помощью node :
Если все пойдет хорошо, ваш терминал должен вывести что-то вроде:
Стандартные правила валидации с экспресс-валидатором
В этом разделе мы узнаем, как добавлять простые правила проверки и очистки к входящим запросам. Во-первых, мы хотим проверить, является ли значение, введенное в поле электронной почты, действительным или нет. Затем мы хотим, чтобы пароль содержал не менее 6 символов.
Для начала давайте добавим пару функций промежуточного программного обеспечения к нашему маршруту /login
В приведенном выше фрагменте мы используем два метода проверки:
- isEmail() : эта функция валидатора проверяет, является ли входящая строка допустимым адресом электронной почты.
- isLength() : этот валидатор проверяет, попадает ли длина строки в указанный диапазон. В нашем случае указанный диапазон составляет минимум 6 символов.
Вот некоторые из других методов, которые мы могли бы использовать:
- isNumeric() - Проверяет, является ли ввод числовым
- contains() - Проверяет, содержит ли ввод определенное значение
- isBoolean() - Проверяет, является ли ввод логическим значением
- isCurrency() - проверяет, отформатирован ли ввод в валюте.
- isJSON() - Проверяет, является ли ввод JSON
- isMobilePhone() - Проверяет, является ли введенный действительный номер мобильного телефона.
- isPostalCode() - Проверяет, является ли введенный почтовый индекс действительным.
- isBefore() и isAfter() - проверяет, находится ли дата до или после другой даты
Есть и другие, но они, вероятно, покрывают большую часть ваших потребностей в валидации.
Чтобы адреса электронной почты, предоставленные пользователем, не содержали шума и нарушений, мы добавим дезинфицирующее средство в наше поле электронной почты, как показано в приведенном выше фрагменте. Метод normalizeEmail() помогает преобразовать введенные электронные письма в стандартный утвержденный формат. Это означает, что если пользователь вводит, например, [email protected] , она будет канонизирована на [email protected] .
Validator.js предлагает некоторую гибкость , как этот вариант может быть переключена off или on но установлена on умолчанию. Существует множество вариантов нормализации, которые вы можете попробовать, если планируете нормализовать ввод. Если вы хотите узнать больше о других функциях валидаторов / дезинфицирующих средств, вы можете ознакомиться с официальной документацией Validator.js.
Для начала давайте создадим нашу конечную точку регистрации пользователей, добавив следующий фрагмент в наш файл index.js
custom () Метод
Чтобы убедиться, что наши пользователи вводят уникальные имена пользователей во время регистрации, мы не можем использовать стандартные методы, заимствованные из методов Validator.js, поскольку нет метода для их проверки.
Начнем с отказа от обещания:
В приведенном выше фрагменте кода мы вызываем метод find() в схеме Mongoose модели User, чтобы проверить, существует ли уже введенное клиентом имя пользователя в нашей базе данных.
Хотя MongoDB автоматически обнаружит это, если поле имени пользователя было помечено как уникальное при указании схемы базы данных. Рекомендуется обработать это до того, как оно попадет в базу данных, чтобы наше приложение не завершилось преждевременно.
В качестве альтернативы вы можете создать исключение, чтобы указать недопустимый ввод:
withMessage () Метод
Давайте применим это с помощью реальных методов к нашему примеру:
Давайте сделаем еще один запрос с неверным паролем и уже используемым именем пользователя:
Проверка схемы с помощью экспресс-валидатора
Проверка схемы предлагает более чистый подход к проверке данных. Вместо того, чтобы вызывать множество функций, мы указываем правила проверки для каждого поля и передаем схему в одну функцию промежуточного программного обеспечения, называемую checkSchema() .
В приведенном ниже фрагменте мы будем создавать схему проверки для конечной точки регистрации пользователя:
Теперь мы можем продолжить и использовать эту checkSchema() для проверки данных при регистрации:
Если вам нужно лишь небольшое количество проверок и вы хотите, чтобы это было просто, вы можете использовать методы. Если вам нужно выполнить огромное количество проверок, это будет более читабельно, если вы воспользуетесь проверкой схемы.
express-validator позволяет стандартизировать ответы на ошибки валидации. Это означает, что вы можете создавать свои функции промежуточного программного обеспечения для выполнения проверок и обработки ошибок проверки.
Примером того, как это можно сделать, является создание функции validate() которая будет принимать все наши валидаторы и запускать их параллельно с помощью Promise.all() :
Теперь наша функция проверки создана, и мы можем повторно использовать ее на нескольких маршрутах. Применим его к нашим маршрутам входа и регистрации:
Следуйте за нами на нашей фан-странице, чтобы получать уведомления каждый раз, когда появляются новые статьи. Facebook1- Подготовка перед тем, как начать
Это первый урок в серии инструкции по Node.js. Есть некоторые подготовки перед тем, как начать, некоторые программные обеспечения нужно установить на вашем компьютере. После установки мы выполним практику первого урока "Hello Node.js".
Рекомендуется вам прочитать мое введение про NodeJS ниже, перед тем как продолжить данный урок. Оно поможет вам получить общий обзор про NodeJS.
Чтобы изучить NodeJS для начала вам нужно скачать и установить его на вашем компьютере.
Atom это текстовый редактор (и исходный код), который поддерживает plugins (плагины) позволяющие вам программировать NodeJS приложения. Он был разработан с помощью GitHub, первая версия 1.0 được была разработана в 2015 году. Это высокооцениваемое программное обеспечение по сравнению с другими индентичными. Чтобы программировать NodeJS приложения я советую вам использовать данное программное обеспечение.
2- Создать проект NodeJS
Для начала вам нужно создать папку с названием MyProject, или название которое вы предпочитаете.
Открыть окно CMD и CD к только что созданной вами папке. Потом запустить следующую команду чтобы NPM создал для вас проект.
Принять опции по умолчанию и нажимать на Enter до завершения.
Создан файл с названием package.json на вашем проекте.
Есть некоторые пакеты (package) необходимых библиотек для вашего проекта, и вам нужно установить его с помощью NPM:
Express.js (или просто Express) это Web Application Framework для NodeJS. Предоставляет набор сильных свойств для веб и мобильных приложений.
EJS это аббревиатура "Embedded JavaScript templating", это библиотека, используемая для анализа файлов ejs, и создания HTML чтобы вернуть client (браузер).
После завершения установки, вы можете увидеть изменения на вашем проекте:
3- Создать структуру для проекта
В предыдущем шаге, мы создали проект с помощью команды. Сейчас мы откроем данный проект с помощью более визуального инструмента, здесь я использую текстовый редактор Atom (Программное обеспечение, которое я посоветовал вам установить в шаге выше).
- public: Это папка содержащая все файлы, в которые пользователь имеет доступ как image, video.
- views: Ваш вебсайт будет иметь много страниц (page), например гланая страница, страница логина. Данная папка это место содержащее все ваши страницы
Далее, создайте файл с названием index.js, и введите содержание для данного файла. Это файл конфигурации для вашего проекта:
OK, теперь время объяснить содержание файла index.js выше.
Код Описание var express = require("express"); ExpressJS это Web Application Framework, данная строка кода говорит о том, что вы хотите ее использовать. var app = express(); Создать объект Express. app.use(express.static("public")); Данная строка кода говорит Application Server, что вы хотите использовать папку public для содержания статических данных, пользователь может получить доступ в файлы данной папки. app.set("view engine", "ejs"); Данная строка кода говорит Application Server что вы хотите использовать библиотеку EJS, это машина, которая обрабатывает ваши страницы. EJS создаст HTML чтобы вернуть браузеру пользователю. app.set("views", "./views"); Данная строка кода показывает Application Server путь к папке содержащей ваши страницы. app.listen(3000); Ваше приложение развернуто, оно будет слушаться на порте (port) 3000. app.get("/test", function(req, res) < .
>);Определить путь для ссылку на одну страницу. 4- Запустить Application Server
Открыть окно CMD, и CD в папку вашего проекта. И выполнить команду ниже для развертывания (deploy) вашего приложения.
Команда выше стартует Web Application Server, и развернет ваше приложение на данный Web Server. Теперь оно готово для обслуживания запросов отправленных от client.
Примечание: Не закрывать окно CMD, потому что ваш Application Serser работает. Откройте браузер и пройдите по ссылке:
Что произойдет в Server если пользователь пройдет по ссылке выше?
Читайте также: