React-Hot-Loader v4.6
- суббота, 15 декабря 2018 г. в 00:19:27
Примерно месяц назад вышли React Hooks, и сразу же выяснилось что React-Hot-Loader портит все малину и не только сам с ними не очень совместим, так еще и весь остальной код ломает. В общем это был жаркий месяц...
Тут почти ничего не изменилось — был hot
— остался hot
. Только стал короче и умнее:
Before
import {hot} from 'react-hot-loader'; .... export default hot(module)(MyComponent)
Now
import {hot} from 'react-hot-loader/root'; .... export default hot(MyComponent)
На самом деле новый hot
это просто старый, разделенный на две части. В итоге можно детектировать ситуации когда первая часть была вызвана, а вторая нет (подробности).
forwardRef
просто работает(никто не сказал что они не работали раньше), memo
будет обновлен несмотря на то что он memo
, ну а lazy
научился пере-импортировать свои внутрености.
И конечно же все работает прямо из кробки.
После выхода 16.7 стало понятно, что с Hooks беда. К сожалению этой беде были подвержены такие крупные проекты как StoryBook(issue) и Gatsby(issue).
Проблема итекала из самой природы React-Hot-Loader — для того чтобы обмануть React и предотвратить уничтожение старой версии дерева HotLoader оборачивает каждый компонент во враппер, который меняет только ссылку на "реальный" компонент внутри себя.
Конечно же SFC были обернуты в Components, и все сломалось.
На самом деле SFC оборачивались с SFC, которые возвращали экземпляр Класса. Очень недокументированная "фабричная" фича Реакта.
Сообщество быстро нашло выход(до которого я сам с ходу не додумался), благо надо было только изменить одну опцию — {pureSFC: true}
, и RHL будет переходит в более простой режим работы, который ранее был выключен из-за проблема с deep-force-update, который мы сейчас тоже обновили.
Hot-Loader всегда был про хакнуть Реакт, и делал это через перегрузку createElement
и возврат "проксированных" компонентов, чтобы обмануть проверку внутри React-Dom
. Теперь Hot-Loader будет хакать как раз эту самую проверку :) Работает изумительно.
К сожалению никакого API для этого сам реакт не предоставляет, потому мы выпустили специальный пакет — hot-loader/react-dom со всеми нужными патчами.
Поставить "patch" просто:
// this would always work
yarn add @hot-loader/react-dom@npm:react-dom
// or change your webpack config
alias: {
'react-dom': '@hot-loader/react-dom'
}
// or do the same with package.json to enable it in parcel
Для тех кому ставить левые пакеты не хочется — в комплекте идет webpack-loader который пропатчит конкретно вашу версию react-dom.
Тот самый webpack loader, который мы прибили в версии 4, вернулся к нам опять. Зачем?
Ошибки во время разработки — любимое дело, но ошибки+react-hot-loader не любил никто — работало просто не очень, а иногда так вообще не работало.
Начиная с версии 4.6 React-Hot-Loader перед началом апдейта будет добавлять во все компоненты по componentDidCatch
, а после апдейта убирать. Ошибки можно будет отловить и показать "just-in-place".
Вроде как мелочь, но эта мелочь меняет весь процесс разработки. Ну и конечно же все настраивается на свой вкус.
Эта проблема была с Hot-Loader всегда. Пока носом не ткнули. Если кратко — в React Dev Tools можно по правому клику открыть меню, и прыгнуть прямо к компоненту… Точнее (было) нельзя этого сделать
Теперь есть опция pureRender
, покуда выключенная по умолчанию, которая снимает с Компонент пару сайд эффектов, которые приводят к этой бяке.
К сожалению это работает только для "Class based" компонентов, для SFC требуется патч в react-dom, про который говорилось выше.
В принципе сейчас есть возможность практически скрыть присуствует HotLoader в системе.
Буквально неделю назад Dan Abramov опубликовал свой wish list для hot-loader — 22 принципа, которым hot-loader должен соотвествовать чтобы быть если не белым и пушистым, то "правильным".
В настоящий момент 14 пункта выполнены 100%, и еще 4 на 50%. Итого — 17 из 22. В принципе не плохо, и ясно что нужно сделать, чтобы добить остальные.
Кто знает, быть можно после этого Дэн вернется в проект.
hot
на новый hot
, знаю — звучит странно, но вы меня поняли.С вами был ️