Я пока не очень понимаю, какую библиотеку пользовательского интерфейса мне следует использовать для проекта PassPill.

Я успешно создавал проекты с использованием React и Preact, и, посмотрев на Inferno, мне очень захотелось попробовать. Его исходный код действительно легко читать и понимать, и даже если он не такой легкий, как Preact, Inferno по-прежнему остается легкой библиотекой, и они говорят, что она очень быстрая.

Итак, я установил Inferno в PassPill и адаптировал приложение, чтобы оно работало. Это не потребовало больших усилий, но я столкнулся с той же проблемой, что и с Preact: react-hot-loader (RHL) с ними не работает.

Мы по-прежнему можем использовать сервер webpack dev с горячей перезагрузкой, но я уже привык к тому, как RHL обновляет только измененные компоненты на лету, сохраняя их состояние, а автоматическая полная перезагрузка приложения теперь кажется болью.

Итак, я решил перенести RHL на preact и inferno, и, чтобы упростить задачу, я создал репозиторий со всем, что необходимо для этого:

Реакция-преакт-инферно-горячий-шаблон называется :)

Цель состоит в том, чтобы иметь одно приложение, один исходный код и 3 настройки веб-пакета, и они должны работать точно так же. Для этого нам нужны уровни совместимости Preact и Inferno, так что они тоже есть в игре.

Заставить RHL работать на Preact или Inferno все еще продолжается (нам посчастливилось привлечь внимание хранителей библиотек, и он будет готов очень скоро), но некоторые факты стали известны из тесты, которыми я хотел поделиться в этом быстром сравнении.

Настройка react-hot-loader

Перед началом сравнения нам нужна общая среда, в которой могут работать все три библиотеки. Наша цель - заставить RHL работать для всех, поэтому первое, что нужно сделать, - это настроить наше приложение для его использования.

Нам нужно будет установить webpack и использовать его сервер разработки с активированной горячей заменой. Кроме того, мы будем использовать babel для преобразования наших файлов JavaScript.

Факт наличия общей конфигурации - это замечательно, они используют не только один и тот же API, но и инструменты разработки! Приятно осознавать, что в случае, если мы захотим переключить библиотеки в середине процесса разработки, у нас не будет особых проблем.

Мы напишем код ES2015 и jsx, а также настроим babel-loader для перевода всего нашего нового модного кода в JavaScript, понятный любому браузеру:

Мы видим, что в нашей настройке есть 2 плагина, связанных с горячей перезагрузкой. Один плагин для webpack, другой для babel.

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

Плагин react-hot-loader/babel Babel предоставлен RHL. Когда мы изменяем любой исходный файл, он создает специальное обновление пакета, которое понимается компонентом RHL в нашем приложении. Это обновление заменяет только измененные части без полной перезагрузки, сохраняя состояние приложения и компонента. Этот «волшебный» способ обновления наших компонентов работает только с React. Preact и inferno проигнорируют изменения, если мы его используем. Вы можете увидеть больше об этом в сравнении библиотек ниже.

И последнее, что заставит БРЗ работать. В нашем корневом компоненте нам необходимо:

import { hot } from ‘react-hot-loader’

И используя hot для обертывания корневого компонента, см. Файл App.js.

export default hot(module)(App)

Настройка React

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

Вы можете подумать, почему бы нам просто не начать реагировать-создать-приложение? Для этого сравнения нам нужен минимум, необходимый для работы React, и мы будем сравнивать то, что нужно и для других библиотек, поэтому мы хотим обратить внимание на то, что мы устанавливаем :)

Теперь мы можем запустить наш сервер разработки, и в консоли мы получим следующее сообщение:

2,76 МБ для этого крошечного приложения - это много, особенно если исходный код нашего приложения перед компиляцией меньше 1 КБ!

Большая часть этого веса связана с инструментами разработки, и при запуске webpack в производственном режиме он исчезнет.

Давайте посмотрим, насколько велик пакет, если мы скомпилируем код для производства. Мы можем увидеть производственный файл конфигурации, если хотим узнать подробности того, как это сделать.

Так-то лучше. В производственном режиме приложение React уменьшает свой размер более чем на 95%. Исходная карта пакета загружается только тогда, когда мы открываем инструменты разработчика в браузере, поэтому пользователи нашего приложения тоже не получат этого.

Это то, что нужно для запуска приложения с React и RHL. Результат отличный, так как приложение будет меняться по мере обновления исходных файлов:

Настройка Preact

Preact - самая легкая библиотека для сравнения, она очень хорошо протестирована в производственной среде, и удивительно, насколько просто заставить ее работать в приложении, которое уже использует React. Нам не нужно менять какой-либо код, просто установите preact и его уровень совместимости:

А затем нам нужно настроить webpack, чтобы он знал, что каждый раз, когда в нашем коде мы говорим React, мы на самом деле имеем в виду Preact:

Вот и все, наше приложение должно работать прямо сейчас с Preact, и мы можем почувствовать это в нашем пакете:

На 1 МБ меньше, чем React, это огромная разница, но мы должны помнить, что React в режиме разработки содержит множество инструментов для отладки и комментариев, которые помогают разработчикам контролировать происходящее в любых обстоятельствах.

Но где Preact действительно ярче, так это при размере производственного пакета:

Как мы уже говорили во введении, react-hot-loader плохо работает с preact, хотя мы надеемся, что они скоро подыграют. Мы по-прежнему можем использовать горячие обновления сервера webpack dev для обновления браузера, когда мы вносим некоторые изменения, но без сохранения состояния:

Настройка Inferno

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

Исходный код Inferno прекрасен и прост для понимания, чего трудно достичь при создании такой сложной библиотеки, как эта. Для меня это плюс, потому что мне нравится знать, что происходит, когда что-то просто не работает.

Так что давай попробуем. Шаги по подготовке аналогичны шагам Preact. Сначала нам нужно установить инструмент и его уровень совместимости с React:

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

Нам нужно сообщить webpack о том, как подделать React с помощью Inferno, как мы это сделали с Preact:

Действительно здорово, что мы можем так легко переключаться между библиотеками! Теперь наше приложение использует Inferno.js, и, даже если это не повлияет на нашу разработку, это большое внутреннее изменение. Посмотрим, как это повлияет на размер нашего пакета:

Мы пока не можем использовать react-hot-loader с Inferno, но мы можем использовать горячую замену модуля webpack, так же, как мы это делали с Preact.

Войны за размер связки

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

Это было всего лишь быстрое сравнение пакетов. Если мы хотим разобраться в том, что делает наш пакет таким большим, существует множество инструментов веб-пакетов, которые могут нам помочь. Взгляните на эту статью Jannik Hell.

Эта статья является частью Проекта PassPill, который хочет поделиться всей разработкой веб-приложения. В рамках проекта мы будем тестировать разные библиотеки, чтобы выяснить, какая из них лучше подходит для наших нужд.

Если вам нравятся такие статьи, не забывайте следить за нашей публикацией и @passpillio в твиттере. Если вы их любите, теперь вы можете поддержать PassPill на Patreon… станьте первым! :)