Разработка лендингов, квизов
сайтов, web-приложений

NodeJS для фронтенд девелоперов

Вольный перевод статьи Node.js Guide for Frontend Developers

Это руководство прежде всего ориентировано на разработчиков, которые знают JavaScript, но еще не очень хорошо владеют NodeJS.

Вероятно вам уже приходилось работать с Node.js: npm scripts, конфигурацией webpack, задачами gulp, автоматической сборкой и запуском тестов. Несмотря на то, что для работы не требуется глубокое понимание всех этих действий, иногда они могут сбивать с толку.

Познакомившись с Node.js поближе, вы сможете во всем разобраться, а заодно автоматизировать некоторые вещи, которые до сих пор делаете вручную. Вы почувствуете себя увереннее и сможете писать более сложные сценарии.

Версия NodeJS

В чем же отличие серверного программирования от клиентского? А отличие заключается в том, что вы сами определяете свою среду выполнения и можете быть абсолютно уверены в поддерживаемыъ функциях. Именно вы выбираете, какую версию программного обеспечения использовать, в зависимости от потребностей проекта и возможностей сервера.

У Node.js есть публичный график релизов. Из этого графика видно, что нечетные версии не имеют долгосрочной поддержки. Текущая LTS-версия (long-term support) будет активно разрабатываться до апреля 2019 года, а затем поддерживаться до 31 декабря 2019 года.

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

Node.js широко применяется в современном фронтенде – трудно найти проект проект, который не использует инструменты этой платформы. Скорее всего, вы уже знакомы с nvm (node version manager), который позволяет установить несколько версий Node одновременно для разных проектов. Это полезно, ведь если разные приложения используют разные релизы, было бы сложно синхронизировать и тестировать их на одной машине. Такие инструменты существуют и для многих других языков, например,virtualenv для Python, rbenv для Ruby.

Babel не нужен

Так как вы можете выбирать любую LTS-версию Node.js, то ничего не мешает использовать ту, в которой поддерживаются практически все современные возможности языка (ES 2015), за исключением хвостовой рекурсии.

Следовательно, Babel вам нужен, только если вы застряли с очень старой версией, или используете JSX-синтаксис, или хотите применять суперновые возможности, которые еще не вошли в стандарт.

Также нет необходимости в использовании webpack или browserify, и поэтому у нас нет инструмента для перезагрузки кода – вы можете использовать nodemon для перезапуска приложения после внесения изменений.

И поскольку мы никуда не отправляем написанный код, нет необходимости его минимизировать – на один шаг меньше в рабочем процессе. Вы просто используете свой код как есть! Очень непривычно.

Стиль коллбэков

Исторически сложилось так, что асинхронные функции в Node.js принимают обратные вызовы с сигнатурой (err, data), где первый аргумент представляет ошибку. Если он равен null, то все хорошо, иначе придется что-то предпринимать. Эти обработчики вызываются после получения ответа, например, при попытке прочитать файл:


  const fs = require('fs');
  
  fs.readFile('myFile.js', (err, file) => {
    if (err) {
      console.error('There was an error reading file :(');
      // process - это глобальный объект в Node
      // https://nodejs.org/api/process.html#process_process_exit_code
      process.exit(1);
    }
  

Вскоре выяснилось, что этот стиль крайне затрудняет написание читаемого и поддерживаемого кода, именно с ним связано callback hell. Позже появился асинхронный Promise – он был стандартизирован в ECMAScript 2015 (это глобальный объект как в браузере, так и в Node.js). Недавно ECMAScript 2017 ввела синтаксис async / await, доступный в Node.js 7.6+, который вы уже можете использовать.

С промисами мы избегаем «ада коллбэков», но появляется другая проблема: старый код и многие встроенные модули до сих пор используют обратные вызовы. Однако их можно преобразовать в обещания. Для примера давайте конвертируем метод fs.readFile:


  const fs = require('fs');
  
  function readFile(...arguments) {
    return new Promise((resolve, reject) => {
      fs.readFile(...arguments, (err, data) => {
        if (err) {
          reject(err);
        } else {
          resolve(data);
        }
      });
    });
  }
  

Этот шаблон может быть легко расширен на любую функцию. Кроме того, существует специальный метод utils.promisify. Вот пример из официальной документации:


  const util = require('util');
  const fs = require('fs');
  
  const stat = util.promisify(fs.stat);
  stat('.').then((stats) => {
    // Какие-то манипуляции со 'stats'
  }).catch((error) => {
    // Обработка ошибки
  });
  

Разработчики Node.js понимают, что нужно переходить от старого стиля к новому, поэтому они пытаются внедрить промисифицированную версию встроенных модулей – например, уже есть промисифицированный модуль файловой системы, хотя он пока экспериментальный.

Вы все еще можете столкнуться со старым кодом с обратными вызовами. Рекомендуется обернуть его с помощью utils.promisify.

Заключение

В этом руководстве рассмотрены фундаментальные принципы Node.js. Вы уже понимаете, где могут возникнуть ошибки, какие интерфейсы используют встроенные модули и чего ожидать от встроенных объектов. Мы не углублялись в конкретные API и определенно пропустили некоторые важные вещи, но теперь вы будете чувствовать себя увереннее и сможете легко разобраться в документации.

  • nodejs
  • javascript
  • nodejs для фронтенд девелоперов
  • фишки node.js
  • ES2015