Вы когда-нибудь пробовали писать интерфейсные приложения с использованием синтаксиса ES6, но затем, когда вы решили изучить внутреннюю разработку с помощью Node.js и Express, вы поняли, что не можете использовать такие вещи, как import from и export default? Если да, то вы пришли в нужное место! Это пошаговое руководство по настройке среды разработки и производства, сценариев установки, а в качестве бонуса мы узнаем, как добавлять тесты!

Оглавление / Резюме тем

Как это работает? Взгляд на высоком уровне того, что нам нужно

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

Транспилятор кода с 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 для перезапуска нашего сервера при каждом изменении файла.

Это общее представление о том, как это работает изнутри. Итак, давайте начнем с того, как нам настроить или спроектировать.

Предпосылки

Прежде чем мы начнем, нам нужно сначала настроить некоторые вещи.

  1. Убедитесь, что у вас установлены Node.js и npm. Я рекомендую установить их последнюю LTS или текущую стабильную версию. Вы можете установить его через Node.js Source или NVM (Node Version Manager).
  2. Базовые знания команд терминала. Большинство команд в любом случае есть в учебнике, поэтому вам не нужно о них беспокоиться.
  3. Убедитесь, что у вас открыт терминал и установлен ваш любимый текстовый редактор.

Вот и все, пора!

Установка 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 переименуйте сценарий запуска в serverfound в объекте 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"
},

Примечания и отказ от ответственности

Обратите внимание, что эта установка может оказаться не идеальной для всех ситуаций, особенно для больших проектов. (например, 1к файлов кода). Транспортировка шага и удаление могут замедлить вашу среду разработки. Кроме того, модули ES почти подходят к узлу. Но, тем не менее, это хороший учебный материал, чтобы понять, как транзитная передача работает под капотом, например, когда мы разрабатываем интерфейсные приложения :)

Вывод

Хорошо! Я надеюсь, ты многому научился. Спасибо, что дочитали до этого места.

Удачного кодирования!

Здесь вы можете посмотреть полное репо.

Эта статья опубликована в freeCodecamp.