Технологии так неумолимы в своем прогрессе. Мне нравится видеть, как мы постоянно переходим от идей к новым продуктам, приложениям и рынкам. Это большая работа, чтобы идти в ногу, но есть много преимуществ, которые можно получить. Одним из больших достижений в Интернете являются улучшения в JavaScript. Кто бы мог подумать, что маленькие скрипты, выводящие окна предупреждений, могут зайти так далеко. Оказывается, дорога прогресса не всегда бывает гладкой. Постоянно сталкиваюсь с той или иной проблемой.

Сегодняшней проблемой было развертывание моего экспресс-сервера на Heroku. Я прочитал руководство по началу работы с документацией по узлам, на которую ссылается ниже. Это выглядело действительно легко. Их пример кода был развернут без сучка и задоринки. Я подумал, давайте попробуем это с существующим проектом. Бум! Это был полный отказ. Даже оператор heroku create не удался. К сожалению, документы не касались ни одной из проблем, которые у меня были. Сначала я не нашел хороших решений в Интернете, но после того, как я начал писать, я нашел несколько отличных постов. Ссылки на них указаны в конце поста.



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

В этом посте предполагается, что у вас установлены node и yarn и вы хотя бы немного знакомы с использованием терминала. Вы можете использовать npm вместо пряжи. В этот момент они реагируют на аналогичные флаги. Я использую Mac, но пользователям Windows потребуется лишь несколько небольших изменений. Я постараюсь рассказать, что и почему я делаю, чтобы вы могли решить любые проблемы, с которыми столкнетесь. Кроме того, весь исходный код доступен на github.com. Посмотрите по ссылке ниже.



Структурирование проекта

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

mkdir express_es2015_webpack; cd $_

Команда создает папку и меняет каталог на нее. Точка с запятой отмечает конец оператора, как и в JavaScript. $_ разрешается в аргумент предыдущей команды. Поэтому после создания папки оболочка изменит каталог на эту папку.

Чтобы создать файл package.json по умолчанию.

yarn init -y

Добавьте экспресс-пакет. Мы будем использовать экспресс как удобный способ получать запросы и отвечать на них.

yarn add express

Webpack 4 ищет исходные файлы в расположении по умолчанию, т. е. src, и помещает результаты компиляции в расположение по умолчанию, т. е. dist. Я думаю, это здорово. Это просто упрощает задачу при запуске. Создайте две папки.

mkdir src dist

До сих пор мы просто создавали папки и добавляли ссылки на проект, но нам нужно место для размещения нашего кода. Создайте файл index.js, где его будет искать webpack.

touch src/index.js

Как оказалось, имя файла очень важно. Это сервер, поэтому я бы назвал его server.js и обновил основное свойство в package.json, чтобы использовать server.js в качестве основной точки входа. К сожалению, это не работает. Webpack будет искать папку src, но не найдет server.js. Однако он находит файл, если он называется index.js или index.json. Ошибка? Впрочем, это не так важно. Индекс в порядке. Поскольку мы пишем JavaScript, имеет смысл называть его index.js, а не index.json.

Мы собираемся использовать Babel для транспиляции, к счастью, некоторые умные и щедрые люди сделали Babel и поделились им с нами.

yarn add --dev babel-cli babel-preset-env nodemon

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

touch .babelrc

В файле .babelrc нам нужно сообщить Babel, что мы хотим сделать. Для этого воспользуемся пресетом. В этом случае пресет называется env. Предустановка включает в себя всю конфигурацию, необходимую для транспиляции es2105+ в es5. Обратите внимание: поскольку вы читаете этот пост в какой-то момент в будущем, возможно, вы установили Babel 7. Я использую версию Babel 6.26.0. Предустановленное использование немного изменится с Babel 7, поэтому проверьте файл package.json, чтобы узнать, какую версию Babel вы используете. Подробнее об этом можно узнать на https://babeljs.io/env/.

Это много команд, и мы еще не сделали ни строчки кода. Добавим небольшую выборку. Я не буду вдаваться в подробности кода index.js, так как это просто доказательство того, что все работает.

Использование экспресс

index.js почти настолько мал, насколько это возможно при использовании Express. Он импортирует экспресс-библиотеку. Создает константу, которая заполняется переданной переменной среды порта. Если переменная среды порта не определена, по умолчанию она будет равна 3000. Создайте новое экспресс-приложение и назовите его app. Мы определили обработчик, когда сервер получает запрос по корневому пути, т. е. ‘/’, нашего приложения. Обработчик ответит строкой «Сервер говорит», за которой следуют текущие дата и время. Наконец, приложение настроено на прослушивание порта, определенного ранее.

И последнее, и мы готовы запустить сервер.

В файле package.json добавьте раздел скриптов. Скрипт запустит nodemon. Это программа, которая автоматически отслеживает ваши файлы на наличие изменений и перезапускает вашу программу, если что-то меняется. В этом случае он будет повторно транспилировать ваш исходный код всякий раз, когда происходит изменение, и удерживать код в памяти. Идеально подходит для развития. Вы можете запустить его непосредственно для папки node_modules.

./node_modules/.bin/nodemon src/index.js --exec babel-node

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

После добавления скрипта разработки наша команда стала намного короче.

yarn dev

Потрясающий! У нас что-то запущено.

Вебпак

Использование babel отлично подходит для разработки, но, к сожалению, не так хорошо для производства. Babel строит код и сохраняет результат в памяти. Это означает, что при любом перезапуске потребуется пересобрать код. В продакшене лучше сохранить транспилированный вывод в набор файлов, а узел загрузит готовый код. Babel полностью способен выводить собранные файлы, но я думаю, что это будет немного дольше. Я бы хотел, чтобы учитывались и другие активы, такие как CSS, SVG и другие. Вот тут-то и появляется Webpack.



Давайте добавим webpack и интерфейс командной строки webpack в наш проект. Мы добавим его как зависимость разработки с флагом —dev, чтобы эти зависимости не включались в транспилируемый вывод.

yarn add --dev webpack webpack_cli

Настройте раздел сценариев файла package.json, чтобы включить новый сценарий для запуска веб-пакета.

Если мы обновим раздел скриптов, включив в него скрипт веб-пакета, мы сможем вызвать его из пряжи.

yarn webpack

Фу. Это дает нам предупреждение и ошибку. Что пошло не так?

Из приведенного выше вывода видно, что был создан файл main.js. Это имя по умолчанию для вывода. Также есть ряд предупреждений и ошибок. Сначала разберемся со вторым предупреждением, так как оно самое простое. Предупреждение говорит нам, что мы должны указать режим. Мы можем дополнить наш существующий скрипт веб-пакета, предоставив режим. Измените сценарий веб-пакета на следующий.

Здорово. Это разрешило предупреждение о режиме. Перейдем к более сложным задачам.

Webpack строит графики всех модулей, на которые ссылаются, начиная с одной или нескольких точек входа. Во многом это то же самое, что и Babel, только по-другому. Мы видим, что webpack пытается связать несколько модулей узла. Как оказалось, их не нужно связывать. К счастью, плагин webpack-node-externals создан специально для решения этой проблемы.

yarn add --dev webpack-node-external

Пакет определяет функцию, которая перечисляет модули узлов, которые являются ссылками, и сообщает веб-пакету, что они будут предоставлены извне для пакета, поэтому веб-пакету не нужно их объединять. На этом этапе нам нужно указать веб-пакету использовать плагин. Создайте файл webpack.config.js в корне проекта.

touch webpack.config.js

В webpack.config.js добавьте следующее.

Как оказалось, целевая спецификация ничего не делает на данный момент, но это немного на будущее.

Мы можем запустить файл напрямую с помощью node.

node dist/main.js

Откройте браузер и посетите http://localhost:3000, и вы должны увидеть следующее.

Потрясающий! Мы приближаемся.

Управление версиями

Если вы еще этого не сделали, самое время закоммитить свой код в git. Создайте новый репозиторий.

git init

На данный момент в вашем проекте много файлов. Если вы не верите, я смотрю в папку node_modules. Обычно вы не должны проверять папку node_modules. Это расточительно и добавляет много шума в ваше репо. Поэтому создайте файл .gitignore в корне вашего проекта и вставьте в него следующее.

На этом этапе git будет игнорировать около 99,9% ваших файлов, но будет отслеживать те, которые имеют отношение к делу. Следует отметить, что мы включаем нашу папку dist в систему управления версиями, поскольку ее нет в файле .gitignore. Это необычно. Подробнее об этом ниже.

Подготовьте все неигнорируемые файлы, чтобы вы могли просмотреть их перед фиксацией.

git add .

Теперь давайте зафиксируем наши файлы.

git commit -m "Committing a working base project"

Героку

Давайте развернемся на Heroku. Я предполагаю, что у вас установлен heroku и вы вошли в систему. Если это не так, сделайте небольшой обход, чтобы прочитать хотя бы первые три пункта начала работы Heroku с node.js, на которые ссылается вверху поста. . Это довольно коротко и мило. До скорой встречи здесь.

В корне вашего проекта введите команду.

heroku create

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

git remote -v

Когда вы нажимаете на Heroku, он автоматически извлекает зависимости, как указано в вашем package.json, а затем запускает сценарий запуска. Отправьте свой код в основной ветке на пульт heroku. Вы должны увидеть процесс сборки в своем терминале.

git push heroku master

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

heroku logs

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

  1. Сценарий запуска необходим в разделе сценариев package.json.
  2. Procfile, указывающий на встроенную версию проекта.
  3. Cors необходимо использовать для ответа на удаленные запросы

Для стартового скрипта действительно просто ищет, как запустить приложение. Мы уже начали проект непосредственно со следующего.

node dist/main.js

Новый стартовый скрипт добавлен в раздел скриптов файла package.json.

Помните, как мы не исключили нашу папку dist в файле .gitignore? Это было сделано для того, чтобы мы могли обратиться к транспилированному коду. Хотя webpack управляет процессом сборки для нас, он делает это только на машине разработчиков. Это не пересборка main.js на Heroku. Это означает, что его необходимо включить в наш репозиторий git, чтобы Heroku получили копию, когда получат наш код.

Небольшое улучшение, которое мы можем сделать, даже если в этом нет функциональной необходимости, — это собрать проект в рабочем режиме. Это выполнит множество оптимизаций.

Добавьте следующий скрипт в файл package.json.

Затем запустите скрипт сборки.

yarn build

Вы должны увидеть, что main.js был изменен, запросив git

git status

Procfile, среди прочего, определяет определения процессов. Он скажет Heroku запустить новый веб-сервер и подключить его к процессу node, который запускает наш транспилированный код.



В корень проекта добавьте новый файл с именем Procfile со следующим в нем.

Чтобы отвечать на запросы из других источников, нам нужно использовать пакет cors.

yarn add cors

Затем ссылайтесь и используйте cors. Настройте содержимое файла index.js, чтобы оно ссылалось на библиотеку cors, и используйте ее.

В этот момент мы должны быть готовы попробовать еще раз. Внесите все наши изменения в git.

git add .

Зафиксируйте наши изменения.

git commit -m "Added start script. Replace the main.js with a production version. Added Procfile and cors."

Вставьте наши изменения в heroku.

git push heroku master

На этом этапе проект должен нормально работать на Heroku. Он предоставляет нам URL-адрес, чтобы мы могли взаимодействовать через наш браузер.

Резюме

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

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

использованная литература