Часть 1 — Настройка

Поскольку Vue.js 2 подходит к концу к концу 2023 года, я уверен, что большинство инженеров/разработчиков, использующих Vue.js 2, ищут пути перехода на другие варианты. Очевидным выбором является обновление до Vue.js 3, однако, поскольку фреймворк не получил широкого распространения в сообществе, а некоторые крупные библиотеки, такие как Vue Apollo, находятся в альфа-версии в течение 3 лет, а другие просто не создали Vue.js 3. .js 3» совместимые версии, возможно, вы захотите найти более широко используемую библиотеку; как Реагировать.

Как и в случае со всеми миграциями, они могут быть огромным мероприятием, на мой взгляд, есть три основных варианта начала миграции:

  1. Создание совершенно нового приложения с нуля и маршрутизация трафика в соответствующее приложение.
  2. Использование микроинтерфейсной архитектуры. Использование таких инструментов, как федерация модулей Webpack или веб-компоненты.
  3. Инкрементальный перенос компонентов в существующем приложении путем монтирования React, где это возможно.

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

Имея это в виду, я буду демонстрировать вариант 3 — поэтапный перенос компонентов в существующем приложении путем монтирования React, где это возможно. Сначала эта идея, вероятно, звучит ужасно, однако я уверен, что к концу этой статьи вы увидите, что на самом деле это самый низкий риск и самый простой вариант достижения безопасной миграции при сохранении и добавлении новых функций.

Шаг 1: Установите React и настройте каталог вашего приложения:

Начните с установки React и React DOM в каталог вашего приложения.

npm i react react-dom

Создайте новую папку внутри вашего каталога src. (я используюreact-migration). Затем запустите cd react-migration, а затем npm init, чтобы создать новый package.json. Наконец, запустите npm i @types/react -D, чтобы добавить модуль React Types.

Далее нам нужно добавить файл tsconfig.json в этот каталог, запустить npx tsc --init. Откройте только что созданный файл tsconfig.json:

// Change
"jsx": "preserve",
// to
"jsx": "react",

Если вы используете Yarn или PNPM, обновите команды соответствующим образом.

Шаг 2: Создайте свой первый компонент React

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

import React from "react";
type HelloWorldProps = {
 title: string;
 respondFunction: () => void;
};
export function HelloWorld({ title, respondFunction }: HelloWorldProps) {
  return (
    <div>
      <h2>Hello World Example</h2>
       {title}
      <br />
      <button onClick={() => respondFunction()}>Respond</button>        
    </div>
  );
}

Этот компонент ожидает два обязательных реквизита: title и respondFunction. Они будут переданы из Vue в React.

Шаг 3: Создайте компонент Vue для монтирования React

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

Этот компонент ReactWrapper.vue можно увидеть здесь:

<template>
   <div ref="container" /> 
</template>  
<script> 
import { createElement } from "react"; 
import { createRoot } from "react-dom/client";  
export default {
   inheritAttrs: false,
   props: {
     component: {
       type: Function,
       required: true,
     },
   },
   data() {
     return {
       reactRoot: null,
     };
   },
   methods: {
     updateReactComponent() {
       this.reactRoot.render(createElement(this.component, this.$attrs));
     },
   },
   mounted() {
     this.reactRoot = createRoot(this.$refs.container);     
     this.updateReactComponent();
   },
   destroyed() {
     this.reactRoot.unmount();
   },
   watch: {
     $attrs: {
       deep: true,
       handler() {
         this.updateReactComponent();
       },
     },
   },
 };
 </script>

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

Мы установили inheritAttrs: false,, чтобы атрибуты не просто помещались в ссылку контейнера, а затем мы передавали $attrs в качестве реквизита при рендеринге компонента. Мы также наблюдаем за $attrs и перерисовываем компонент при их изменении.

Наконец, мы unmount, когда компоненту destroyed, чтобы убедиться, что мы очищаем приложение React.

Шаг 4: Добавьте компонент ReactWrapper с компонентом React и необходимым реквизитом.

Мы можем либо зарегистрировать этот компонент глобально, чтобы он был доступен во всем приложении Vue, либо просто импортировать его в те компоненты, где мы хотим его смонтировать.

Чтобы установить его глобально, откройте main.ts и добавьте:

import ReactWrapper from "@/components/ReactWrapper.vue";
Vue.component("ReactWrapper", ReactWrapper);

Чтобы импортировать его локально в компонент:

import ReactWrapper from "./ReactWrapper.vue"
...
components: {
   ReactWrapper,
},

Затем мы хотим импортировать компонент HelloWorld.tsx и предоставить его шаблону, вернув его в вычисляемое свойство:

import { HelloWorld } from "../react-migration/src/components/HelloWorld";
...
computed: {
   HelloWorldComponent() {
     return HelloWorld;
   },   
},

Наконец, мы можем добавить компонент и получить результирующий файл:

<template>
   <div>
     <h1>{{ msg }}</h1>
     <p>
       For a guide and recipes on how to configure / customize this project,<br />
       check out the
       <a href="https://cli.vuejs.org" target="_blank" rel="noopener">vue-cli documentation</a>.
     </p>
     <hr />
      <div>
       <react-wrapper
         :component="HelloWorldComponent"
         title="Well Hello there"
         :respondFunction="respondFunction"
       />
     </div>
   </div>
</template>
<script lang="ts">
 import Vue from "vue";
 import { HelloWorld } from "../react-migration/src/components/HelloWorld";
 export default Vue.extend({
   name: "HelloWorld",
   props: {
     msg: String,
   },
   computed: {
     HelloWorldComponent() {
       return HelloWorld;
     },
   },
   methods: {
     respondFunction() {
       alert("We have responded");
     },
   },
 });
</script>

Хорошо, давайте запустим приложение и посмотрим, что у нас есть. В каталоге приложения выполните:

npm run serve

И перейдите по ссылке, указанной в терминале. Теперь вы должны увидеть это:

Мы видим, что верхняя половина компонента является стандартным компонентом HelloWorld.vue для начала работы, и внутри него мы можем видеть загрузку нашего компонента React HelloWorld.tsx, включая реквизит заголовка. Давайте нажмем кнопку и проверим, запускает ли она функцию Vue, которую мы передали:

Отлично, мы запустили функцию Vue, которая открыла окно предупреждения браузера. Теперь у нас есть React, работающий во Vue без каких-либо проблем, что также позволяет нам общаться между ними с помощью реквизитов.

Двусторонняя связь

Как показано выше, при использовании реквизита для запуска событий очень легко общаться между ними, но если ваше приложение крупномасштабное, то сверление реквизита действительно станет для вас огромной проблемой. Именно тогда вам нужно будет начать смотреть либо на использование событий браузера для запуска и прослушивания, либо на настройку глобального состояния. Выбор идеального глобального состояния может быть сложным, поскольку вам нужно, чтобы оно было совместимо как с Vue, так и с React.

Я расскажу об этом в другой статье, а также о том, как заставить ванильные библиотеки, такие как Valtio, работать с Vue 2.

Запросы

  • Отдых. Если вы используете REST, то обновление ваших запросов будет таким же простым, как создание их из React, а не из Vue. Если у вас есть собственный экземпляр вашего любимого HTTP-клиента, такого как Axios, то лучше всего инициализировать синглтон в файле, который можно импортировать и использовать как в React, так и в Vue.
  • GraphQLЕсли вы используете Apollo, вы можете обнаружить, что ваше приложение Vue находится в более старой версии библиотеки, и вам необходимо создать новую настройку для React. Я расскажу об этом в другой статье.

Заключение

Я уверен, что некоторые люди, читающие эту статью, думают: «Вы уверены? Это может быть излишне медленным». Однако я хотел бы отметить, что React рекомендует начинать так:

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

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

Источник: https://reactjs.org/docs/add-react-to-a-website.html

Я также могу заверить вас, что я знаю компании, использующие этот метод, и производственная сборка по-прежнему занимает менее 1 МБ, и клиенты не видели снижения производительности в тех областях, где он используется!

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

Лично я считаю, что этот метод миграции является самым безопасным, простым и удобным в сопровождении вариантом, поскольку вы все еще работаете в одной кодовой базе и выполняете миграцию шаг за шагом, если вы решите заменить целые страницы или только небольшие компоненты, выбор за вами, но это позволяет вам начать работу. Я также хотел бы отметить, что › 15 месяцев на миграцию всего приложения с одновременной доработкой функций и поддержкой текущего приложения могут быть проблемой, если вы работаете над большим приложением или даже над приложением с большим техническим долгом. С чего-то нужно начинать, почему бы не начать здесь?

Наконец, я работал исключительно с Vue в течение нескольких лет, и мне очень нравится Composition API, но с отсутствием понимания, сторонними библиотеками и сообществом, вы действительно хотите рискнуть снова выполнить эту миграцию через 2 года? ? React никуда не денется, у него огромная экосистема, в которую влюбится любой разработчик JavaScript.

Кроме того, если этого недостаточно, чтобы повлиять на вас… было бы здорово иметь React в своем наборе навыков для своего резюме.

Спасибо, что нашли время, чтобы прочитать мою статью. Надеюсь, вы нашли его познавательным и интересным. Я буду писать больше статей о Typescript, Node, React, Vue, GraphQL, Performance, Go и многом другом.

Репозиторий GitHub