Это обзор моего опыта интеграции VueJS и ReactJS в одну базу кода, написания всего кода на JSX и использования одной сборки Webpack. Для получения более подробного пошагового руководства о том, как настроить это самостоятельно. См. Мою Часть 2 - Полное руководство, в которой я предлагаю пошаговое руководство по настройке проекта Vue, который может напрямую использовать компоненты React. Затем я выделяю, как использовать некоторые из основных функций React в этом проекте Vue.

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

TL; DR

  • Vuera, библиотека с открытым исходным кодом на Github, может использоваться для создания относительно простого взаимодействия между Vue и React с использованием JSX для написания согласованного кода для обоих инструментов.
  • Возможность использовать компоненты Vue и React в одном проекте (и файле) открывает возможность использовать ресурсы и компоненты как из экосистем Vue, так и из React.
  • Ссылка на репозиторий Github с полным примером кода здесь

Мотивация

Недавно один из моих деловых партнеров начал создавать невероятное приложение B2B с использованием Vue и добился огромного прогресса. В какой-то момент я решил начать вносить свой вклад в его проект и начал создавать прототипы с помощью Vue. Мне удалось многого добиться с Vue, но я обнаружил, что мне нужны определенные компоненты, которые либо плохо обслуживаются, либо находятся в процессе разработки, либо просто не существуют. Это ни в коем случае не ошибка Vue как фреймворка, но я считаю, что это в большей степени потому, что многие из наиболее популярных и мощных компонентов React были либо созданы, либо поддержаны одним из технологических гигантов, модным стартапом или умным специалистом. консалтинговая фирма. Я лично считаю, что появление более высокобюджетных пользователей Vue по разным причинам, которые выровняют игровое поле, - лишь вопрос времени, но это определенно долгий и спекулятивный разговор в другой раз. В любом случае, вместо того, чтобы тратить время на создание этих компонентов с нуля и их поддержку, я решил рискнуть и посмотреть, смогу ли я легко интегрировать некоторые из наиболее высокотехнологичных компонентов React в наше приложение Vue. Быстрый поиск привел меня к единственному надежному результату - увлекательной библиотеке с открытым исходным кодом под названием Vuera. Vuera предоставляет блестящий способ интеграции компонентов React в компоненты Vue и наоборот без потери тонны основных функций, характерных для Vue или React. Хотя Vuera все еще находится на начальной стадии, он по-прежнему является сильным потенциальным решением в давней битве Vue против React, которая вызвала тонну разногласий в мире интерфейсных приложений.

Vuera и JSX

Сначала я полностью следовал документации Vuera, просто чтобы познакомиться с инструментом. Я подумал, что интеграция была совершенно фантастической, однако она не сразу работала напрямую с JSX. Написание React без JSX возможно, но абсолютно не рекомендуется практически всеми, кого вы спрашиваете в сообществе React. Как предприимчивый разработчик React, я первым делом решил выяснить, как интегрировать компоненты React с JSX в мое приложение Vue. К счастью, Vue предлагает возможность явного использования функций рендеринга с JSX в отличие от Однофайловых компонентов (SFC), которые содержат DSL с шаблонами html. Как человек, которому действительно нравится использовать синтаксис JSX, я предпочитаю его системе шаблонов Vue, но я понимаю плюсы и минусы обоих. Уловка состоит в том, чтобы передать компонент через функции оболочки Компонент высшего порядка (HOC), предоставляемые Vuera, без регистрации вашего компонента в экземпляре Vue. Вывод HOC возвращает именно то, что babel-plugin-transform-vue-jsx ожидает в качестве входных данных в вашей функции рендеринга Vue. Я объясню с подробностями и примерами в моем сообщении Часть 2 - Полное руководство. Обратите внимание, что этот конкретный метод работает только для компонентов React, загруженных из внешних модулей. Любые компоненты, которые вы пишете сами, должны быть разрешены с помощью небольшой неинвазивной небольшой настройки вашей конфигурации Vue Webpack, которую я придумал и подробно расскажу ниже.

JSX и Babel в двух словах

Под капотом и Vue, и React принимают HTML в форме, подобной javascript, и обрабатывают его таким образом, который кажется пользователю волшебным. Они оба просто предоставляют пользователю синтаксический сахар, чтобы сделать весь процесс создания представлений с помощью javascript последовательным, кратким, удобным и организованным. Первичный инструмент, ответственный за эту трансформацию, - Вавилон. По сути, одна из основных целей Babel - переносить код из одной формы в другую. В данном случае мы заменяем JSX (человеческий интерфейс) на достаточно производительный, совместимый с браузером и обратно совместимый код javascript (интерфейс компьютера). Если вы не знакомы с тем, как работает babel, я настоятельно рекомендую пройтись по некоторым руководствам, чтобы лучше понять точную интуицию, лежащую в основе моего объяснения.

Функция рендеринга и функция "h" во Vue

Еще одна важная часть контекста, которую необходимо понять, прежде чем все это обретет смысл, - это функция h в Vue. Вы можете прочитать больше в документации Vue:



Они прекрасно объясняют это, поэтому я не буду вдаваться в подробности. Вот базовое сравнение того, как выглядят Vue и React без синтаксического сахара JSX:

По умолчанию определение функции рендеринга Vue ожидает, что функция h будет передана в область видимости. Эта функция h на самом деле является просто широко используемым сокращенным псевдонимом для createElement. Функция рендеринга - это просто функция, которая регистрируется в компоненте Vue, который позволяет вам указать, как экземпляр Vue должен штамповать ваши элементы в DOM. Думайте об этом как о более явном наборе инструкций, чем при использовании шаблонов Vue. Конечно, внутреннее устройство React другое, но концепция функций рендеринга, используемых для управления DOM, очень похожа. Чтобы быть более эффективными, и Vue, и React интеллектуально отслеживают и обрабатывают эти изменения в DOM внутри так называемого Virtual DOM. Используя плагин babel transform-vue-jsx, мы можем создать эквивалент наших компонентов с JSX:

Однако, в зависимости от вашей версии плагина преобразования JSX babel, вы должны указать h в качестве аргумента вашей функции рендеринга Vue, иначе что-то сломается, потому что h не определено и, следовательно, у него нет фабричной функции для создания элементов Vue. Недавние обновления transform-vue-jsx сделали его автоматически вводить h в качестве параметра, поэтому вам больше не нужно делать это в ваших компонентах Vue, начиная с transform-vue-jsx версии 3.4.0:



Тем не менее, когда Webpack загружается в ваши компоненты Vue и React, он ищет файлы .jsx (или .tsx, если вы используете машинописный текст). По умолчанию webpack использует babel-loader для обработки JSX, потому что он содержит плагин babel transform-vue-jsx. Как упоминалось выше, этот плагин отвечает за преобразование JSX во что-то, что может понять Vue. Проблема в том, что, поскольку компоненты Vue и React могут иметь расширения файлов .jsx (или .tsx), Webpack не знает, какой плагин преобразователя JSX использовать, и пытается использовать преобразователь Vue для обработки файлов Vue и React. Ирония заключается в том, что Vue JSX и React JSX выглядят почти на 100% эквивалентными, но все равно не работают. Единственное отличие состоит в том, что этот забавный маленький символ «h» должен быть доступен в рамках вашей функции рендеринга Vue для работы. Поэтому, если парсер Vue JSX попытается проанализировать ваш файл React, он сломается с ошибкой «h не определен». Все, что вам нужно сделать, чтобы решить эту проблему, - это добавить еще одно правило в конфигурацию Webpack, чтобы указать загрузчику babel, как различать файлы JSX Vue и React.

Это также относится к файлам TSX. Кроме того, вам нужно будет добавить ко всем файлам React в вашем проекте суффикс .react.jsx (или .react.tsx). Это означает, что Webpack связывает ваш babel-загрузчик с преобразователем React JSX для файлов .react.tsx или .react.jsx, в противном случае по умолчанию используется преобразователь Vue JSX. Это было всего лишь одно возможное неинвазивное решение, которое я придумал, но я очень открыт для других идей, если кто-нибудь может придумать лучший способ. Также не беспокойтесь о внешних модулях компонентов React. Вам не нужно ничего переименовывать, чтобы они работали. Конечно, не забудьте добавить react и react-dom в качестве зависимостей к вашему проекту, чтобы этот процесс работал. Вы также можете столкнуться со следующей ошибкой при использовании загрузчика react babel:

URIError: не удалось декодировать параметр ‘/%3C%=%20BASE_URL%20%%3Efavicon.ico’

Чтобы решить эту проблему, вам нужно переименовать свою общую папку (я выбрал «vpublic» как «vue-public») и клонировать файл favicon.ico в пустую общую папку в вашем корне. Мне не очень нравится идея менять имя общей папки, и я понимаю, что многие люди могут не захотеть это сделать. В настоящее время я ищу более эффективные способы сделать это, но, если у кого-то есть рекомендации по лучшему решению, не стесняйтесь написать мне! В результате структура вашего проекта должна выглядеть так:

Заключение

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

P.S. Хотя на самом деле Vuera - действительно классное имя, я предлагаю более подходящее имя TruceJS, потому что мне кажется, что это консенсус между разработчиками Vue и React. Я думаю, многие из нас могут согласиться с тем, что отсутствие консенсуса было одновременно основным катализатором и тормозом для мира фронтенд-разработки.