Содержание
- Шаг 1: Установите Vite и плагины
- Шаг 2: Создайте файл конфигурации Vite
- Шаг 3: Создание ссылки на файл типа Vite
- Шаг 4: Переместите файл index.html.
- Шаг 5: Обновление файла index.html
- Шаг 6: Замените CRA на Vite.
- Шаг 7: Запустите ваше приложение
- Возможные блокировщики и их решения
- Шаг 8: Установка Jest и зависимостей, связанных с TypeScript
- Шаг 9: Обновление конфигурации Jest
- Шаг 10: Добавьте каталог __mocks__ в корень вашего проекта
- Шаг 11: Обновление скриптов package.json.
- Шаг 12: Запустите ваши тесты
- Что такое конфигурация списка браузеров?
- Почему browserslist является проблемой в Vite?
- Шаг 13: Установите browserslist-to-esbuild.
- Шаг 14: Подтверждаем browserslist в Vite Config
- Заключение
Команда React больше не рекомендует использовать create-react-app (CRA) в качестве бандлера для создания нового React-приложения. Команда и сообщество поняли, что хотя CRA и является стартовым инструментом, ему не хватает гибкости, необходимой для настройки и управления большими и сложными приложениями.
Сейчас команда рекомендует использовать production-grade React-фреймворки, такие как NextJS, Remix, Gatsby или Expo для нативных приложений. Хотя фреймворки являются предпочтительным выбором, команда React также рекомендует использовать Vite или Parcel для пользовательских процессов сборки.
Отчасти это связано с тем, что пакет CRA не обновлялся уже около года. Это может вызвать некоторые проблемы, когда пакеты, уже обновленные до более свежих версий, не могут быть использованы в существующем приложении. В результате вам может потребоваться обновить существующие приложения, заменив пакет CRA на рекомендованные альтернативы - Vite или Parcel.
В этой статье мы рассмотрим шаги по миграции производственного приложения с CRA на Vite. Вы узнаете, зачем нужен каждый шаг, как сохранить Jest для тестов и как обновить browserslist, поскольку он не работает с vite из коробки.
В разделе ”Заключение” вы найдете пример запроса на исправление, который включает все изменения. В конце каждого шага вы найдете пример текста коммита, который показывает, какие изменения кода требуются для каждого шага.
Шаг 1: Установите Vite и плагины
Вот команды для установки необходимых нам пакетов:
yarn add vite @vitejs/plugin-react vite-tsconfig-paths
ИЛИ
npm install vite @vitejs/plugin-react vite-tsconfig-paths
Помимо Vite, мы добавляем два плагина - @vitejs/plugin-react и vite-tsconfig-paths.
Плагин vitejs/plugin-react plugin обеспечивает быстрое обновление при разработке, использует автоматическое время выполнения JSX, а также пользовательские плагины или пресеты Babel. Он обогащает ваш опыт разработки React.
Плагин vite-tsconfig-paths plugin разрешает импорт для отображения путей TypeScript. Например, вы можете использовать components/ComponentName вместо ./../components/ComponentName.
Другие плагины Vite
Еще один плагин, который вы можете рассмотреть, это vite-plugin-svgr, который преобразует SVG в компоненты React и использует svgr под капотом. Я не стал его использовать, так как в переносимом приложении у нас нет такого сценария использования.
Вы также можете ознакомиться с другими официальными плагинами Vite здесь.
Шаг 2: Создайте файл конфигурации Vite
При запуске vite в командном терминале Vite пытается найти файл vite.config.ts в корневом каталоге проекта. О том, как дополнительно настроить этот файл для intellisense, конфигурации на основе окружения, конфигурации async и использования переменных окружения, вы можете прочитать на странице Vite.
В корне вашего приложения создайте файл vite.config.ts со следующим содержимым:
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import viteTsconfigPaths from 'vite-tsconfig-paths';
export default defineConfig({
// в зависимости от вашего приложения, base также может быть "/"
base: '',
plugins: [react(), viteTsconfigPaths()],
server: {
// это гарантирует, что браузер откроется при запуске сервера
open: true,
// устанавливается порт по умолчанию 3000
port: 3000,
},
});
Шаг 3: Создание ссылки на файл типа Vite
Этот шаг необходим для ссылки на файл деклараций типов, что помогает при проверке типов и Intellisense. По умолчанию типы Vite предназначены для среды NodeJS. Для кода на стороне клиента Vite предоставляет определения типов в vite/client.d.ts.
В корне вашего приложения создайте файл с именем vite-env.d.ts со следующим содержанием:
/// <reference types="vite/client" />
Шаг 4: Переместите файл index.html.
У Vite есть корневая директория, из которой обслуживаются ваши файлы. Поскольку index.html является точкой входа на сервер Vite, этот файл должен находиться в корневой директории.
Из публичной директории переместите файл index.html в корень вашего проекта.
Шаг 5: Обновление файла index.html
Здесь необходимо сделать два обновления:
Удалите %PUBLIC_URL%.
Vite автоматически разрешает URL внутри index.html, поэтому нет необходимости в %PUBLIC_URL%. Для этого вы можете выполнить поиск и замену внутри файла index.html. Обязательно удалите все вхождения.
Ранее:
<link rel="icon" type="image/svg+xml" href="%PUBLIC_URL%/favicon.svg" />
После:
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
Добавьте скрипт модуля в нижнюю часть тега body
Vite рассматривает index.html как исходный код и часть графа модуля. Он разрешает <script type="module" src="...">, который ссылается на ваш исходный код JavaScript.
В нижней части тега body в файле index.html добавьте скрипт, как показано ниже:
<body>
{/* другие здесь */}
<script type="module" src="/src/index.tsx"></script>
.
</body>
Шаг 6: Замените CRA на Vite.
Теперь вы можете удалить CRA, добавить скрипты Vite в файл package.json и обновить tsconfig.json.
Удаление CRA
Чтобы удалить CRA, выполните следующую команду. Это удалит react-scripts из наших установленных пакетов.
yarn remove react-scripts
ИЛИ
npm uninstall react-scripts
После выполнения вышеуказанной команды удалите файл react-app-env.d.ts.
Добавьте скрипты Vite в файл package.json.
Если Vite установлен, вы можете использовать бинарник vite в своих скриптах. Это может означать замену react-scripts в нескольких местах. Ваше внимание должно быть сосредоточено на ключах start и build. Ключ preview - это дополнение, которое помогает предварительно просматривать сборку локально.
Обратите внимание, что start - это vite, а не vite start.
{
"scripts": {
"start": "vite", // запуск dev-сервера
"build": "tsc && vite build", // сборка для производства
"preview": "vite preview" // локальный предварительный просмотр сборки для производства
}
},
Обновление tsconfig.json
Здесь вы должны сосредоточиться на параметрах isolatedModules, lib, target и types. Для получения дополнительных опций, вот пример файла tsconfig от Vite.
{
"compilerOptions": {
"lib": ["dom", "dom.iterable", "esnext"],
"target": "ESNext",
"types": ["vite/client"],
"isolatedModules": true,
},
}
Обновление process.env.REACT_APP_VARIABLE (необязательно)
Это необходимо, если ваше приложение использует переменную окружения. Vite использует import.meta.env.REACT_APP_VARIABLE вместо process.env.REACT_APP_VARIABLE. Более подробную информацию о переменных окружения и режимах Vite вы можете найти здесь.
Ранее:
process.env.REACT_APP_VARIABLE;
После:
import.meta.env.REACT_APP_VARIABLE;
Замените REACT_ на VITE_ (необязательно)
Это нужно только в том случае, если вы обновили process.env выше. Замените переменные окружения REACT_, чтобы они начинались с VITE_. Это необходимо, потому что Vite отфильтровывает любые переменные окружения, не начинающиеся с VITE_.
Ранее:
REACT_APP_API_BASE;
После:
VITE_APP_API_BASE;
Шаг 7: Запустите ваше приложение
запуск yarn
ИЛИ
npm start
Поздравляем! Вы успешно завершили первый шаг по переносу приложения с CRA на Vite. Вы должны увидеть экран, похожий на изображение ниже:

Примера коммита нет ;).
Возможные блокировщики и их решения
Ошибка global не определена
Если у вас возникла эта ошибка, определите global в файле vite.config.ts, как показано ниже:
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
export default defineConfig({
// ...
define: {
// здесь находится основное обновление
global: 'globalThis',
},
});
Если вы используете @emotion/react или @emotion/css
Вам необходимо сообщить об этом Vite. Для этого установите @emotion/babel-plugin.
yarn add @emotion/babel-plugin
ИЛИ
npm install @emotion/babel-plugin
Затем обновите r в вашем ViteПлагин eact в файле vite.config.ts, как показано ниже:
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import viteTsconfigPaths from 'vite-tsconfig-paths';
import svgr from 'vite-plugin-svgr';
export default defineConfig({
// ...
plugins: [
// здесь находится основное обновление
react({
jsxImportSource: '@emotion/react',
babel: {
plugins: ['@emotion/babel-plugin'],
},
}),
],
// ...
});
О нет, мои модульные тесты не работают!
На этом этапе попробуйте запустить свои модульные тесты - yarn test или npm run test. Вполне возможно, что они не работают. В следующих шагах описано, как можно исправить работу юнит-тестов.

Ваши модульные тесты не работают, потому что CRA использует react-scripts test для запуска тестов, поэтому мы хотим перейти на использование jest.
Шаг 8: Установка Jest и зависимостей, связанных с TypeScript
Для начала вам нужно установить jest, ts-jest и jest-environment-jsdom. jest будет нашим новым бинарником для запуска тестов, [ts-jest](https://www.npmjs.com/package/ts-jest) - это трансформатор с поддержкой source map, который позволяет запускать тесты в проектах TypeScript, а jest-environment-jsdom имитирует поведение браузера во время запуска тестов.
yarn add -D jest @types/jest ts-jest jest-environment-jsdom
ИЛИ
npm install --save-dev jest @types/jest ts-jest jest-environment-jsdom
Шаг 9: Обновление конфигурации Jest
Это зависит от вашей текущей конфигурации Jest. Если она настроена внутри package.json, вы можете обновить ее следующим образом. Здесь вы сосредоточитесь на preset, testEnvironment, moduleNameMapper и modulePaths.
preset устанавливается на ts-jest/presets/js-with-ts, чтобы разрешить TypeScript с JavaScript. Вы также можете просто установить значение ts-jest в зависимости от вашего приложения.
moduleNameMapper настраивает Jest на изящную обработку таких активов, как таблицы стилей и изображения.
"jest": {
"preset": "ts-jest/presets/js-with-ts",
"testEnvironment": "jest-environment-jsdom",
"moduleNameMapper": {
"\\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/__mocks__/fileMock.js",
"\\\.(css|less)$": "<rootDir>/**mocks**/styleMock.js"
},
"modulePaths": [
// вы можете изменить это в соответствии с настройками вашего приложения
"<rootDir>/src"
],
},
Поскольку мы ссылались на файл в moduleNameMapper выше, нам нужно создать этот файл и соответствующие ему файлы. Шаг 10 позаботится об этом. Более подробно эта настройка описана в документации Jest здесь.
Шаг 10: Добавьте каталог __mocks__ в корень вашего проекта
В корне вашего проекта создайте папку с именем __mocks__.
Внутри созданной папки __mocks__ добавьте файл с именем styleMock.js и добавьте в него следующее содержимое:
module.exports = {};
Внутри созданной папки __mocks__ добавьте файл с именем fileMock.js и добавьте в него следующее содержимое.
module.exports = 'test-file-stub';
Шаг 11: Обновление скриптов package.json.
Теперь, когда у нас правильно установлен jest, мы можем заменить react-scripts tests на jest. Изменения должны быть такими, как показано ниже. Если в вашем коде до этого не было ключей test:coverage или test:debug, можете не обращать внимания.
До:
"scripts": {
"test": "react-scripts test",
"test:coverage": "react-scripts test --coverage .",
"test:debug": "react-scripts test --inspect-brk --runInBand --no-cache"
}
После:
"scripts": {
"test": "jest",
// вы можете добавить это, чтобы сохранить режим наблюдения
"test:watch": "jest --watch",
"test:coverage": "jest --coverage .",
"test:debug": "jest --inspect-brk --runInBand --no-cache"
}
Шаг 12: Запустите ваши тесты
yarn test
ИЛИ
npm test
Если вы столкнулись с проблемой, связанной с import.meta, вы можете решить ее, перенеся все ключи окружения в один файл и подражая этому файлу в вашем тесте. Вы можете взглянуть на этот коммит (https://github.com/suretrust/stock-ticker/commit/07d15d1f000ec2cef7ec6dd01fccb43af3e67d30), чтобы лучше понять, что я имею в виду.
Примера коммита нет :).
А, это работает! Но как насчет конфигурации списка браузеров?
Что такое конфигурация списка браузеров?
Это конфигурация, используемая для обмена целевыми или поддерживаемыми браузерами между несколькими репозиториями фронтенда.
Существуют различные стандарты в зависимости от отрасли. Например, в сфере EdTech возможно, что все пользователи, обучающиеся онлайн, используют схожие браузеры по марке, версии и размеру экрана. Этот список часто используемых браузеров может легко стать стандартом для индустрии EdTech.
Пример применения конфигурации browserslist - когда вам нужно обеспечить совместимость со старыми браузерами. Передача этого диапазона в конфигурацию browserslist поможет вашему бандлеру скомпилировать ваш код с использованием полифиллов, совместимых с целевыми браузерами. Таким образом, ваша страница будет иметь оптимизированную производительность и хороший пользовательский опыт.
Mozilla определяет полифилл как часть кода (обычно JavaScript в Интернете), используемую для обеспечения современной функциональности в старых браузерах, которые не поддерживают ее изначально.
Конфигурация списка браузеров часто задается в файле package.json или .browserslistrc, как показано ниже.
package.json
{
"browserslist": [
"iOS >= 9",
"Android >= 4.4",
"2 последние версии",
"> 0.2%",
"не мертв"
]
}
.browserslistrc
iOS >= 9
Android >= 4.4
последние 2 версии
> 0.2%
не умер
Вы также можете прочитать больше о Browserslist здесь.
Почему browserslist является проблемой в Vite?
Vite использует ESBuild под капотом, который ожидает формат, отличный от обычного формата browserslist.
ESBuild ожидает формат: ['es2015', 'safari11', 'ios11'].
Формат списка браузеров: ['defaults', 'Safari >= 11', 'ios_saf >= 11'].
В результате этого несоответствия Vite игнорирует вашу конфигурацию browserslist, которая в данный момент находится в файле package.json или .brwserslistrc.
Чтобы исправить это, вы можете использовать пакет под названием browserslist-to-esbuild, который делает это преобразование под капотом и передает конфигурацию в build.target внутри файла vite.config.ts. Шаги 13 и 14 позаботятся об этом.
Шаг 13: Установите browserslist-to-esbuild.
yarn add browserslist-to-esbuild
ИЛИ
npm install browserslist-to-esbuild
Шаг 14: Подтверждаем browserslist в Vite Config
В файле vite.config.ts сделайте обновление, как показано ниже.
import { defineConfig } from 'vite'
import browserslistToEsbuild from 'browserslist-to-esbuild'
export default defineConfig({
..
build: {
// --> ["chrome79", "edge92", "firefox91", "safari13.1"]
target: browserslistToEsbuild(),
},
..
})
Затем вы можете передать свои конфигурации, как показано ниже,
export default defineConfig({
..
build: {
// вы также можете передать сюда свой обычный конфиг списка браузеров
target: browserslistToEsbuild([
'>0.2%',
'not dead',
'not op_mini all'
]),
},
..
})
Заключение
Вуаля! Вы закончили, и ваше приложение полностью перенесено.
Пропустили какой-нибудь шаг? Вот пример запроса на исправление, в котором выделены все изменения.
Вы узнали ”почему” и “как” заменить create-react-app на Vite. Надеюсь, вы гордитесь собой так же, как я гордился тем, что узнал в процессе миграции.
Хорошо, это все! Счастливого кодинга!