falbar Миграция с PHP на Node.js

Миграция с PHP на Node.js

11 июля 2021 Перевод 823 0

На протяжении многих лет я разрабатывал веб-приложения на PHP, но в последнее время я больше занимался приложениями для iOS. Когда я вернулся к веб-разработке, то осознал, что очень соскучился по элегантности Objective-C и его структуры MVC.

Реклама

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

После каждой работы, которую я выполняю при помощи PHP, я говорю себе: пора начать работать умнее. Тогда я начинаю изучать фреймворки для PHP и размышляю о том, чтобы полностью перейти на совершенно новую платформу, которая использует Java, Ruby или Python. Я начинаю колдовать над новым подходом и создаю простые приложения. Неминуемо происходит следующее: появляется новая работа, и мне приходится вернуться к PHP. Частично вина за это лежит на мне, но в то же время это вина платформы, которую я пытаюсь изучить.

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

Помимо всех популярных альтернатив PHP, появилась относительно новая - Node.js. Когда я начал возиться с Node несколько лет назад, мне было приятно опираться на знания JavaScript, которые мне приходилось использовать на стороне сервера. Однако Node никогда не казался реальным конкурентом популярным языкам, когда речь шла о написании полного кода на стороне сервера. Это было просто слишком ново и беспрецедентно.

Недавно я еще раз рассмотрел использование Node в качестве основного языка для серверной стороны. Я был поражен его прогрессом и комьюнити. Он достаточно развит, чтобы его можно было использовать в качестве важного инструмента любому веб-разработчику. Он особенно полезен для UI- и фронтенд-разработчиков. Пришло время снова покопаться в Node и посмотреть, не разлучит ли он меня с PHP раз и навсегда.

Node: вкратце

Установить и запустить Node на моем MacBook было очень просто. Вот как выглядит установка для OSX:

// Install homebrew then Node
ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"brew install node

После этого вы будете готовы запустить код JavaScript на сервере. Приложение Node «Hello World» демонстрирует базовую структуру кода и в то же время показывает, что это очень функциональный веб-сервер. Имея всего 2 строки в терминале, вы получите всю мощь JavaScript и веб-сервер для загрузки. Попробуйте поиграться. Откройте текстовый редактор и вставьте этот код:

var http = require('http');http.createServer(function (req, res) {
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.end('Hello World\n');
}).listen(1337, '127.0.0.1');

console.log('Server running at http://127.0.0.1:1337/');

Сохраните файл как app.js и введите в терминал:

node app.js

Загрузите ваш браузер и зайдите на http://localhost:1337, и вуаля!

Сейчас вы можете спросить: «Хорошо, что теперь?» По крайней мере я так и сделал, когда впервые опробовал Node. Я не знал и не понимал, как применить какие-либо из моих существующих знаний о том, как создать действительно правильное веб-приложение из этого примера.

NPM

Node становится действительно мощным, когда вы начинаете добавлять к нему дополнения. Node Package Manager, или NPM, входит в комплект установки Node. Сообщество создало несколько бесценных приложений, инструментов, фреймворков и промежуточного ПО, чтобы помочь разработчикам UI сосредоточиться на ключевых задачах, создании отличного пользовательского опыта. Если у вас есть опыт работы с composer при создании веб-приложений на PHP, то использование NPM у вас не вызовет трудностей. NPM использует файл package.json для описания метаданных вашего приложения и, что наиболее важно, зависимости. Вы можете отредактировать этот файл вручную и заполнить зависимости по своему усмотрению, как если бы вы использовали файл composer.json. Вы также можете установить пакеты из командной строки следующим образом:

npm install <package_name> --save

Обычно я добавляю опцию — save, чтобы пакет был добавлен в список зависимостей в файле package.json.

Помимо веб-приложения, в NPM есть несколько замечательных серверных приложений, которые упростят вам жизнь. Вы можете установить пакеты в локальном каталоге приложения или выбрать глобальную установку. Глобальная установка даст вам доступ к пакету из командной строки (вам нужно будет добавить папку bin NPM в PATH терминала). Установка пакета в целом выглядит так:

npm install -g <package_name>

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

Создание и портирование вебсайтов

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

Express

Возможно, наиболее важным компонентом построения успешных веб-приложений в Node является Express. Это пакет, который базируется на Node, добавляя некоторые важные структуры для создания веб-приложений. Сам Node делегирует большую часть ответственности веб-сервера программисту. Express основан на middleware под названием Connect, который заполняет этот пробел, поэтому разработчикам не нужно беспокоиться о мелких деталях анализа ввода и обслуживания страниц. Вдобавок ко всему, Express предоставляет очень удобную платформу для разработчика, чтобы код был богатым, стабильным и понятным. Де-факто Express стал стандартом для создания веб-приложений в Node. Я бы не стал создавать веб-приложение без него.

Nodemon

Запуск и тестирование приложения в PHP или Node сильно отличаются. Обычно с PHP вы разрабатываете некоторый код, затем переходите в браузер и обновляете страницу. Время от времени вам может понадобиться изменить конфигурацию Apache и перезапустить веб-сервер. Процесс в Node довольно сильно отличается. Поскольку веб-сервер и приложение объединены в один компактный пакет, изменение кода стало означать необходимость перезапуска всего веб-приложения, а также и веб-сервера. Когда я изучал основы, казалось, что процесс нужно было постоянно "убивать", нажимая стрелку вверх, чтобы перейти к последней команде, а затем Enter, чтобы перезапустить приложение (цикл: [Ctrl + C] [Up] [Enter]). Это быстро стало надоедать. Для того, чтобы люди делали удобную работу в Node, этот момент было необходимо улучшить. К счастью, именно здесь поможет Nodemon. Установите Nodemon, используя NPM, и вместо запуска своего приложения используйте:

node app.js

Далее примените:

nodemon app.js

Это приложение будет отслеживать перемены в коде и автоматически перезапустит Node. Все очень просто и важно.

Swig

Когда я создавал веб-приложения на PHP, я выбирал шаблонный движок Twig от SensioLabs. Это был компонент фреймворка Symfony, благодаря которому сборка внешнего интерфейса HTML становилась проще. Twig был важным инструментом для меня. Если я собирался перенести какой-либо из моих существующих проектов на Node, мне пришлось повторно использовать шаблоны представлений, которые у меня уже были. Swig сделал этот переход невероятно простым. Почти каждая часть Twig, которую я использовал, была доступна в Swig. Мне пришлось внести пару небольших изменений в код шаблона, но в целом он был готов сразу же. Он полностью совместим с Express.

Существует прямой порт Twig в Node, но, к сожалению, этот проект остановился. Swig очень активно обновляется, поэтому я решил использовать его и дальше.

MySQL для Node

Когда вы читаете о Node, в большинстве случаев он связан с базами данных типа NoSQL, такими как MongoDB. В дальнейшем я, скорее всего, буду использовать Mongo просто из-за потрясающей библиотеки Mongoose. Она упрощает управление моделями в веб-приложениях. Однако, учитывая, что у меня есть несколько устаревших проектов для управления и портирования, я хочу сохранить как можно больше программ. Значит, мне нужно сохранить существующие схемы и данные MySQL. Доступно несколько пакетов MySQL, но, мне кажется, felixge обладает всеми нужными функциями.

PassportJS

Почти все веб-приложения в наши дни имеют какую-то связь со сторонними API. Аутентификация с помощью этих сервисов имеет свои проблемы. К счастью, в PHP доступно множество пакетов, облегчающих доступ к этим API. С Node вам действительно нужно заботиться только о PassportJS. Это совместимый с Express пакет, который позволяет проходить аутентификацию практически в любом месте в Интернете. Вы даже можете использовать его для аутентификации своего локального входа в систему и управления сеансами, если это будет необходимо. Мне кажется, этот инструмент бесценен при аутентификации на других сервисах, таких как Twitter, Instagram и Facebook. Считается, что это дополнение может аутентифицироваться на 140 различных сервисах. Маст-хэв для любого разработчика веб-приложений.

Начало работы

После того как я разобрался в основах Node и познакомился с новой платформой, я был готов начинать создание приложений. Я потратил где-то день на изучение книг о NodeJS и разработку пару примеров с помощью Express. Так как я уже понимал основы механики платформы, теперь нужно было перенести сюда одну из моих старых работ. На то, чтобы перенести многоязычный сайт малого или среднего размера, ушло около 2-3 дней. Скорость портирования сайтов, несомненно, будет увеличиваться по мере того, как я буду знакомиться с процессом и структурами Node и Express. Тем, кто переходит с PHP или Node для которых является первой платформой, будут полезны следующие замечания.

Синхронный или асинхронный?

Одной из крупнейших перемен, которые мне необходимо было осознать, является конвертация синхронного кода на PHP в асинхронный JavaScript-код. Node – это неблокируемая система с событийными циклами и одиночным потоком. Из-за этого любому действию не нужно блокирующее действие, чтобы вернуть данные перед выполнением следующей строки кода. Все строки кода выполняются сразу же, друг за другом. Здесь уже нет идеи о том, что запрошенные данные будут доступны в следующей строке кода. Здесь-то вам и пригодится опыт фронтенд-разработок на JavaScript. Как и в случае с клиентской стороной, события управляются функциями обратного вызова. То же касается и кода JavaScript на сервере. Чтобы создать синхронный код на JavaScript, последовательность событий необходимо поместить в функции обратного вызова. Например:

// PHP
$sql1 = "SELECT user_id FROM users WHERE email=?";
$stmt = DB()->prepare($sql);
$stmt->execute(array($email));$sql2 = "SELECT photo_id FROM photos WHERE user_id=?";
$stmt = DB()->prepare($sql);
$stmt->execute(array($user_id));

Что и требовалось ожидать. PHP выполнит первый запрос и дождется его результата, а затем использует полученные данные во втором запросе. В Node запросы должны находиться в обратных вызовах по завершению:

var sql1 = "SELECT user_id FROM users WHERE email=?";
connection.query(sql1, [email], function(err, rows)
{
  var sql2 = "SELECT photo_id FROM photos WHERE user_id=?";
  connection.query(sql2, [rows[0].user_id], function(err, rows)
  {
    console.log(rows); // output all the photos
  }
}

Вам может показаться, что код такого типа со временем станет громоздким, когда нужно будет выполнять большое количество асинхронного кода. Вы правы. Эту проблему решает использование объектов promise.

Баги – это очень плохо

Так как Node – это система одиночного потока, важно иметь в виду, что если в коде обнаружится необработанное исключение, то программа на Node «упадет» для всех, а не только для того, кто вызвал катастрофу. В PHP, Apache, Nginx дело обстоит иначе, так как «отмирает» ветка, которая занималась запросом, а не весь процесс. На среду разработок в Node это чаще всего не влияло, но вдохновляло вас тщательно искать баги. А вот в эксплуатационной среде это может иметь разрушительный эффект, так как веб-приложение «упадет» для всех пользователей, которые посещают сайт. Чтобы справиться с этой проблемой, нужно создать слушателя для всех необработанных исключений. Он и будет ими заниматься. Код выглядит так:

process.on('uncaughtException', function (err) {
 console.log('Caught exception: ' + err);
});

Данный шаг будет гарантировать, что приложение будет работать даже в случае чего-либо неожиданного.

Правила замены

Один из мощнейших аспектов веб-разработки – способность заменять хаотичные URL на более аккуратные. Это приводит в восторг поисковые системы и пользователей. PHP не волновал внешний вид ссылок, ему просто нужны были входные значения. Заменой ссылок можно было заняться в Apache или Nginx. При использовании Node для разработки веб-приложений направлять запросы помогает маршрутизация Express. Мне показалось, что управление маршрутами через серверную часть кода программы, – очень интересная перемена. Разобравшись с этой идеей, вы больше никогда не захотите снова писать правила маршрутизации через входную точку <VirtualHost>. Вот небольшой пример:

RewriteRule ^/blog/([A-Za-z-]+)$ /blog/entry.php?slug=$1

С использованием маршрутизации Express:

app.get('/blog/:slug([A-Za-z-]+)', blogController.entry);

Вам больше не придется носиться с маршрутизацией запросов между веб-сервером и кодом приложения.

Запуск нескольких сайтов Node на одном сервере

Поскольку Node является как процессором кода, так и веб-сервером, встроенным в него, может возникнуть проблема при запуске нескольких сайтов в одной среде. Для запуска веб-сервера Node необходимо выбрать порт для запуска запросов. Запустив сайт на порту 80, вы не сможете сделать второй сайт с тем же портом. Кто-то может просто сказать вам: получите новый VPS для каждого веб-сайта, учитывая, что сейчас они очень доступны. Однако во многих случаях VPS может вызвать проблемы на сайте. В этих случаях вы можете выбрать запуск стандартного веб-сервера, такого как Apache или Nginx, и передавать запросы в Node через прокси. Я выбрал прокси с использованием переписывания Apache, потому что я часто его применяю. Вот как выглядит пример записи <VirtualHost>:

<VirtualHost *:80>
  ServerName example.com
  ServerAlias another-example.com
  DocumentRoot  /my/folder/

  RewriteEngine On
  RewriteRule ^(/.*)$ http://%{HTTP_HOST}:1337$1 [P]
</VirtualHost>

В nginx будет нечто такое:

server {
  listen 80;

  server_name your-domain.com;

  location / {
    proxy_pass http://localhost:{YOUR_PORT};
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection ‘upgrade’;
    proxy_set_header Host $host;
    proxy_cache_bypass $http_upgrade;
  }
}

Также можно использовать подход JavaScript с помощью пакета Node-Http-Proxy. Используйте то, что больше приходится вам по душе.

Ищите, и вы точно найдете

Одна из самых захватывающих частей программирования в Node — это его комьюнити. Там так много всего происходит, причем очень быстро. Когда я портировал свой первый сайт, я сталкивался с проблемой и спрашивал: «Как мне это сделать в Node?». Я просто гуглил, какой бы ни была моя проблема, и был уверен, что через несколько секунд у меня будут ответы. Я никогда не сталкивался с проблемой, которую просто невозможно было решить с помощью Node. Это свидетельствует о достигнутом прогрессе. Если вы столкнулись с проблемой, просто гуглите ее. Несомненно, у кого-то найдется решение.

Заключение

Потратив 3-4 дня на Node и его дополнения, я был потрясен тем, как просто запустить рабочий сайт. Барьер входа для разработки веб-приложений в Node еще не такой низкий, как в PHP, но стремится к тому же! Знания, которые вы получите, поняв менеджеры пакетов и фреймворки MVC, чрезвычайно важны для современных веб-разработчиков. Только из-за этих двух концепций барьеры PHP или Node различаются. Node+Express заставляют выучить эти концепции, перед тем как начать разработку. Это замечательно для разработчика и его программ.

Наконец, думаю, важно понимать, почему веб-разработчикам (в особенности UI- и фронтенд-разработчикам) нужно писать серверный код на JavaScript.

Полный контроль

Большинство UI-разработчиков уже знают все подробности и нюансы JavaScript. Использование этих знаний при подготовке серверного кода увеличивает продуктивность. Кроме того, судя по моему опыту, бизнес- и бекенд-разработчики обычно брезгуют использованием UI-кода при создании сайтов. Они скорее фокусируются на разработке основных функций приложения. Создание программ в Node позволяет UI-разработчику «захватить» часть серверного приложения про интерфейс. Функционал приложения можно полностью отделить от интерфейса, получить к нему доступ через API. Отделение бекенда от фронтенда позволяет каждому разработчику выбрать желаемую платформу для выполнения работы.

Учитывая этот мой опыт, я решил перенести все мои будущие проекты на Node, где это возможно, и использовать для UI-разработок платформу, полностью связанную с JavaScript. Этот язык чрезвычайно важен для создания хорошего пользовательского впечатления. Теперь им можно пользоваться и для создания серверной части кода. Честно говоря, я считаю, что этот язык станет главным для разработки фронтенд-приложений. Благодарю комьюнити разработчиков, которые своим трудом сделали все эти великолепные инструменты, чтобы такие, как я, с помощью них создавали замечательные сайты.

Реклама
Комментарии не найдены
 no_avatar