Вы когда-нибудь пробовали писать интерфейсные приложения с использованием синтаксиса ES6, но затем, когда вы решили изучить внутреннюю разработку с помощью Node.js и Express, вы поняли, что не можете использовать такие вещи, как import from
и export default
? Если да, то вы пришли в нужное место! Это пошаговое руководство по настройке среды разработки и производства, сценариев установки, а в качестве бонуса мы узнаем, как добавлять тесты!
Оглавление / Резюме тем
- Как это работает?
- Предпосылки
- Установка экспресс
- Настройка скриптов
- Бонус
- TL;DR
Как это работает? Взгляд на высоком уровне того, что нам нужно
Чтобы при разработке серверных приложений использовать интерфейс, похожий на интерфейсную, вот общий обзор процессов, происходящих с вашим проектом.
Транспилятор кода с ES6 + на ES5
Нам нужен пакет, который переводит синтаксис ES6 и выше в код ES5. Код ES5 - это стиль синтаксиса JS, который читается в node.js, например module.exports
или var module = require('module')
. Обратите внимание, что в настоящее время почти 99% синтаксиса ES6 + можно использовать в Node.js. Вот где сияет пакет под названием babel.
Babel берет файл js, преобразует в нем код и выводит в новый файл.
Скрипт, удаляющий файлы
Каждый раз, когда мы что-то меняем в нашем коде, мы передаем это транспилятору, и он каждый раз выводит новую копию. Вот почему нам нужен сценарий, который удаляет файлы до того, как поступит свежая перенесенная копия. А для этого есть уже существующий пакет под названием римраф. Римраф удаляет файлы. Мы продемонстрируем это позже.
Наблюдатель за изменениями файлов
При кодировании в Node.js автоматический перезапуск нашего сервера происходит не из коробки, как при выполнении проекта, созданного поверх create-react-app или vue-cli. Вот почему мы установим пакет под названием nodemon, который что-то выполняет всякий раз, когда мы изменяем файл в нашем коде. Мы можем использовать nodemon для перезапуска нашего сервера при каждом изменении файла.
Это общее представление о том, как это работает изнутри. Итак, давайте начнем с того, как нам настроить или спроектировать.
Предпосылки
Прежде чем мы начнем, нам нужно сначала настроить некоторые вещи.
- Убедитесь, что у вас установлены Node.js и npm. Я рекомендую установить их последнюю LTS или текущую стабильную версию. Вы можете установить его через Node.js Source или NVM (Node Version Manager).
- Базовые знания команд терминала. Большинство команд в любом случае есть в учебнике, поэтому вам не нужно о них беспокоиться.
- Убедитесь, что у вас открыт терминал и установлен ваш любимый текстовый редактор.
Вот и все, пора!
Установка Express
Используя генератор Express, мы создадим новый проект со сгенерированным кодом, переместим некоторые файлы и преобразуем код в синтаксис ES6. Нам нужно преобразовать его на этой ранней стадии, потому что нам нужен способ проверить, работает ли наш код ES6.
Настройка проекта
Запустите эту команду в своем терминале. Вы можете назвать your-project-name
любым именем. --no-view
флаг означает, что мы не будем использовать какие-либо механизмы создания шаблонов, такие как handlebars, ejs или pug, для нашего приложения skeleton Express.
npx express-generator your-project-name --no-view
После создания приложения вам нужно перейти в каталог приложения. Для терминалов Windows Powershell и Linux используйте:
cd your-project-name
Затем откройте понравившийся текстовый редактор. Что касается меня, я просто использую VSCode, поэтому у меня одновременно открыты мой терминал и текстовый редактор. Но вы можете использовать любой текстовый редактор, какой захотите.
Установка пакетов, перемещение и удаление файлов
После того, как сгенерированный проект будет готов, нам нужно install
зависимости и переместить некоторые папки. Выполните эту команду, чтобы установить Express и другие пакеты.
npm install
Пока вы ждете установки зависимостей, выполните следующие действия.
- создать папку
server/
- Поместите
bin/
,app.js
иroutes/
в папкуserver/
. - Переименовать
www
, найденный вbin
, вwww.js
- Оставьте папку
public/
в корне вашего проекта.
Ваша файловая структура будет выглядеть так:
Теперь, поскольку мы изменили файловую структуру, наш сценарий стартового сервера работать не будет. Вот что мы сделаем, чтобы это исправить. В файле package.json переименуйте сценарий запуска в server
found в объекте JSON с именем "scripts"
// package.json { "name": "your-project-name", // ....other details "scripts": { "server": "node ./server/bin/www" } }
Вы увидите, что мы изменили путь к файлу с ./bin/www
на ./server/bin/www
, потому что мы переместили файлы в server/
. Позже мы воспользуемся стартовым скриптом.
Попробуй! Попробуйте запустить сервер, набрав npm run server
на своем терминале и перейдите к localhost:3000
в браузере.
Преобразование кода верхнего уровня для использования импорта ES6
Преобразование сгенерированного кода в ES6 немного утомительно, поэтому я просто опубликую здесь код и не стесняйтесь копировать и вставлять его.
Код для bin/www.js
:
// bin/www.js /** * Module dependencies. */ import app from '../app'; import debugLib from 'debug'; import http from 'http'; const debug = debugLib('your-project-name:server'); // ..generated code below.
Практически все наши модификации находятся только вверху и внизу файлов. Остальной сгенерированный код мы оставляем как есть.
Код для routes/index.js
и routes/users.js
:
// routes/index.js and users.js import express from 'express'; var router = express.Router(); // ..stuff below export default router;
Код для app.js
:
// app.js import express from 'express'; import path from 'path'; import cookieParser from 'cookie-parser'; import logger from 'morgan'; import indexRouter from './routes/index'; import usersRouter from './routes/users'; var app = express(); app.use(logger('dev')); app.use(express.json()); app.use(express.urlencoded({ extended: false })); app.use(cookieParser()); app.use(express.static(path.join(__dirname, '../public'))); app.use('/', indexRouter); app.use('/users', usersRouter); export default app;
В app.js
, поскольку мы оставили public/
в корне проекта, нам нужно изменить статический путь Express на одну папку вверх. Обратите внимание, что путь 'public'
стал '../public'
.
app.use(express.static(path.join(__dirname, '../public')));
Хорошо, мы закончили преобразование кода! Теперь давайте настроим наши скрипты.
Настройка скриптов
При настройке сценариев каждый сценарий выполняет свою роль. И мы повторно используем каждый скрипт npm. А для нашей среды разработки и производства у них другая конфигурация. (Почти идентично, вы увидите позже). Вот почему нам нужно составить наши сценарии, чтобы мы могли использовать их, не набирая один и тот же материал снова и снова.
Установите `npm-run-all`
Поскольку некоторые команды терминала не работают с Windows cmd, нам нужно установить пакет с именем npm-run-all
, чтобы этот скрипт работал в любой среде. Выполните эту команду в корне проекта терминала.
npm install --save npm-run-all
Установите babel, nodemon и rimraf
Babel - это современный транспилятор JavaScript. Транспилер означает, что ваш современный код JavaScript будет преобразован в более старый формат, понятный Node.js. Выполните эту команду в корне проекта терминала. Мы будем использовать последнюю версию babel (Babel 7+).
Обратите внимание, что Nodemon является нашим наблюдателем за файлами, а Rimraf - нашими пакетами для удаления файлов.
npm install --save @babel/core @babel/cli @babel/preset-env nodemon rimraf
Добавление скрипта транспиляции
Прежде чем babel начнет преобразование кода, нам нужно сообщить ему, какие части кода нужно переводить. Обратите внимание, что существует множество доступных конфигураций, потому что babel может конвертировать множество синтаксисов JS для различных целей. К счастью, нам не нужно об этом думать, потому что для этого есть доступное значение по умолчанию. Мы используем конфигурацию по умолчанию, называемую preset-env (ту, которую мы установили ранее) в нашем файле package.json, чтобы сообщить Babel, в каком формате мы транслируем код.
Внутри вашего package.json
файла создайте объект "babel"
и поместите этот параметр.
// package.json { // .. contents above "babel": { "presets": ["@babel/preset-env"] }, }
После этой настройки мы готовы проверить, действительно ли Babel конвертирует код. Добавьте сценарий с именем transpile в свой package.json
:
// package.json "scripts": { "start": "node ./server/bin/www", "transpile": "babel ./server --out-dir dist-server", }
Что здесь произошло? Сначала нам нужно запустить команду cli babel
, указать файлы для преобразования, в данном случае файлы в server/
, и поместить перенесенное содержимое в другую папку с именем dist-server
в корне нашего проекта.
Вы можете проверить это, выполнив эту команду
npm run transpile
Вы увидите всплывающую новую папку.
Ура, это сработало! ✅ Как видите, есть папка с той же структурой папок, что и папка нашего сервера, но с преобразованным кодом внутри. Довольно круто, правда? Следующий шаг - запустить try, если наш сервер работает!
Чистый скрипт
Чтобы получать новую копию каждый раз, когда мы переносим код в новые файлы, нам нужен сценарий, который удаляет старые файлы. Добавьте этот скрипт в свой package.json
"scripts": { "server": "node ./dist-server/bin/www", "transpile": "babel ./server --out-dir dist-server", "clean": "rimraf dist-server" }
Этот сценарий npm, который мы создали, означает, что он удаляет папку dist-server/
Теперь, чтобы объединить транспилирование и очистку, добавьте скрипт с именем build
, который объединяет эти два процесса.
// scripts "build": "npm-run-all clean transpile"
Запуск сценария разработки
Теперь у нас есть сценарий сборки, и нам нужно запустить наш сервер разработки. Мы добавим скрипт с именем dev
в наш package.json. Это позаботится о настройке нашей среды узла на «разработку», удалении старого перенесенного кода и замене его новым.
"scripts": { "build": "npm-run-all clean transpile" "server": "node ./dist-server/bin/www", "dev": "NODE_ENV=development npm-run-all build server", "transpile": "babel ./server --out-dir dist-server", "clean": "rimraf dist-server" }
Обратите внимание, что мы снова изменили файл, который запускаем на нашем серверном скрипте. Мы запускаем путь к файлу с перенесенным кодом, находящимся в dist-server/
.
Добавление скриптов продакшена
Если у нас есть сценарий разработчика, который устанавливает среду узла для разработки, у нас есть prod
сценарий, который устанавливает его в состояние «производство». Мы используем эту конфигурацию при развертывании. (Heroku, AWS, DigitalOcean и т. Д.) Теперь мы снова добавляем наш сценарий запуска и сценарий prod в наш package.json.
"scripts": { "start": "npm run prod" "build": "npm-run-all clean transpile" "server": "node ./dist-server/bin/www", "dev": "NODE_ENV=development npm-run-all build server", "prod": "NODE_ENV=production npm-run-all build server", "transpile": "babel ./server --out-dir dist-server", "clean": "rimraf dist-server" }
Мы устанавливаем start
сценарий по умолчанию на prod, потому что сценарий запуска всегда используется платформами развертывания, такими как AWS или Heroku, для запуска сервера.
Попробуйте запустить npmstart
или npm run prod
.
Как насчет автоматического перезапуска сервера при изменении файла?
Один последний сценарий, чтобы завершить настройку нашей разработки. Нам нужно добавить скрипт-наблюдатель за файлами, который запускает команду всякий раз, когда в файл вносятся изменения. Добавьте объект JSON с именем «nodemonConfig» в свой package.json. Здесь мы храним то, что мы говорим наблюдателю, что делать при изменении файла.
Также добавьте скрипт с именем watch:dev
в свой package.json
// package.json ... "nodemonConfig": { "exec": "npm run dev", "watch": ["server/*", "public/*"], "ignore": ["**/__tests__/**", "*.test.js", "*.spec.js"] }, "scripts": { // ... other scripts "watch:dev": "nodemon" }
Конфигурация Nodemon содержит настройки, относящиеся к
- Какую команду запускать при изменении файла, в нашем случае
npm run dev
- Какие папки и файлы смотреть
- И какие файлы игнорировать
Подробнее о настройке nodemon здесь.
Теперь, когда у нас есть средство отслеживания файлов, вы можете просто запустить npm run watch:dev
, написать код и сохранить файл. и всякий раз, когда вы переходите к localhost:3000
, вы увидите изменения. Попробуйте!
Бонус: добавляйте тесты!
Чтобы добавить тесты в наш проект, просто установите Jest из npm, добавьте несколько конфигураций и добавьте скрипт с именем test
в наш package.json
npm i -D jest
Добавьте объект под названием «jest» и тестовый скрипт в свой package.json.
// package.json ... "jest": { "testEnvironment": "node" }, "scripts": { // ..other scripts "test": "jest" }
Попробуйте, сделайте файл sample.test.js, напишите какие-нибудь тесты и запустите скрипт!
npm run test
TL;DR
Вот упрощенные шаги по включению ES6 в Node.js. Я также добавлю репозиторий, чтобы вы могли скопировать и проверить весь код.
- Создайте новый проект, используя команду терминала
express your-project-name
. - Переместите
bin/
,routes/
иapp
в новую папку с именемsrc/
и преобразуйте код в ES6. Также не забудьте переименоватьbin/www
вwww.js
- Установите все зависимости и devDependencies
npm i npm-run-all @babel/cli @babel/core @babel/preset-env nodemon rimraf --save npm i -D jest
- Добавьте эти скрипты в свой package.json
"scripts": { "start": "npm run prod", "build": "npm-run-all clean transpile", "server": "node ./dist-server/bin/www", "dev": "NODE_ENV=development npm-run-all build server", "prod": "NODE_ENV=production npm-run-all build server", "transpile": "babel ./server --out-dir dist-server", "clean": "rimraf dist-server", "watch:dev": "nodemon", "test": "jest" }
- Поместите конфигурации для babel, nodemon и jest в свой package.json
"nodemonConfig": { "exec": "npm run dev", "watch": [ "server/*", "public/*" ], "ignore": [ "**/__tests__/**", "*.test.js", "*.spec.js" ] }, "babel": { "presets": [ "@babel/preset-env" ] }, "jest": { "testEnvironment": "node" },
- Проверьте свои сценарии, запустив
npm run your-script-here
- Вы увидите полное репо на моем гитхабе
Примечания и отказ от ответственности
Обратите внимание, что эта установка может оказаться не идеальной для всех ситуаций, особенно для больших проектов. (например, 1к файлов кода). Транспортировка шага и удаление могут замедлить вашу среду разработки. Кроме того, модули ES почти подходят к узлу. Но, тем не менее, это хороший учебный материал, чтобы понять, как транзитная передача работает под капотом, например, когда мы разрабатываем интерфейсные приложения :)
Вывод
Хорошо! Я надеюсь, ты многому научился. Спасибо, что дочитали до этого места.
Удачного кодирования!
Здесь вы можете посмотреть полное репо.
Эта статья опубликована в freeCodecamp.