1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/tiansongbo-react-antd-manager

В этом репозитории не указан файл с открытой лицензией (LICENSE). При использовании обратитесь к конкретному описанию проекта и его зависимостям в коде.
Клонировать/Скачать
Внести вклад в разработку кода
Синхронизировать код
Отмена
Подсказка: Поскольку Git не поддерживает пустые директории, создание директории приведёт к созданию пустого файла .keep.
Loading...
README.md

Этот проект был создан с помощью Create React App.

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

Перевод: "Этот проект был создан с помощью Create React App.

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

  • create-react-app — это глобальная утилита командной строки, которую вы используете для создания новых проектов.
  • react-scripts — это зависимость для разработки в сгенерированных проектах (включая этот).

Вы почти никогда не будете нуждаться в обновлении create-react-app самой по себе: она делегирует все настройки на react-scripts.

Когда вы запускаете create-react-app, он всегда создает проект с последней версией react-scripts, поэтому вы автоматически получаете все новые функции и улучшения в новых проектах.

Чтобы обновить существующий проект до новой версии react-scripts, откройте журнал изменений, найдите версию, на которой вы находитесь (проверьте package.json в этой папке, если вы не уверены), и примите инструкции по миграции для новых версий.

В большинстве случаев увеличение версии react-scripts в package.json и выполнение npm install в этой папке должно быть достаточно, но полезно проконсультироваться с журналом изменений для возможных разрушительных изменений.

Мы обязуемся сохранять разрушительные изменения минимальными, чтобы вы могли обновлять react-scripts безболезненно.

Отправка отзывов

Мы всегда открыты для вашего отзыва.## Структура папок

После создания проект должен выглядеть следующим образом:

my-app/
  README.md
  node_modules/
  package.json
  public/
    index.html
    favicon.ico
  src/
    App.css
    App.js
    App.test.js
    index.css
    index.js
    logo.svg

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

  • public/index.html — это шаблон страницы;
  • src/index.js — это точка входа JavaScript.

Вы можете удалить или переименовать другие файлы.

Вы можете создавать подпапки внутри src. Для более быстрых сборок обрабатывается только содержимое папки src Webpack-ом.
Вы должны размещать все файлы JavaScript и CSS внутри src, иначе Webpack не увидит их.

Только файлы внутри public могут быть использованы из public/index.html.
Чтобы использовать активы из JavaScript и HTML, читайте инструкции ниже.

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

Доступные скрипты

В директории проекта вы можете запустить:

npm start

Запускает приложение в режиме разработки.
Откройте http://localhost:3000, чтобы просмотреть его в браузере.

Страница перезагрузится, если вы внесете изменения.
Вы также увидите ошибки проверки кода в консоли.

npm test

Запускает тестовый запускатель в интерактивном режиме отслеживания.
Чтобы узнать больше информации о запуске тестов, прочитайте соответствующий раздел.### npm run build

Создает приложение для продакшена в папке build.
Он правильно собирает React в режиме продакшена и оптимизирует сборку для наилучшей производительности.

Сборка минифицирована, и имена файлов включают хеши.
Ваше приложение готово к развертыванию!

Чтобы узнать больше информации о развертывании, прочитайте соответствующий раздел.

npm run eject

Внимание: это однократная операция. После выполнения eject вернуться назад нельзя!

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

Вместо этого она скопирует все конфигурационные файлы и транзитивные зависимости (Webpack, Babel, ESLint и т.д.) прямо в ваш проект, чтобы вы имели полный контроль над ними. Все команды, кроме eject, продолжат работать, но они будут указывать на скопированные скрипты, чтобы вы могли их настроить. В этот момент вы находитесь самостоятельно.

Вы не обязаны использовать eject. Подобранный набор функций подходит для небольших и средних развертываний, и вы не должны чувствовать себя обязанным использовать эту функцию. Однако мы понимаем, что этот инструмент не будет полезен, если вы не сможете настроить его, когда будете готовы к этому.## Поддерживаемые браузеры

По умолчанию, сгенерированный проект использует последнюю версию React.

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

Поддерживаемые языковые возможности и полифиллы

Этот проект поддерживает множество последнего стандарта языка JavaScript.
Кроме ES6 синтаксических возможностей, он также поддерживает:

Узнайте больше о разных стадиях предложений.

Хотя мы рекомендуем использовать экспериментальные предложения с некоторой осторожностью, Facebook активно использует эти функции в продукт-коде, поэтому мы намерены предоставлять codemods, если какие-либо из этих предложений изменятся в будущем.Обратите внимание, что проект включает только несколько ES6 polyfills:

Если вы используете какие-либо другие ES6+ функции, которые требуют временной поддержки (например, Array.from() или Symbol), убедитесь, что вы включаете соответствующие polyfills вручную или что браузеры, которые вы используете, уже поддерживают их.

Также обратите внимание, что использование некоторых новых синтаксических функций, таких как for...of или [...nonArrayValue], заставляет Babel генерировать код, который зависит от ES6 временных функций и может не работать без polyfill. Если у вас есть сомнения, используйте Babel REPL, чтобы увидеть, как любой конкретный синтаксис компилируется.

Выделение синтаксиса в редакторе

Чтобы настроить выделение синтаксиса в вашем любимом текстовом редакторе, перейдите на соответствующую страницу документации Babel и следуйте инструкциям. Некоторые из самых популярных редакторов включены.

Отображение вывода проверки на ошибки в редакторе>Примечание: эта функция доступна с react-scripts@0.2.0 и выше.

Она также работает только с npm 3 или выше.

Некоторые редакторы, включая Sublime Text, Atom и Visual Studio Code, предоставляют плагины для ESLint.

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

Вам потребуется установить плагин ESLint для вашего редактора. Затем добавьте файл под названием .eslintrc в корень проекта:

{
  "extends": "react-app"
}

Теперь ваш редактор должен отображать предупреждения проверки стиля кода.

Обратите внимание, что даже если вы измените ваш файл .eslintrc, эти изменения будут влиять только на интеграцию редактора. Они не повлияют на терминал и вывод проверки стиля кода в браузере. Это связано с тем, что Create React App предоставляет минимальное количество правил, которые помогают найти общие ошибки.

Если вы хотите применить определённые правила оформления кода для вашего проекта, рассмотрите возможность использования Prettier вместо правил стиля ESLint.

Отладка в редакторе

**Эта функция в настоящее время поддерживается только Visual Studio Code и WebStorm.**Visual Studio Code и WebStorm поддерживают отладку прямо из коробки с использованием Create React App. Это позволяет вам как разработчику писать и отлаживать свой код React без необходимости выходить из редактора. Это также позволяет вам иметь непрерывный процесс разработки, где минимальное количество переключений между инструментами обеспечивает максимальную продуктивность.

Visual Studio Code

Для использования этой функции вам потребуется последняя версия VS Code и расширение Chrome Debugger Extension для VS Code.

Затем добавьте блок кода ниже в ваш файл launch.json и поместите его в папку .vscode в корневой директории вашего приложения.

{
  "version": "0.2.0",
  "configurations": [{
    "name": "Chrome",
    "type": "chrome",
    "request": "launch",
    "url": "http://localhost:3000",
    "webRoot": "${workspaceRoot}/src",
    "sourceMapPathOverrides": {
      "webpack:///src/*": "${webRoot}/*"
    }
  }]
}

Примечание: URL может отличаться, если вы внесли изменения через переменные окружения HOST или PORT.

Запустите ваше приложение, выполнив команду npm start, и начните отладку в VS Code, нажав клавишу F5 или щелкнув зелёную иконку отладки. Теперь вы можете писать код, устанавливать точки останова, вносить изменения в код и отлаживать ваш отредактированный код — всё это прямо из вашего редактора.Встретили проблемы с отладкой в VS Code? Пожалуйста, обратитесь к их руководству по устранению неполадок.### WebStorm

Для работы вам потребуется WebStorm и расширение JetBrains IDE Support для браузера Chrome.

В меню WebStorm выберите Run -> Edit Configurations.... Затем нажмите + и выберите JavaScript Debug. Вставьте http://localhost:3000 в поле URL и сохраните конфигурацию.

Примечание: URL может быть другим, если вы внесли изменения через переменные окружения HOST или PORT.

Запустите ваше приложение командой npm start, затем нажмите ^D на macOS или F9 на Windows и Linux, или нажмите зелёную кнопку отладки, чтобы начать отладку в WebStorm.

То же самое можно сделать для отладки вашего приложения в IntelliJ IDEA Ultimate, PhpStorm, PyCharm Pro и RubyMine.

Автоматическое форматирование кода

Prettier — это убеждённый форматтер кода с поддержкой JavaScript, CSS и JSON. С помощью Prettier вы можете автоматически форматировать код, который вы пишете, чтобы обеспечить единообразный стиль кода в вашем проекте. Подробнее о Prettier можно узнать на странице проекта на GitHub, а также посмотреть этот пример работы Prettier.

Чтобы форматировать код перед каждым коммитом в git, вам нужно установить следующие зависимости:```sh npm install --save husky lint-staged prettier


В качестве альтернативы вы можете использовать `yarn`:

```sh
yarn add husky lint-staged prettier
  • husky позволяет легко использовать githooks как npm-скрипты.
  • lint-staged позволяет запускать скрипты на отмеченных для коммита файлах в git. Подробнее о lint-staged можно узнать на этом блоге.
  • prettier — это форматтер JavaScript, который мы будем запускать перед коммитами.

Теперь вы можете убедиться, что каждый файл правильно форматирован, добавив несколько строк в package.json в корне проекта.

Добавьте следующую строку в раздел scripts:

  "scripts": {
+   "precommit": "lint-staged",
    "start": "react-scripts start",
    "build": "react-scripts build",

Затем добавьте поле lint-staged в package.json, например:

  "dependencies": {
    // ...
  },
+ "lint-staged": {
+   "src/**/*.{js,jsx,json,css}": [
+     "prettier --single-quote --write",
+     "git add"
+   ]
+ },
  "scripts": {

Теперь каждый раз, когда вы делаете коммит, Prettier будет автоматически форматировать измененные файлы. Вы также можете запустить ./node_modules/.bin/prettier --single-quote --write "src/**/*.{js,jsx,json,css}", чтобы сформатировать весь проект в первый раз.

Далее вы можете интегрировать Prettier в свой любимый редактор. Прочитайте раздел о интеграции с редактором на странице Prettier в GitHub.

Изменение заголовка страницы <title>

Исходный HTML-файл можно найти в папке public сгенерированного проекта. Вы можете редактировать тег <title> в нем, чтобы изменить заголовок с "React App" на любой другой.Обратите внимание, что обычно вы не будете часто редактировать файлы в папке public. Например, добавление стилистики выполняется без изменения HTML.

Если вам нужно динамически обновлять заголовок страницы в зависимости от содержимого, вы можете использовать API браузера document.title. Для более сложных сценариев, когда вы хотите изменить заголовок из компонентов React, вы можете использовать React Helmet, библиотеку третьей стороны.

Если вы используете кастомный сервер для вашего приложения в продакшене и хотите изменить заголовок перед отправкой его в браузер, вы можете следовать советам в этой секции. В качестве альтернативы, вы можете предварительно построить каждый HTML-файл как статический файл, который затем загружает JavaScript-пакет, что описано здесь.

Установка зависимости

Сгенерированный проект включает React и ReactDOM как зависимости. Также включены наборы скриптов, используемые Create React App как зависимости разработки. Вы можете установить другие зависимости (например, React Router) с помощью npm:

npm install --save react-router

В качестве альтернативы вы можете использовать yarn:```sh yarn add react-router


Это работает для любой библиотеки, а не только для `react-router`.

## Импорт компонента

Эта конфигурация проекта поддерживает ES6 модули благодаря Babel.<br>
Хотя вы все еще можете использовать `require()` и `module.exports`, мы рекомендуем использовать [`import` и `export`](http://exploringjs.com/es6/ch_modules.html) вместо них.

Например:

### `Button.js`

```js
import React, { Component } from 'react';

Button.js

import React, { Component } from 'react';

Класс Button

class Button extends Component {
  render() {
    // ...
  }
}

export default Button; // Не забудьте использовать export default!

DangerButton.js

import React, { Component } from 'react';
import Button from './Button'; // Импорт компонента из другого файла

class DangerButton extends Component {
  render() {
    return <Button color="red" />;
  }
}

export default DangerButton;

Обратите внимание на различие между default и named импортами. Это распространённый источник ошибок.

Мы рекомендуем использовать default импорты и экспорт, когда модуль экспортирует только одно значение (например, компонент). Это то, что вы получаете, используя export default Button и import Button from './Button'.

Named экспорт полезен для модулей с утилитами, которые экспортируют несколько функций. Модуль может иметь только один default экспорт и столько named экспортов, сколько вам нужно.

Узнайте больше о ES6 модулях:* Когда использовать фигурные скобки?

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

Эта конфигурация проекта поддерживает разделение кода через динамическое import(). Его предложение находится на стадии 3. Функциональная форма import() принимает имя модуля в качестве аргумента и возвращает объект Promise, который всегда разрешается в пространство имен модуля.

Вот пример:

moduleA.js

const moduleA = 'Привет';

export { moduleA };

App.js

import React, { Component } from 'react';

class App extends Component {
  handleClick = () => {
    import('./moduleA')
      .then(({ moduleA }) => {
        // Использовать moduleA
      })
      .catch(err => {
        // Обработать ошибку
      });
  };
}

Для рендера используется следующий код:

render() {
  return (
    <div>
      <button onClick={this.handleClick}>Загрузить</button>
    </div>
  );
}
}

export default App;

Это позволит moduleA.js и все его уникальные зависимости быть отдельным куском, который загружается только после того, как пользователь нажмет кнопку "Загрузить".

Вы также можете использовать его с синтаксисом async / await, если вам это удобнее.

С React RouterЕсли вы используете React Router, ознакомьтесь с этим руководством о том, как использовать кодовое разделение с ним. Вы можете найти сопутствующий репозиторий GitHub здесь.Также ознакомьтесь с разделом Code Splitting в документации React.

Добавление стилей

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

Button.css

.Button {
  padding: 20px;
}

Button.js

import React, { Component } from 'react';
import './Button.css'; // Сообщаем Webpack, что Button.js использует эти стили

class Button extends Component {
  render() {
    // Вы можете использовать их как обычные CSS стили
    return <div className="Button" />;
  }
}

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

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

Если вы обеспокоены использованием семантики, специфичной для Webpack, вы можете поместить все ваши CSS прямо в src/index.css. Он все равно будет импортироваться из src/index.js, но вы всегда можете удалить этот импорт, если вы позже перейдете на другой инструмент сборки. ## Пост-обработка CSSЭтот проект автоматически минимизирует ваш CSS и добавляет префиксы для производителей через Autoprefixer, поэтому вам не нужно беспокоиться об этом.

Например, это:

.App {
  display: flex;
  flex-direction: row;
  align-items: center;
}

становится таким:

.App {
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  -webkit-box-orient: horizontal;
  -webkit-box-direction: normal;
      -ms-flex-direction: row;
          flex-direction: row;
  -webkit-box-align: center;
      -ms-flex-align: center;
          align-items: center;
}

Если вам нужно отключить автопрефексирование по какой-либо причине, следуйте этому разделу.

Добавление препроцессора CSS (Sass, Less и т.д.)

В целом мы рекомендуем не переиспользовать одни и те же CSS-классы в разных компонентах. Например, вместо использования класса CSS .Button в компонентах <AcceptButton> и <RejectButton>, мы рекомендуем создать компонент <Button> со своими собственными стилями .Button, которые могут рендериться как <AcceptButton>, так и <RejectButton> (но не наследоваться).

Следование этому правилу часто делает препроцессоры CSS менее полезными, так как функции, такие как миксины и вложенность, заменяются компонентной композицией. Однако вы можете интегрировать препроцессор CSS, если считаете это полезным. В этом руководстве мы будем использовать Sass, но вы также можете использовать Less или другой альтернативный вариант.Сначала установим командную строку для Sass:

npm install --save node-sass-chokidar

В качестве альтернативы вы можете использовать yarn:

yarn add node-sass-chokidar

Затем в файле package.json добавьте следующие строки в scripts:

   "scripts": {
+    "build-css": "node-sass-chokidar src/ -o src/",
+    "watch-css": "npm run build-css && node-sass-chokidar src/ -o src/ --watch --recursive",
     "start": "react-scripts start",
     "build": "react-scripts build",
     "test": "react-scripts test --env=jsdom",

Примечание: Чтобы использовать другой препроцессор, замените команды build-css и watch-css в соответствии с документацией вашего препроцессора. Теперь вы можете переименовать src/App.css в src/App.scss и запустить npm run watch-css. Монитор будет находить каждый файл Sass в подкаталогах src, и создавать соответствующий файл CSS рядом с ним, в данном случае перезаписывая src/App.css. Поскольку src/App.js всё ещё импортирует src/App.css, стили становятся частью вашего приложения. Вы можете теперь редактировать src/App.scss, и src/App.css будет перегенерирован. Чтобы поделиться переменными между файлами Sass, вы можете использовать импорты Sass. Например, файл src/App.scss и другие файлы стилей компонентов могут включать @import "./shared.scss"; с определениями переменных.

Чтобы включить возможность импорта файлов без использования относительных путей, вы можете добавить опцию --include-path к команде в package.json.

"build-css": "node-sass-chokidar --include-path ./src --include-path ./node_modules src/ -o src/",
"watch-css": "npm run build-css && node-sass-chokidar --include-path ./src --include-path ./node_modules src/ -o src/ --watch --recursive",
```Это позволит вам выполнять импорты, например:

```scss
@import 'styles/_colors.scss'; // предполагая наличие директории styles под src/
@import 'nprogress/nprogress'; // импорт CSS файла из модуля nprogress

На этом этапе вы можете захотеть удалить все CSS-файлы из системы контроля версий и добавить src/**/*.css в ваш файл .gitignore. Обычно это хорошая практика поддерживать результаты сборки вне системы контроля версий.

В качестве финального шага вы можете найти удобным автоматическое выполнение watch-css с помощью npm start, и выполнение build-css как часть npm run build. Вы можете использовать оператор && для выполнения двух скриптов последовательно. Однако нет кросс-платформенного способа выполнения двух скриптов параллельно, поэтому мы установим пакет для этого:

npm install --save npm-run-all

В качестве альтернативы вы можете использовать yarn:

yarn add npm-run-all

Затем мы можем изменить скрипты start и build для включения команд препроцессора CSS:

   "scripts": {
     "build-css": "node-sass-chokidar src/ -o src/",
     "watch-css": "npm run build-css && node-sass-chokidar src/ -o src/ --watch --recursive",
-    "start": "react-scripts start",
-   cq "build": "react-scripts build",
+    "start-js": "react-scripts start",
+    "start": "npm-run-all -p watch-css start-js",
+    "build-js": "react-scripts build",
+    "build": "npm-run-all build-css build-js",
     "test": "react-scripts test --env=jsdom",
     "eject": "react-scripts eject"
   }

Теперь выполнение npm start и npm run build также собирает файлы Sass.Почему node-sass-chokidar?

node-sass был отмечен следующими проблемами:

  • node-sass --watch был отмечен как имеющий производительность проблемы в определённых условиях при использовании в виртуальной машине или с использованием Docker.
  • Бесконечное компиляция стилей #1939
  • node-sass был отмечен как имеющий проблемы с обнаружением новых файлов в директории #1891

node-sass-chokidar используется здесь, так как он решает эти проблемы.

Добавление изображений, шрифтов и файлов

С Webpack использование статических активов, таких как изображения и шрифты, работает аналогично CSS.

Вы можете import файл прямо в модуле JavaScript. Это говорит Webpack включить этот файл в пакет. В отличие от импорта CSS, импорт файла дает строковое значение. Это значение — это конечный путь, который можно использовать в коде, например, как src атрибут изображения или href ссылки на PDF.

Чтобы снизить количество запросов к серверу, импорт изображений размером менее 10 000 байт возвращает data URI вместо пути. Это применимо к следующим расширениям файлов: bmp, gif, jpg, jpeg и png. Файлы SVG исключены из-за #1153.

Вот пример:

import React from 'react';
import logo from './logo.png'; // Сообщаем Webpack, что этот JS-файл использует это изображение
``````javascript
console.log(logo); // /logo.84287d09.png

function Header() {
  // Результат импорта — это путь к вашему изображению
  return <img src={logo} alt="Логотип" />;
}

export default Header;

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

Это работает и в CSS:

.Logo {
  background-image: url(./logo.png);
}

Webpack находит все относительные ссылки на модули в CSS (они начинаются с ./) и заменяет их конечными путями из собранного пакета. Если вы допускаете опечатку или случайно удаляете важный файл, вы увидите ошибку компиляции, как при импорте несуществующего JavaScript-модуля. Конечные имена файлов в собранном пакете генерируются Webpack на основе хэшей содержимого. Если содержимое файла изменится в будущем, Webpack даст ему другое имя в продакшене, поэтому вам не нужно беспокоиться о долгосрочном кэшировании активов.

Пожалуйста, обратите внимание, что это также является специальным функционалом Webpack.Не требуется для React, но многие люди это любят (и React Native использует похожий механизм для изображений). Альтернативный способ обработки статических активов описан в следующем разделе.

Использование папки public

Примечание: эта функция доступна с react-scripts@0.5.0 и выше.

Изменение HTMLПапка public содержит HTML-файл, поэтому вы можете изменять его, например, чтобы установить заголовок страницы.

Тег <script> с скомпилированным кодом будет добавлен к нему автоматически во время процесса сборки.### Добавление активов вне системы модулей

Вы также можете добавить другие активы в папку public.

Обратите внимание, что мы обычно рекомендуем вам import активов в JavaScript-файлах. Для примера, см. разделы добавления стилистики и добавления изображений, шрифтов и файлов. Эта механика предоставляет ряд преимуществ:

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

Однако существует выход из системы (escape hatch), который вы можете использовать, чтобы добавить актив вне системы модулей.

Если вы поместите файл в папку public, он не будет обрабатываться Webpack. Вместо этого он будет скопирован в папку сборки без изменений. Чтобы ссылаться на активы в папке public, вам нужно использовать специальную переменную PUBLIC_URL.

Внутри index.html вы можете использовать её следующим образом:

<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
```Только файлы внутри папки `public` будут доступны по префиксу `%PUBLIC_URL%`.
Если вам нужно использовать файл из `src` или `node_modules`, вам придётся скопировать его туда, чтобы явно указать ваше намерение сделать этот файл частью сборки.Когда вы запускаете `npm run build`, Create React App заменит `%PUBLIC_URL%` на правильный абсолютный путь, чтобы ваш проект работал даже если вы используете клиентскую маршрутизацию или хостите его на нестандартном URL.

В JavaScript-коде вы можете использовать `process.env.PUBLIC_URL` для аналогичных целей:

```js
render() {
  // Примечание: это выход из системы и следует использовать редко!
  // Обычно мы рекомендуем использовать `import` для получения URL активов
  // как описано в разделе "Добавление изображений и шрифтов" выше этого раздела.
  return <img src={process.env.PUBLIC_URL + '/img/logo.png'} />;
}

Учитывайте недостатки этого подхода:

  • Никакие файлы в папке public не проходят пост-обработку или минификацию.
  • Отсутствующие файлы не будут выявлены во время компиляции и вызовут ошибки 404 для ваших пользователей.
  • Имена выходных файлов не будут содержать хэши содержимого, поэтому вам потребуется добавить параметры запроса или переименовать их каждый раз, когда они изменяются.

Когда использовать папку public

Обычно мы рекомендуем импортировать стили, изображения и шрифты из JavaScript. Папка public полезна как обходной путь для ряда менее распространенных случаев:* Вам требуется файл с определенным именем в выходных данных сборки, например, manifest.webmanifest.

  • У вас есть тысячи изображений, и вам нужно динамически ссылаться на их пути.
  • Вы хотите включить небольшой скрипт, такой как pace.js, вне объединенного кода.
  • Некоторая библиотека может быть несовместима с Webpack, и у вас нет другого выбора, кроме как включить её как тег <script>.Обратите внимание, что если вы добавите <script>, который объявляет глобальные переменные, вам также потребуется прочитать следующий раздел о их использовании.

Использование глобальных переменных

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

Вы можете избежать этого, явно читающим глобальную переменную из объекта window, например:

const $ = window.$;

Это делает очевидным, что вы намеренно используете глобальную переменную, а не из-за опечатки.

В качестве альтернативы вы можете заставить линтер игнорировать любую строку, добавив // eslint-disable-line после неё.

Добавление Bootstrap

Вы не обязаны использовать React Bootstrap вместе с React, но это популярная библиотека для интеграции Bootstrap с React-приложениями. Если вам это нужно, вы можете интегрировать его с Create React App, следуя этим шагам:

Установите React Bootstrap и Bootstrap из npm. React Bootstrap не включает CSS Bootstrap, поэтому это необходимо установить отдельно:

npm install --save react-bootstrap bootstrap@3

В качестве альтернативы вы можете использовать yarn:

yarn add react-bootstrap bootstrap@3

Импортируйте CSS Bootstrap и, по желанию, CSS темы Bootstrap в начале файла src/index.js:```js import 'bootstrap/dist/css/bootstrap.css'; import 'bootstrap/dist/css/bootstrap-theme.css'; // Разместите любые другие импорты ниже, чтобы CSS из ваших // компонентов имел приоритет над стандартными стилями.


Импортируйте необходимые компоненты React Bootstrap в файл ```src/App.js``` или в ваши собственные файлы компонентов:

```js
import { Navbar, Jumbotron, Button } from 'react-bootstrap';

Теперь вы готовы использовать импортированные компоненты React Bootstrap в вашей иерархии компонентов, определенной в методе render. Вот пример файла App.js, переработанного с использованием React Bootstrap.

Использование пользовательской темы

Иногда вам может потребоваться настроить визуальные стили Bootstrap (или эквивалентного пакета).
Мы рекомендуем следующий подход:

  • Создайте новый пакет, зависящий от пакета, который вы хотите настроить, например Bootstrap.
  • Добавьте необходимые шаги сборки для настройки темы, и опубликуйте ваш пакет на npm.
  • Установите ваш собственный пакет темы npm как зависимость вашего приложения.

Вот пример добавления настроенной темы Bootstrap, которая следует этим шагам.

Добавление FlowFlow — это статический анализатор типов, который помогает писать код с меньшим количеством ошибок. Изучите этот вводный материал по использованию статических типов в JavaScript, если вы новичок в этой концепции.Недавние версии Flow работают с проектами Create React App из коробки.

Чтобы добавить Flow в проект Create React App, выполните следующие шаги:

  1. Выполните npm install --save flow-bin (или yarn add flow-bin).
  2. Добавьте "flow": "flow" в раздел scripts файла package.json.
  3. Выполните npm run flow init (или yarn flow init), чтобы создать файл .flowconfig в корневой директории.
  4. Добавьте // @flow в любые файлы, которые вы хотите типизировать (например, в src/App.js). Теперь вы можете запустить npm run flow (или yarn flow) для проверки файлов на наличие ошибок типов. По желанию вы можете использовать IDE, такое как Nuclide, для более интегрированного опыта. В будущем мы планируем интегрировать это в Create React App ещё теснее. Чтобы узнать больше о Flow, ознакомьтесь с его документацией.

Добавление маршрутизатора

Create React App не предписывает конкретное решение для маршрутизации, но React Router является наиболее популярным.

Чтобы добавить его, выполните:

npm install --save react-router-dom

В качестве альтернативы вы можете использовать yarn:

yarn add react-router-dom

Чтобы попробовать его, удалите весь код в src/App.js и замените его любым из примеров на его сайте. Пример Basic Example является хорошим местом для начала.Обратите внимание, что вам может потребоваться настроить ваш сервер для поддержки клиентской маршрутизации перед развертыванием приложения.

Добавление пользовательских переменных окружения

Примечание: эта функция доступна с react-scripts@0.2.3 и выше.

Ваш проект может использовать переменные окружения, объявленные в вашем окружении, как если бы они были объявлены локально в ваших JS файлах. По умолчанию у вас будет определена переменная NODE_ENV, а также любые другие переменные окружения, начинающиеся с REACT_APP_.

Переменные окружения встраиваются во время сборки. Поскольку Create React App создает статический HTML/CSS/JS пакет, он не может прочитать их во время выполнения. Чтобы прочитать их во время выполнения, вам потребуется загрузить HTML в память на сервере и заменить плейсхолдеры во время выполнения, как описано здесь. В качестве альтернативы вы можете пересобрать приложение на сервере каждый раз, когда изменяете эти переменные.>Примечание: вы должны создать пользовательские переменные окружения, начинающиеся с REACT_APP_. Любые другие переменные, кроме NODE_ENV, будут проигнорированы, чтобы избежать случайного предоставления закрытого ключа на машине, который мог бы иметь такое же имя. Изменение любых переменных окружения потребует перезапуска сервера разработки, если он запущен.Эти переменные окружения будут определены для вас в process.env. Например, имея переменную окружения с именем REACT_APP_SECRET_CODE будет доступна в ваших JS файлах как process.env.REACT_APP_SECRET_CODE. Также есть специальная встроенная переменная окружения с именем NODE_ENV. Вы можете прочитать её из process.env.NODE_ENV. Когда вы запускаете npm start, она всегда равна 'development', когда запускаете npm test — всегда равна 'test', и когда запускаете npm run build для создания продакшн-пакета, она всегда равна 'production'. Переменную NODE_ENV нельзя переопределить вручную. Это предотвращает разработчиков от случайного развертывания медленного продакшн-пакета в режиме разработки. Эти переменные окружения могут быть полезны для условного отображения информации в зависимости от того, где проект развернут, или для использования чувствительных данных, которые находятся вне системы контроля версий.

Сначала вам нужно определить переменные окружения. Например, предположим, что вы хотите использовать секрет, определенный в окружении, внутри <form>:

render() {
  return (
    <div>
      <small>Вы запускаете это приложение в режиме <b>{process.env.NODE_ENV}</b>.</small>
      <form>
        <input type="hidden" defaultValue={process.env.REACT_APP_SECRET_CODE} />
      </form>
    </div>
  );
}

Во время сборки process.env.REACT_APP_SECRET_CODE будет заменен текущим значением переменной окружения REACT_APP_SECRET_CODE. Помните, что переменная NODE_ENV будет установлена для вас автоматически.Когда вы загружаете приложение в браузере и проверяете <input>, вы увидите, что его значение установлено на abcdef, а жирный текст покажет окружение, предоставленное при использовании npm start:

<div>
  <small>Вы запускаете это приложение в режиме <b>development</b>.</small>
  <form>
    <input type="hidden" value="abcdef" />
  </form>
</div>

Вышеуказанный <form> ищет переменную с именем REACT_APP_SECRET_CODE в окружении. Чтобы использовать это значение, нам нужно определить его в окружении. Это можно сделать двумя способами: либо в вашей оболочке, либо в файле .env. Оба этих способа описаны в следующих разделах.

Доступ к переменной NODE_ENV также полезен для выполнения действий условно:

if (process.env.NODE_ENV !== 'production') {
  analytics.disable();
}

Когда вы собираете приложение с помощью npm run build, шаг минификации удалит это условие, и результирующий пакет будет меньше.

Ссылки на переменные окружения в HTML

Примечание: эта функция доступна с react-scripts@0.9.0 и выше.

Вы также можете получить доступ к переменным окружения, начинающимся с REACT_APP_, в public/index.html. Например:

<title>%REACT_APP_WEBSITE_NAME%</title>

Обратите внимание, что примечания из предыдущего раздела применимы:* В дополнение к нескольким встроенным переменным (NODE_ENV и PUBLIC_URL), имена переменных должны начинаться с REACT_APP_, чтобы работать.

  • Переменные окружения внедряются во время сборки. Если вам нужно внедрить их во время выполнения, следуйте этому подходу.

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

Windows (cmd.exe)

set "REACT_APP_SECRET_CODE=abcdef" && npm start

(Примечание: Кавычки вокруг присвоения переменной обязательны для предотвращения появления пробела в конце.)

Windows (PowerShell)

($env:REACT_APP_SECRET_CODE = "abcdef") -and (npm start)

Linux, macOS (Bash)

REACT_APP_SECRET_CODE=abcdef npm start

Добавление переменных окружения для разработки в файл .env

Примечание: данная функция доступна с react-scripts@0.5.0 и выше.

Чтобы определить постоянные переменные окружения, создайте файл с именем .env в корне вашего проекта:

REACT_APP_SECRET_CODE=abcdef

Примечание: Вы должны создать пользовательские переменные окружения, начинающиеся с REACT_APP_. Любые другие переменные, кроме NODE_ENV, будут проигнорированы для предотвращения случайного раскрытия приватного ключа на машине, которая может иметь такое же имя. Изменение любых переменных окружения потребует перезапуска сервера разработки, если он запущен.

Файлы .env должны быть добавлены в систему контроля версий (с исключением файлов .env*.local).

Какие другие файлы .env могут быть использованы?

Примечание: данная функция доступна с react-scripts@1.0.0 и выше.* .env: По умолчанию.

  • .env.local: Локальные переопределения. Этот файл загружается для всех окружений, кроме тестового.

  • .env.development, .env.test, .env.production: Окружение-специфические настройки.

  • .env.development.local, .env.test.local, .env.production.local: Локальные переопределения окружение-специфических настроек.Файлы слева имеют более высокий приоритет, чем файлы справа:

  • npm start: .env.development.local, .env.development, .env.local, .env

  • npm run build: .env.production.local, .env.production, .env.local, .env

  • npm test: .env.test.local, .env.test, .env (примечание: .env.local отсутствует)

Эти переменные будут служить значениями по умолчанию, если машина не явно устанавливает их.
Для получения дополнительной информации обратитесь к документации dotenv. Примечание: Если вы определяете переменные окружения для разработки, ваш CI и/или платформа хостинга, скорее всего, также потребуют их определения. Обратитесь к их документации для получения информации о том, как это сделать. Например, см. документацию для Travis CI или Heroku.

Раскрытие переменных окружения в файле .env

Примечание: эта функция доступна с react-scripts@1.1.0 и выше.

Раскройте переменные, уже определенные на вашем компьютере, для использования в вашем файле .env (используя dotenv-expand).

Например, чтобы получить переменную окружения npm_package_version:

REACT_APP_VERSION=$npm_package_version
# также работает:
# REACT_APP_VERSION=${npm_package_version}

Или раскройте переменные, локальные к текущему файлу .env:

DOMAIN=www.example.com
REACT_APP_FOO=$DOMAIN/foo
REACT_APP_BAR=$DOMAIN/bar

Можно ли использовать декораторы?Многие популярные библиотеки используют декораторы в своей документации.

Create React App в настоящее время не поддерживает синтаксис декораторов, поскольку:

  • Это экспериментальное предложение и подвержено изменениям.
  • Текущая версия спецификации не официально поддерживается Babel.
  • Если спецификация изменится, мы не сможем написать код модификатора, так как мы не используем их внутренне в Facebook.

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

Create React App добавит поддержку декораторов, когда спецификация достигнет стабильной стадии.

Запрос данных с помощью AJAXReact не предписывает конкретный подход к запросу данных, но люди обычно используют либо библиотеку, такую как axios, либо API fetch(), предоставляемое браузером. Удобно, что Create React App включает полифилл для fetch(), поэтому вы можете использовать его, не беспокоясь о поддержке браузеров. Глобальная функция fetch позволяет легко выполнять AJAX-запросы. Она принимает URL в качестве входных данных и возвращает Promise, который разрешается в объект Response. Вы можете найти больше информации о fetch здесь. Этот проект также включает polyfill Promise, который предоставляет полную реализацию Promises/A+. Promise представляет собой конечный результат асинхронной операции, вы можете найти больше информации о Promise здесь и здесь. Оба axios и fetch() используют Promise в качестве внутренней реализации. Вы также можете использовать синтаксис async / await для уменьшения вложенности callback.Вы можете узнать больше о выполнении AJAX-запросов из компонентов React в вопросе FAQ на сайте React.

Интеграция с API-сервером

Эти руководства помогут вам интегрировать ваше приложение с API-сервером, работающим на другом порту, используя fetch() для доступа к нему.

Node

Посмотрите этот учебник. Вы можете найти сопутствующий репозиторий GitHub здесь.

Ruby on Rails

Посмотрите этот учебник. Вы можете найти сопутствующий репозиторий GitHub здесь.

Проксирование API-запросов в разработке

Примечание: эта функция доступна с react-scripts@0.2.3 и выше.

Люди часто размещают фронтенд React-приложение на том же хосте и порту, что и их backend-реализация. Например, производственная конфигурация может выглядеть так после развертывания приложения:

/             - статический сервер возвращает index.html с React-приложением
/todos        - статический сервер возвращает index.html с React-приложением
/api/todos    - сервер обрабатывает любые запросы /api/* с помощью backend-реализации

Такое размещение не обязательно. Однако, если вы имеете такую конфигурацию, удобно выполнять запросы вида fetch('/api/todos') без необходимости перенаправления их на другой хост или порт в процессе разработки.Чтобы указать серверу разработки проксировать все неизвестные запросы к вашему API-серверу в разработке, добавьте поле proxy в ваш package.json, например:

  "proxy": "http://localhost:4000",

Таким образом, когда вы fetch('/api/todos') в режиме разработки, сервер разработки распознает, что это не статический ресурс, и перенаправляет ваш запрос на http://localhost:4000/api/todos в качестве резервного варианта. Сервер разработки будет только пытаться отправлять запросы без text/html в заголовке Accept к прокси.

Конечно, это избегает проблем CORS и сообщений об ошибках, таких как этот в режиме разработки:

Fetch API cannot load http://localhost:4000/api/todos. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3000' is therefore not allowed access. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

Не забывайте, что proxy действует только в режиме разработки (с npm start), и вам нужно убедиться, что URL-адреса, такие как /api/todos, указывают на правильное место в продакшене. Вы не обязаны использовать префикс /api. Любые неизвестные запросы без заголовка text/html будут перенаправлены на указанный proxy.

Параметр proxy поддерживает HTTP, HTTPS и соединения WebSocket. Если параметр proxy не достаточно гибок для вас, вы можете:* Настроить прокси самостоятельно

При включении параметра proxy вы соглашаетесь с более строгим набором проверок хоста. Это необходимо, так как оставление бэкенда открытым для удаленных хостов делает ваш компьютер уязвимым для атак DNS rebinding. Проблема объясняется в этой статье и этом вопросе.

Это не должно повлиять на вас при разработке на localhost, но если вы разрабатываете удаленно, как описано здесь, вы увидите эту ошибку в браузере после включения параметра proxy.

Недействительный заголовок Host

Чтобы обойти эту проблему, вы можете указать ваш публичный разработочный хост в файле под названием .env.development в корне вашего проекта:

HOST=mypublicdevhost.com

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

Если у вас всё ещё возникают проблемы или если вы используете более экзотическую среду, такую как облачный редактор, вы можете полностью обойти проверку хоста, добавив строку в .env.development.local. Обратите внимание, что это опасно и делает вашу машину уязвимой для выполнения удалённого кода с вредоносных сайтов:

# ВНИМАНИЕ: ЭТО ОПАСНО!
# Это делает вашу машину уязвимой для атак с сайтов, которые вы посещаете.
DANGEROUSLY_DISABLE_HOST_CHECK=true
```Мы не рекомендуем этот подход.

### Ручная настройка прокси

>Примечание: эта функция доступна с `react-scripts@1.0.0` и выше.

Если опция `proxy` **не** достаточно гибкая для вас, вы можете указать объект в следующем формате (в `package.json`).<br>
Вы также можете указать любое значение конфигурации, поддерживаемое [`http-proxy-middleware`](https://github.com/chimurai/http-proxy-middleware#options) или [`http-proxy`](https://github.com/nodejitsu/node-http-proxy#options).
```js
{
  // ...
  "proxy": {
    "/api": {
      "target": "<url>",
      "ws": true
      // ...
    }
  }
  // ...
}

Все запросы, соответствующие этому пути, будут проксироваться, без исключений. Это включает запросы для text/html, которые стандартная опция proxy не проксирует.

Если вам нужно указать несколько прокси, вы можете сделать это, добавив дополнительные записи. Совпадения являются регулярными выражениями, поэтому вы можете использовать регулярное выражение для соответствия нескольким путям.

{
  // ...
  "proxy": {
    // Соответствует любому запросу, начинающемуся с /api
    "/api": {
      "target": "<url_1>",
      "ws": true
      // ...
    },
    // Соответствует любому запросу, начинающемуся с /foo
    "/foo": {
      "target": "<url_2>",
      "ssl": true,
      "pathRewrite": {
        "^/foo": "/foo/beta"
      }
      // ...
    },
    // Соответствует /bar/abc.html, но не /bar/sub/def.html
    "/bar/[^/]*[.]html": {
      "target": "<url_3>",
      // ...
    },
    // Соответствует /baz/abc.html и /baz/sub/def.html
    "/baz/.*/.*[.]html": {
      "target": "<url_4>"
      // ...
    }
  }
  // ...
}

Настройка прокси-сервера для WebSocketПри настройке прокси-сервера для WebSocket следует учитывать несколько дополнительных аспектов.

Если вы используете WebSocket-движок, такой как Socket.io, вам потребуется запущенный сервер Socket.io, который можно использовать в качестве целевого объекта прокси. Socket.io не будет работать с обычным WebSocket-сервером. В частности, не ожидайте, что Socket.io будет работать с тестом эхо на websocket.org.

Есть хорошая документация по настройке сервера Socket.io.

Обычные WebSocket будут работать с обычным WebSocket-сервером, а также с тестом эхо на websocket.org. Вы можете использовать библиотеки, такие как ws для сервера, а также нативные WebSocket в браузере.

В любом случае, вы можете вручную настроить прокси-запросы WebSocket в файле package.json:

{
  // ...
  "proxy": {
    "/socket": {
      // Ваш совместимый WebSocket-сервер
      "target": "ws://<socket_url>",
      // Сообщите http-proxy-middleware, что это прокси-сервер для WebSocket.
      // Также позволяет вам проксировать запросы WebSocket без дополнительного HTTP-запроса
      // https://github.com/chimurai/http-proxy-middleware#external-websocket-upgrade
      "ws": true
      // ...
    }
  }
  // ...
}

Использование HTTPS в разработке

Примечание: эта функция доступна с react-scripts@0.4.0 и выше.Вы можете потребовать, чтобы сервер разработки обслуживал страницы по протоколу HTTPS. Одним из случаев, когда это может быть полезно, является использование функции "proxy" для проксирования запросов к серверу API, когда сам сервер API использует HTTPS.Для этого установите переменную окружения HTTPS в значение true, затем запустите сервер разработки как обычно с помощью npm start:

Windows (cmd.exe)

set HTTPS=true&&npm start

Windows (Powershell)

($env:HTTPS = $true) -and (npm start)

(Примечание: отсутствие пробелов является намеренным.)

Linux, macOS (Bash)

HTTPS=true npm start

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

Генерация динамических тегов <meta> на сервере

Так как Create React App не поддерживает серверное рендеринг, вы можете задаться вопросом, как сделать теги <meta> динамическими и отражать текущий URL. Для решения этой проблемы рекомендуется добавить плейсхолдеры в HTML, например:

<!doctype html>
<html lang="en">
  <head>
    <meta property="og:title" content="__OG_TITLE__">
    <meta property="og:description" content="__OG_DESCRIPTION__">
  </head>
</html>

Затем, на сервере, независимо от используемого вами backend, вы можете считать index.html в память и заменить __OG_TITLE__, __OG_DESCRIPTION__ и любые другие плейсхолдеры значениями, зависящими от текущего URL. Убедитесь, что санитизируете и экранируете интерполированные значения, чтобы они были безопасны для встраивания в HTML!

Если вы используете сервер на Node, вы можете даже разделить логику соответствия маршрутов между клиентом и сервером. Однако дублирование также работает хорошо в простых случаях.## Предрендеринг в статические HTML-файлы

Если вы хостите свой build с помощью статического хостинг-провайдера, вы можете использовать react-snapshot или react-snap для генерации HTML-страниц для каждого маршрута или относительной ссылки в вашем приложении. Эти страницы затем будут активированы или "гидратированы", когда загрузится пакет JavaScript.

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

Основное преимущество предрендеринга заключается в том, что вы получаете основной контент каждой страницы с HTML-пакетом — независимо от того, успешно ли загружается пакет JavaScript. Это также увеличивает вероятность того, что каждый маршрут вашего приложения будет обнаружен поисковыми системами.

Вы можете прочитать больше о нулевом конфигурационном предрендеринге (также называемом snapshotting).

Внедрение данных с сервера в страницу

Аналогично предыдущему разделу, вы можете оставить некоторые плейсхолдеры в HTML, которые внедряют глобальные переменные, например:```js <!doctype html>

<script> window.SERVER_DATA = __SERVER_DATA__; </script> ```Затем на сервере вы можете заменить `__SERVER_DATA__` на JSON с реальными данными непосредственно перед отправкой ответа. Клиентский код может затем прочитать `window.SERVER_DATA` для использования данных. **Убедитесь, что [JSON очищен перед отправкой клиенту](https://medium.com/node-security/the-most-common-xss-vulnerability-in-react-js-applications-2bdffbcc1fa0), так как это делает вашу приложение уязвимым для атак XSS.**## Запуск тестов>Примечание: эта функция доступна с `react-scripts@0.3.0` и выше.
>[Чтобы узнать, как включить её в старых проектах, прочитайте миграционное руководство!](https://github.com/facebookincubator/create-react-app/blob/master/CHANGELOG.md#migrating-from-023-to-030)

Create React App использует Jest в качестве своего тестового запускателя. Для подготовки к этой интеграции мы провели значительное обновление Jest, поэтому если вы слышали плохое о нём в прошлом, попробуйте его ещё раз.

Jest — это запускатели на основе Node. Это означает, что тесты всегда запускаются в окружении Node и не в реальном браузере. Это позволяет нам обеспечить быструю скорость итераций и предотвратить нестабильность.

Хотя Jest предоставляет глобальные переменные браузера, такие как window, благодаря jsdom, они являются лишь приближением к поведению реального браузера. Jest предназначен для использования для юнит-тестирования вашей логики и компонентов, а не для квирков DOM.

Мы рекомендуем использовать отдельный инструмент для браузерных тестов end-to-end, если вам это нужно. Они выходят за рамки Create React App.

Конвенции названий файлов

Jest ищет файлы с тестами с любыми из следующих популярных конвенций названий файлов:

  • Файлы с суффиксом .js в папках __tests__.
  • Файлы с суффиксом .test.js.
  • Файлы с суффиксом .spec.js.Файлы с суффиксами .test.js / .spec.js (или папки __tests__) могут находиться на любом уровне под папкой src.

Мы рекомендуем размещать файлы с тестами (или папки __tests__) рядом с кодом, который они тестируют, чтобы относительные импорты выглядели короче. Например, если App.test.js и App.js находятся в одной папке, тест просто должен import App from './App', а не длинным относительным путём. Коллокация также помогает быстрее находить тесты в больших проектах.

Командная строка

Когда вы запускаете npm test, Jest запускается в режиме отслеживания. Каждый раз, когда вы сохраняете файл, он перезапускает тесты, как и npm start перекомпилирует код.

Отслеживатель включает интерактивный интерфейс командной строки с возможностью запуска всех тестов или фокусироваться на шаблоне поиска. Он разработан таким образом, чтобы вы могли оставить его открытым и наслаждаться быстрыми перезапусками. Вы можете узнать команды из заметки «Watch Usage», которую отслеживатель печатает после каждого запуска:Режим наблюдения Jest

Интеграция с системами контроля версийПо умолчанию, когда вы запускаете npm test, Jest выполняет только те тесты, которые связаны с файлами, изменившимися с момента последнего коммита. Это оптимизация, направленная на то, чтобы ваши тесты выполнялись быстро, независимо от того, сколько у вас тестов. Однако это предполагает, что вы редко коммитите код, который не проходит тесты.Jest всегда явно упоминает, что он выполняет только те тесты, которые связаны с файлами, изменившимися с момента последнего коммита. Вы также можете нажать a в режиме наблюдения, чтобы заставить Jest выполнить все тесты.

Jest всегда выполняет все тесты на сервере непрерывной интеграции или если проект находится вне Git или Mercurial репозитория.

Написание тестов

Чтобы создать тесты, добавьте блоки it() (или test()) с названием теста и его кодом. Вы можете опционально обернуть их в блоки describe() для логической группировки, но это ни к чему не обязывает и не рекомендуется.

Jest предоставляет встроенную глобальную функцию expect() для создания утверждений. Пример базового теста может выглядеть так:

import sum from './sum';

it('складывает числа', () => {
  expect(sum(1, 2)).toEqual(3);
  expect(sum(2, 2)).toEqual(4);
});

Все поддерживаемые Jest утверждения полностью документированы здесь.
Вы также можете использовать jest.fn() и expect(fn).toBeCalled() для создания "шпионов" или моковых функций.

Тестирование компонентовСуществует широкий спектр методов тестирования компонентов. Они варьируются от "дымовых тестов", проверяющих, что компонент отображается без выброса исключений, до частичного рендеринга и тестирования части вывода, до полного рендеринга и тестирования жизненного цикла и изменений состояния компонента.Разные проекты выбирают разные торговые соглашения по тестированию в зависимости от того, насколько часто меняются компоненты, и сколько логики они содержат. Если вы еще не выбрали стратегию тестирования, мы рекомендуем вам начать с создания простых "дымовых тестов" для ваших компонентов:

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';

it('рендерится без выброса исключений', () => {
  const div = document.createElement('div');
  ReactDOM.render(<App />, div);
});

Этот тест монтирует компонент и проверяет, что он не выбросил исключение во время рендера. Тесты такого типа предоставляют много ценной информации с минимальными усилиями, поэтому они являются отличным стартовым пунктом, и именно такой тест вы найдете в файле src/App.test.js.

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

Если вы хотите тестировать компоненты в изоляции от дочерних компонентов, которые они рендерят, мы рекомендуем использовать API shallow() рендера из Enzyme. Для установки выполните:

npm install --save enzyme enzyme-adapter-react-16 react-test-renderer
```В качестве альтернативы вы можете использовать `yarn`:

```sh
yarn add enzyme enzyme-adapter-react-16 react-test-renderer

С версии Enzyme 3 вам потребуется установить Enzyme вместе с адаптером, соответствующим версии React, которую вы используете. (Примеры выше используют адаптер для React 16.)

Адаптер также потребуется настроить в вашем глобальном файле настроек:

src/setupTests.js

import { configure } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';

configure({ adapter: new Adapter() });

Примечание: Имейте в виду, что если вы решите "выпустить" (eject) до создания src/setupTests.js, файл package.json не будет содержать ссылку на него. Читайте здесь, чтобы узнать, как добавить это после выпуска.

Теперь вы можете написать тест на выявление ошибок с его помощью:

import React from 'react';
import { shallow } from 'enzyme';
import App from './App';

it('рендерится без ошибок', () => {
  shallow(<App />);
});
```В отличие от предыдущего теста на выявление ошибок, использующего `ReactDOM.render()`, этот тест рендерит только `<App>` и не идёт глубже. Например, даже если `<App>` сам рендерит `<Button>`, который выбрасывает исключение, этот тест пройдёт. Shallow рендеринг отлично подходит для изолированных юнит-тестов, но вы всё ещё можете захотеть создать некоторые полные тесты рендера, чтобы убедиться, что компоненты правильно интегрируются. Enzyme поддерживает [полный рендер с `mount()`](http://airbnb.io/enzyme/docs/api/mount.html), и вы также можете использовать его для тестирования изменений состояния и жизненного цикла компонентов. Вы можете ознакомиться с [документацией Enzyme](http://airbnb.io/enzyme/) для получения дополнительных тестовых техник. Документация Enzyme использует Chai и Sinon для утверждений, но вы не обязаны использовать их, так как Jest предоставляет встроенные `expect()` и `jest.fn()` для шпионов.Вот пример из документации Enzyme, который утверждает конкретный вывод, переписанный с использованием матчеров Jest:

```js
import React from 'react';
import { shallow } from 'enzyme';
import App from './App';

it('рендерит приветственное сообщение', () => {
  const wrapper = shallow(<App />);
  const welcome = <h2>Добро пожаловать в React</h2>;
  // expect(wrapper.contains(welcome)).to.equal(true);
  expect(wrapper.contains(welcome)).toEqual(true);
});

Все матчеры Jest подробно документированы здесь.
Однако вы можете использовать стороннюю библиотеку утверждений, такую как Chai, если хотите, как описано ниже.

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

expect(wrapper).toContainReact(welcome)

Чтобы включить это, установите jest-enzyme:

npm install --save jest-enzyme

Альтернативно вы можете использовать yarn:

yarn add jest-enzyme

Импортируйте его в src/setupTests.js, чтобы сделать его матчеры доступными для каждого теста:

import 'jest-enzyme';

Использование сторонних библиотек утвержденийМы рекомендуем использовать expect() для утверждений и jest.fn() для шпионов. Если у вас возникли проблемы с ними, пожалуйста, отправьте их в репозиторий Jest, и мы исправим их. Мы намерены продолжать улучшать их для React, поддерживая, например, красивую печать React элементов как JSX.Однако, если вы привыкли к другим библиотекам, таким как Chai и Sinon, или если у вас есть существующий код, использующий их, который вы хотите перенести, вы можете импортировать их обычным образом:

import sinon from 'sinon';
import { expect } from 'chai';

и затем использовать их в ваших тестах так, как вы обычно делаете.

Инициализация тестового окружения

Примечание: эта функция доступна с react-scripts@0.4.0 и выше.

Если ваше приложение использует браузерную API, которую вы хотите имитировать в тестах, или если вам просто нужно глобальное настроить окружение перед запуском тестов, добавьте файл src/setupTests.js в ваш проект. Он будет автоматически выполнен перед запуском тестов.

Пример:

src/setupTests.js

const localStorageMock = {
  getItem: jest.fn(),
  setItem: jest.fn(),
  clear: jest.fn()
};
global.localStorage = localStorageMock;

Примечание: имейте в виду, что если вы решите "eject" до создания src/setupTests.js, в результирующем файле package.json не будет ссылок на него, поэтому вам нужно будет вручную создать свойство setupTestFrameworkScriptFile в конфигурации для Jest, что-то вроде следующего:

"jest": {
  // ...
  "setupTestFrameworkScriptFile": "<rootDir>/src/setupTests.js"
 }

Фокусировка и исключение тестов

Вы можете заменить it() на xit() для временного исключения теста из выполнения.
Аналогично, fit() позволяет сосредоточиться на конкретном тесте, не запуская другие тесты.### Отчет о покрытии

Jest имеет встроенный отчет о покрытии, который хорошо работает с ES6 и требует минимальной конфигурации.
Запустите npm test -- --coverage (обратите внимание на дополнительный -- в середине) для включения отчета о покрытии, например:

отчет о покрытии

Обратите внимание, что тесты выполняются значительно медленнее с покрытием, поэтому рекомендуется запускать его отдельно от вашего обычного рабочего процесса.

Конфигурация

По умолчанию конфигурация покрытия Jest может быть переопределена добавлением одного из следующих поддерживаемых ключей в конфигурацию Jest в вашем файле package.json.

Поддерживаемые переопределения:

Пример файла package.json:json { "name": "your-package", "jest": { "collectCoverageFrom": [ "src/**/*.{js,jsx}", "!<rootDir>/node_modules/", "!<rootDir>/path/to/dir/" ], "coverageThreshold": { "global": { "branches": 90, "functions": 90, "lines": 90, "statements": 90 } }, "coverageReporters": ["text"], "snapshotSerializers": ["my-serializer-module"] } } ### Непрерывная интеграцияПо умолчанию npm test запускает watcher с интерактивным CLI. Однако вы можете заставить его выполнить тесты один раз и завершить процесс, установив переменную окружения под названием CI.При создании сборки вашего приложения с помощью npm run build предупреждения линтера по умолчанию не проверяются. Как и в случае с npm test, вы можете заставить сборку проверять предупреждения линтера, установив переменную окружения CI. Если будут обнаружены предупреждения, сборка завершится неудачей.

Популярные серверы CI по умолчанию устанавливают переменную окружения CI, но вы можете сделать это и самостоятельно:

На серверах CI

Travis CI

  1. Следуйте руководству по началу работы для синхронизации вашего репозитория GitHub с Travis. Возможно, вам придется инициализировать некоторые настройки вручную на вашей странице профиля.
  2. Добавьте файл .travis.yml в ваш репозиторий git.
language: node_js
node_js:
  - 6
cache:
  directories:
    - node_modules
script:
  - npm run build
  - npm test
  1. Запустите ваш первый сбор с помощью git push.
  2. Настройте свой сбор Travis CI, если это необходимо.

CircleCI

Следуйте этому руководству для настройки CircleCI с проектом Create React App.

В вашей собственной среде

Windows (cmd.exe)
set CI=true&&npm test
set CI=true&&npm run build

(Примечание: отсутствие пробелов намеренно.)

Windows (Powershell)
($env:CI = $true) -and (npm test)
($env:CI = $true) -and (npm run build)
Linux, macOS (Bash)```bash

CI=true npm test


```bash
CI=true npm run build

Команда тестирования заставит Jest выполнить тесты один раз вместо запуска watcher.

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

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

Отключение jsdom

По умолчанию, package.json сгенерированного проекта выглядит следующим образом:

  "scripts": {
    "start": "react-scripts start",
   cq "build": "react-scripts build",
    "test": "react-scripts test --env=jsdom"
  }

Если вы знаете, что ни один из ваших тестов не зависит от jsdom, вы можете безопасно удалить --env=jsdom, и ваши тесты будут выполняться быстрее:

  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
-   "test": "react-scripts test --env=jsdom"
+   "test": "react-scripts test"
  }

Чтобы помочь вам принять решение, вот список API, которые требуют jsdom:

Наконец, jsdom также не требуется для тестирования снапшотов.

Тестирование снапшотов

Тестирование снапшотов — это функция Jest, которая автоматически генерирует текстовые снапшоты ваших компонентов и сохраняет их на диске, чтобы если вывод UI изменился, вы получили уведомление без необходимости вручную писать утверждения на вывод компонента. Читайте больше о тестировании снапшотов.

Интеграция с редактором

Если вы используете Visual Studio Code, есть расширение Jest, которое работает с Create React App из коробки. Это предоставляет множество функций IDE-типа, используя текстовый редактор: показывает статус тестового запуска с потенциальными сообщениями об ошибках в реальном времени, автоматически запускает и останавливает watcher, и предлагает однонажатие обновление снапшотов.VS Code Jest Preview

Отладка тестов

Существует несколько способов настройки отладчика для ваших тестов Jest. Мы рассматриваем отладку в Chrome и Visual Studio Code.>Примечание: отладка тестов требует Node 8 или выше.

Отладка тестов в Chrome

Добавьте следующее в раздел scripts в вашем проекте package.json

"scripts": {
    "test:debug": "react-scripts --inspect-brk test --runInBand --env=jsdom"
  }

Добавьте debugger; в любом тесте и запустите:

$ npm run test:debug

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

Откройте следующее в Chrome

about:inspect

После открытия этой ссылки, будут отображены Chrome Developer Tools. Выберите inspect для вашего процесса, и будет установлена точка останова на первой строке react скрипта (это делается просто для того, чтобы дать вам время открыть инструменты разработчика и предотвратить выполнение Jest до того, как вы успеете это сделать). Нажмите кнопку, которая выглядит как "play" в верхнем правом углу экрана, чтобы продолжить выполнение. Когда Jest выполнит тест, содержащий точку останова, выполнение будет приостановлено, и вы сможете изучить текущий контекст и стек вызовов.

Примечание: опция командной строки --runInBand гарантирует, что Jest будет запускать тесты в одном процессе, а не запускать отдельные процессы для каждого теста. Обычно Jest параллелизирует выполнение тестов в нескольких процессах, но отладка многих процессов одновременно затруднительна.### Отладка тестов в Visual Studio Code

Отладка тестов Jest поддерживается из коробки для Visual Studio Code.

Используйте следующую конфигурацию файла launch.json:

{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "Отладка тестов CRA",
      "type": "node",
      "request": "launch",
      "runtimeExecutable": "${workspaceRoot}/node_modules/.bin/react-scripts",
      "args": [
        "test",
        "--runInBand",
        "--no-cache",
        "--env=jsdom"
      ],
      "cwd": "${workspaceRoot}",
      "protocol": "inspector",
      "console": "integratedTerminal",
      "internalConsoleOptions": "neverOpen"
    }
  ]
}

Разработка компонентов в изоляции

Обычно в приложении есть множество UI-компонентов, и каждый из них имеет множество различных состояний. Например, простая кнопка может иметь следующие состояния:

  • В обычном состоянии с текстовой меткой.
  • В отключённом режиме.
  • В состоянии загрузки.

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

Create React App не включает никаких инструментов для этого по умолчанию, но вы можете легко добавить Storybook для React (источник) или React Styleguidist (источник) в ваш проект. Это сторонние инструменты, которые позволяют вам разрабатывать компоненты и видеть все их состояния в изоляции от вашего приложения.

Пример Storybook для ReactВы также можете развернуть ваш Storybook или руководство по стилю как статическое приложение. Таким образом, каждый член вашей команды может просматривать и проверять различные состояния UI-компонентов без запуска сервера или создания учётной записи в вашем приложении.

Начало работы с Storybook

Storybook — это среда разработки для React UI-компонентов. Он позволяет просматривать библиотеку компонентов, видеть различные состояния каждого компонента и интерактивно разрабатывать и тестировать компоненты.

Сначала установите следующий npm-пакет глобально:

npm install -g @storybook/cli

Затем выполните следующую команду внутри директории вашего приложения:

getstorybook

После этого следуйте инструкциям на экране.

Узнайте больше о React Storybook:

Начало работы с StyleguidistStyleguidist объединяет руководство по стилю, где все ваши компоненты представлены на одной странице с документацией по их свойствам и примерами использования, с окружением для разработки компонентов в изоляции, подобно Storybook. В Styleguidist вы пишете примеры в Markdown, где каждый фрагмент кода отображается как интерактивное редактируемое окружение. Сначала установите Styleguidist:```sh

npm install --save react-styleguidist


В качестве альтернативы вы можете использовать `yarn`:

```sh
yarn add react-styleguidist

Затем добавьте эти скрипты в ваш package.json:

   "scripts": {
+    "styleguide": "styleguidist server",
+    "styleguide:build": "styleguidist build",
     "start": "react-scripts start",

Затем выполните следующую команду внутри директории вашего приложения:

npm run styleguide

После этого следуйте инструкциям на экране.

Узнайте больше о React Styleguidist:

Публикация компонентов в npm

Create React App не предоставляет встроенной функциональности для публикации компонента в npm. Если вы готовы извлечь компонент из вашего проекта, чтобы другие люди могли им воспользоваться, мы рекомендуем переместить его в отдельную директорию вне вашего проекта и затем использовать инструмент, такой как nwb, чтобы подготовить его для публикации.

Создание Progressive Web App

По умолчанию, выпуск для продакшена является полностью функциональным, офлайн-первыми Progressive Web App.

Progressive Web Apps работают быстрее и надежнее, чем традиционные веб-страницы, и предоставляют захватывающий мобильный опыт: * Все статические ресурсы сайта кэшируются, чтобы ваша страница загружалась быстро при последующих посещениях, независимо от состояния сети (например, 2G или 3G). Обновления загружаются в фоновом режиме.

  • Ваше приложение будет работать независимо от состояния сети, даже если оно не подключено к интернету. Это означает, что пользователи смогут использовать ваше приложение на высоте 10 000 футов и в метро.
  • На мобильных устройствах ваше приложение можно добавить напрямую в домашний экран пользователя, вместе с иконкой приложения. Вы также можете воспользоваться веб-推送通知 для привлечения пользователей обратно. Это исключает необходимость использования магазина приложений. sw-precache-webpack-plugin встроен в производственную конфигурацию, и он будет отвечать за генерацию файла служебного работника, который автоматически предварительно кэширует все ваши локальные ресурсы и поддерживает их актуальными при развертывании обновлений. Служебный работник будет использовать стратегию кэширования с приоритетом кэша для обработки всех запросов к локальным ресурсам, включая начальный HTML, обеспечивая то, что ваш веб-приложение будет надежно быстрым, даже на медленной или нестабильной сети.### Отказ от кэшированияЕсли вы предпочитаете не включать сервисные работники до вашего первоначального промышленного развертывания, то удалите вызов registerServiceWorker() из src/index.js.

Если вы ранее включили сервисные работники в вашем промышленном развертывании и считаете, что вам нужно отключить их для всех ваших существующих пользователей, вы можете заменить вызов registerServiceWorker() в src/index.js сначала, модифицируя импорт сервисного работника:

import { unregister } from './registerServiceWorker';

и затем вызвать unregister(). После того, как пользователь посетит страницу, которая имеет unregister(), сервисный работник будет отключен. Обратите внимание, что в зависимости от того, как /service-worker.js подаётся, может потребоваться до 24 часов для сброса кэша.

Рассмотрение вопросов о работе в офлайн-режиме

  1. Сервисные работники требуют HTTPS, хотя для упрощения локального тестирования, эта политика не применима к localhost. Если ваш промышленный веб-сервер не поддерживает HTTPS, то регистрация сервисного работника будет неудачной, но остальная часть вашего веб-приложения останется функциональной.1. Сервисные работники не поддерживаются во всех веб-браузерах. Регистрация сервисного работника не будет пытаться в браузерах, которые не поддерживают его.1. Сервисный работник только включен в промышленной среде, например, выход npm run build. Рекомендуется не включать офлайн-первичный сервисный работник в среде разработки, так как это может привести к разочарованию, когда ранее кэшированные активы используются и не включают последние изменения, которые вы внесли локально.1. Если вам необходимо локально протестировать ваш офлайн-первичный сервисный работник, соберите приложение (используя npm run build) и запустите простой http-сервер из вашей папки сборки. После выполнения скрипта сборки, create-react-app даст инструкции для одного способа тестирования вашего промышленного сбора локально и инструкции по развертыванию имеют инструкции для использования других методов. *Убедитесь, что всегда используете окно в режиме инкогнито, чтобы избежать проблем с кэшем вашего браузера.*1. Если это возможно, настройте вашу среду производства для обслуживания сгенерированного service-worker.js с отключенным кэшированием HTTP. Если это невозможно—GitHub Pages, например, не позволяет изменять стандартный срок хранения кэша HTTP в 10 минут—то имейте в виду, что если вы посетите ваш сайт в производственной среде, а затем снова посетите его до того, как service-worker.js истечет из вашего HTTP кэша, вы продолжите получать ранее закэшированные активы от сервис-воркера. Если у вас есть срочная необходимость просмотреть обновленное производственное развертывание, выполнение сдвига при обновлении (shift-refresh) временно отключит сервис-воркер и загрузит все активы из сети.1. Пользователи не всегда знакомы с веб-приложениями, ориентированными на работу в оффлайн-режиме. Это может быть полезно, чтобы сообщить пользователю когда сервис-воркер завершил заполнение ваших кэшей (показывая сообщение "Это веб-приложение работает в оффлайн-режиме!") и также сообщить им, когда сервис-воркер загрузил последние обновления, которые будут доступны при следующей загрузке страницы (показывая сообщение "Новое содержимое доступно; пожалуйста, обновите."). Показ этих сообщений в настоящее время оставлен как упражнение для разработчика, но как начальная точка, вы можете использовать логику, включённую в src/registerServiceWorker.js, которая показывает, какие события жизненного цикла сервис-воркера следует слушать для обнаружения каждого сценария, и которая по умолчанию просто выводит соответствующие сообщения в консоль JavaScript.1. По умолчанию, сгенерированный файл сервис-воркера не перехватывает или не закэширует никакие активы с других доменов, такие как HTTP запросы API, изображения или встраиваемые элементы, загруженные с другого домена. Если вы хотите использовать стратегию кэширования в режиме выполнения для этих запросов, вы можете eject и затем настроить опцию runtimeCaching в разделе SWPrecacheWebpackPlugin файла webpack.config.prod.js.### Метаданные Progressive Web AppПо умолчанию конфигурация включает в себя манифест веб-приложения, расположенный по адресу public/manifest.json, который можно настроить с учетом специфических для вашего веб-приложения данных.

Когда пользователь добавляет веб-приложение на домашний экран с помощью Chrome или Firefox на Android, метаданные в файле manifest.json определяют, какие иконки, названия и цвета бренда будут использоваться при отображении веб-приложения. Руководство по веб-приложению манифеста предоставляет больше контекста о значении каждого поля и о том, как ваши настройки повлияют на опыт пользователей.

Анализ размера пакета

Source map explorer анализирует JavaScript пакеты с использованием source maps. Это помогает понять, откуда возникает увеличение размера кода.

Чтобы добавить Source map explorer к проекту Create React App, выполните следующие шаги:

npm install --save source-map-explorer

В качестве альтернативы вы можете использовать yarn:

yarn add source-map-explorer

Затем в файле package.json добавьте следующую строку в раздел scripts:

   "scripts": {
+    "analyze": "source-map-explorer build/static/js/main.*",
     "start": "react-scripts start",
     "build": "react-scripts build",
     "test": "react-scripts test --env=jsdom",

Затем для анализа пакета выполните команды сборки в режиме production и запустите скрипт анализа.``` npm run build npm run analyze


## Развертывание

Команда `npm run build` создает директорию `build` с производственной сборкой вашего приложения. Настройте ваш любимый HTTP-сервер так, чтобы посетитель вашего сайта получал `index.html`, а запросы к статическим путям, таким как `/static/js/main.<hash>.js`, обрабатывались с содержимым файла `/static/js/main.<hash>.js`.

### Статический сервер

Для сред, использующих [Node](https://nodejs.org/), самым простым способом обработки этого является установка [serve](https://github.com/zeit/serve) и использование его для дальнейшей работы:

```sh
npm install -g serve
serve -s build

Последняя команда, показанная выше, будет обслуживать ваш статический сайт на порту 5000. Как и многие внутренние настройки serve, порт можно настроить с помощью флагов -p или --port. Запустите следующую команду для получения полного списка доступных опций:

serve -h

Другие решения

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

Вот пример с использованием Node и Express:

const express = require('express');
const path = require('path');
const app = express();

app.use(express.static(path.join(__dirname, 'build')));

app.get('/', function (req, res) {
  res.sendFile(path.join(__dirname, 'build', 'index.html'));
});

app.listen(9000);
```Выбор вашего серверного ПО также не имеет большого значения. Поскольку Create React App полностью агностичен к платформе, нет необходимости явно использовать Node.

Папка `build` с статическими активами является единственным выходом, производимым Create React App.

Однако этого может быть недостаточно, если вы используете клиентскую маршрутизацию. Прочитайте следующий раздел, если вы хотите поддерживать URL-адреса вроде `/todos/42` в вашем одностраничном приложении.

### Поддержка приложений с клиентской маршрутизацией

Если вы используете маршрутизаторы, которые используют HTML5 API `pushState` истории (например, [React Router](https://github.com/ReactTraining/react-router) с `browserHistory`), многие статические серверы будут работать некорректно. Например, если вы используете React Router с маршрутом для `/todos/42`, сервер разработки будет корректно отвечать на `localhost:3000/todos/42`, но Express, обслуживающий производственный сбор, будет некорректно работать.

Это происходит потому, что при свежей загрузке страницы для `/todos/42`, сервер ищет файл `build/todos/42` и не находит его. Серверу необходимо настроить отображение запроса на `/todos/42` как обслуживание `index.html`. Например, мы можем изменить наш пример Express выше, чтобы он обслуживал `index.html` для любых неизвестных путей:

```diff
 app.use(express.static(path.join(__dirname, 'build')));

-app.get('/', function (req, res) {
+app.get('/*', function (req, res) {
   res.sendFile(path.join(__dirname, 'build', 'index.html'));
 });
```Если вы используете [Apache HTTP Server](https://httpd.apache.org/), вам нужно создать файл `.htaccess` в папке `public`, который будет выглядеть следующим образом:

Options -MultiViews RewriteEngine On RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^ index.html [QSA,L]


Эти настройки будут скопированы в папку `build`, когда вы запустите `npm run build`.

Если вы используете [Apache Tomcat](http://tomcat.apache.org/), вам нужно следовать [этому ответу на Stack Overflow](https://stackoverflow.com/a/41249464/4878474).

Теперь запросы к `/todos/42` будут обрабатываться правильно как в режиме разработки, так и в режиме производства.

В режиме производства и в браузере, поддерживающем [service workers](https://developers.google.com/web/fundamentals/getting-started/primers/service-workers), service worker автоматически обрабатывает все запросы навигации, такие как для `/todos/42`, предоставляя закешированную копию вашего `index.html`. Эту маршрутизацию навигации service worker можно настроить или отключить, используя команду `eject` и затем изменяя опции `navigateFallback` и `navigateFallbackWhitelist` плагина `SWPreachePlugin` в конфигурации.

Когда пользователи устанавливают ваше приложение на главный экран их устройства, по умолчанию конфигурация создаст ярлык для `/index.html`. Это может не работать для клиентских маршрутизаторов, которые ожидают, что приложение будет доступно с корневого URL. Редактируйте манифест веб-приложения в файле [`public/manifest.json`](public/manifest.json) и измените `start_url` на соответствующий требуемому URL-шаблону, например:```js
  "start_url": ".",

Настройка для относительных путей

По умолчанию, Create React App создает сборку, предполагая, что ваше приложение размещено в корневом каталоге сервера. Чтобы изменить это, укажите homepage в вашем package.json, например:

  "homepage": "http://mywebsite.com/relativepath",

Это позволит Create React App правильно определить корневой путь для использования в сгенерированном HTML-файле.

Примечание: Если вы используете react-router@^4, вы можете использовать свойство basename для маршрутизации <Link> с корневого URL. Более подробная информация здесь.

Например:

<BrowserRouter basename="/calendar"/>
<Link to="/today"/> // отображается как <a href="/calendar/today">

Предоставление одной и той же сборки с разных путей

Примечание: эта функция доступна с react-scripts@0.9.0 и выше.

Если вы не используете HTML5 pushState API истории или вообще не используете клиентскую маршрутизацию, не обязательно указывать URL, с которого будет подан ваш приложение. Вместо этого вы можете добавить это в ваш package.json:

  "homepage": ".",

Это гарантирует, что все пути к активам будут относительными к index.html. Вы сможете переместить свое приложение с http://mywebsite.com на http://mywebsite.com/relativepath или даже http://mywebsite.com/relative/path без необходимости пересборки.

Azure

Чтобы разместить свое React приложение на Microsoft Azure, прочитайте этот блог.Для использования автоматического развертывания на Azure App Service прочитайте этот блог или этот репозиторий.

Firebase

Установите Firebase CLI, если еще не сделали этого, запустив npm install -g firebase-tools. Зарегистрируйтесь на Firebase и создайте новый проект. Запустите firebase login и войдите в свой ранее созданный Firebase аккаунт.

Затем запустите команду firebase init из корневой директории вашего проекта. Вам нужно выбрать Hosting: Настройка и развертывание сайтов Firebase Hosting и выбрать проект Firebase, созданный в предыдущем шаге. Вам потребуется согласиться с созданием database.rules.json, выбрать build как публичную директорию и также согласиться с Настройкой как одностраничного приложения ответив y.

    === Проектная настройка

    Сначала ассоциируем эту проектную директорию с проектом Firebase.
    Вы можете создать несколько псевдонимов проекта, запустив firebase use --add,
    но для начала мы просто настроим стандартный проект.

    ? Какой проект Firebase вы хотите ассоциировать как стандартный? Example app (example-app-fd690)

    === Настройка базы данных
```    Правила Firebase Realtime Database позволяют вам определить, как должна быть структурирована ваша база данных, и когда ваша база данных может быть прочитана и записана.
? Какой файл следует использовать для правил базы данных? database.rules.json
✔  Правила базы данных для example-app-fd690 были загружены в database.rules.json.
Будущие изменения в файле database.rules.json обновят правила базы данных при выполнении
команды firebase deploy.    === Настройка Hosting

Ваш публичный каталог — это папка (относительно каталога проекта), содержащая ресурсы для размещения, которые будут загружены с помощью `firebase deploy`. Если у вас есть процесс сборки для ваших ресурсов, используйте каталог выходных данных сборки.

? Какой каталог вы хотите использовать в качестве публичного? build
? Настроить как одностраничное приложение (перезаписать все URL на /index.html)? Да
✔  Записан build/index.html

i  Запись информации о конфигурации в firebase.json...
i  Запись информации о проекте в .firebaserc...

✔  Полная инициализация Firebase завершена!

ВАЖНО: вам нужно правильно настроить HTTP-заголовки кэширования для файла service-worker.js в файле firebase.json, иначе вы не сможете увидеть изменения после первого развертывания (проблема #2440). Он должен быть добавлен внутри ключа "hosting" следующим образом:

{
  "hosting": {
    ...
    "headers": [
      {"source": "/service-worker.js", "headers": [{"key": "Cache-Control", "value": "no-cache"}]}
    ]
    ...

Теперь, после создания производственного сборочного файла с помощью npm run build, вы можете развернуть его, выполнив firebase deploy.

    === Развертывание в 'example-app-fd690'...    i  развертывание базы данных, хостинг
    ✔  база данных: правила готовы для развертывания.
    i  хостинг: подготовка каталога сборки для загрузки...
    Загрузка: [==============================          ] 75%✔  хостинг: каталог сборки загружен успешно
    ✔  хостинг: 8 файлов загружены успешно
    i  начало процесса развертывания (может занять несколько минут)...    ✔ Развертывание завершено!

    Консоль проекта: https://console.firebase.google.com/project/example-app-fd690/overview
    URL Hosting: https://example-app-fd690.firebaseapp.com

Для получения дополнительной информации см. [Добавление Firebase в ваш проект на языке JavaScript](https://firebase.google.com/docs/web/setup).

### [GitHub Pages](https://pages.github.com/)

> Примечание: эта функция доступна с `react-scripts@0.2.0` и выше.

#### Шаг 1: Добавьте `homepage` в `package.json`

**Этот шаг очень важен!**<br>
**Если вы пропустите его, ваше приложение не будет развернуто правильно.**

Откройте ваш `package.json` и добавьте поле `homepage` для вашего проекта:

```json
  "homepage": "https://myusername.github.io/my-app",

или для GitHub пользовательской страницы:

  "homepage": "https://myusername.github.io",

Create React App использует поле homepage для определения корневого URL в построенном HTML файле.

Шаг 2: Установите gh-pages и добавьте deploy в scripts в package.json

Теперь, каждый раз, когда вы запускаете npm run build, вы увидите шпаргалку с инструкциями по развертыванию на GitHub Pages.

Чтобы опубликовать его по адресу https://myusername.github.io/my-app, выполните:

npm install --save gh-pages

Альтернативно вы можете использовать yarn:

yarn add gh-pages

Добавьте следующие скрипты в ваш package.json:

  "scripts": {
+   "predeploy": "npm run build",
+   "deploy": "gh-pages -d build",
    "start": "react-scripts start",
    "build": "react-scripts build",

Скрипт predeploy будет запущен автоматически перед выполнением deploy.Если вы развертываете на GitHub пользовательской странице вместо страницы проекта, вам потребуется сделать два дополнительных изменения:

  1. Сначала измените ветку исходного репозитория на любую ветку, кроме main.
  2. Дополнительно отредактируйте скрипты в package.json, чтобы размещение деплоя осуществлялось на main:
  "scripts": {
    "predeploy": "npm run build",
-   "deploy": "gh-pages -d build",
+   "deploy": "gh-pages -b main -d build",

Шаг 3: Разверните сайт, выполнив npm run deploy

Затем выполните:

npm run deploy

Шаг 4: Убедитесь, что настройки вашего проекта используют gh-pages

Наконец, убедитесь, что опция GitHub Pages в настройках вашего проекта на GitHub установлена на использование ветки gh-pages:

gh-pages branch setting

Шаг 5: Опционально, настройте домен

Вы можете настроить пользовательский домен с помощью GitHub Pages, добавив файл CNAME в папку public/.#### Примечания по клиентскому маршрутизации

GitHub Pages не поддерживает маршрутизаторы, которые используют HTML5 pushState history API (например, React Router с использованием browserHistory). Это связано с тем, что при свежей загрузке страницы для URL вида http://user.github.io/todomvc/todos/42, где /todos/42 является маршрутом фронтенда, сервер GitHub Pages возвращает ошибку 404, так как он ничего не знает о /todos/42. Если вы хотите добавить маршрутизатор в проект, хостируемый на GitHub Pages, вот несколько решений:

  • Вы можете переключиться с использования HTML5 history API на маршрутизацию с хэшами. Если вы используете React Router, вы можете переключиться на hashHistory для этого эффекта, но URL будет длиннее и более подробным (например, http://user.github.io/todomvc/#/todos/42?_k=yknaj). Подробнее о различных реализациях истории в React Router.
  • В качестве альтернативы, вы можете использовать хитрость, чтобы научить GitHub Pages обрабатывать 404, перенаправляя на вашу страницу index.html с специальным параметром перенаправления. Вам потребуется добавить файл 404.html с кодом перенаправления в папку build перед развертыванием проекта, и вам потребуется добавить код обработки параметра перенаправления в index.html. Вы можете найти подробное объяснение этой техники в этом руководстве.#### Устранение неполадок
"/dev/tty: Устройство или адрес не найдены"

Если при развертывании вы получаете ошибку /dev/tty: Устройство или адрес не найдены или что-то подобное, попробуйте следующее:

  1. Создайте новый личный токен доступа
  2. git remote set-url origin https://<user>:<token>@github.com/<user>/<repo> .
  3. Попробуйте npm run deploy снова

Heroku

Используйте Heroku Buildpack для Create React App.
Вы можете найти инструкции в Развертывании React с нулевым конфигурированием.

Устранение ошибок развертывания на Heroku

Иногда npm run build работает локально, но завершается ошибкой во время развертывания через Heroku. Ниже приведены наиболее распространённые случаи.

"Модуль не найден: Ошибка: Не удалось разрешить 'файл' или 'директорию'"

Если вы получаете что-то вроде этого:

remote: Failed to create a production build. Reason:
remote: Module not found: Error: Cannot resolve 'file' or 'directory'
MyDirectory in /tmp/build_1234/src

Это означает, что вам нужно убедиться, что регистр букв в файле или директории, который вы import-ите, соответствует регистру на вашей файловой системе или на GitHub.Это важно, потому что Linux (операционная система, используемая Heroku) чувствителен к регистру. Так что MyDirectory и mydirectory — это две разные директории, и хотя проект успешно собирается локально, различие в регистре приводит к ошибке import-ов на удалённых серверах Heroku.

"Не удалось найти необходимый файл."Если вы исключите или проигнорируете необходимые файлы из пакета, вы увидите ошибку, похожую на эту:
remote: Не удалось найти необходимый файл.
remote:   Имя: `index.html`
remote:   Поиск в: /tmp/build_a2875fc163b209225122d68916f1d4df/public
remote:
remote: npm ERR! Linux 3.13.0-105-generic
remote: npm ERR! argv "/tmp/build_a2875fc163b209225122d68916f1d4df/.heroku/node/bin/node" "/tmp/build_a2875fc163b209225122d68916f1d4df/.heroku/node/bin/npm" "run" "build"

В этом случае убедитесь, что файл присутствует с правильным регистром букв и что он не игнорируется в вашем локальном .gitignore или ~/.gitignore_global.

Netlify

Для ручного развертывания на CDN Netlify:

npm install netlify-cli -g
netlify deploy

Выберите build как путь для развертывания.

Для настройки непрерывной доставки:

С этой настройкой Netlify будет автоматически собирать и развертывать при каждом вашем коммите в git или при открытии pull request:

  1. Начните новый проект Netlify
  2. Выберите вашу службу хостинга Git и выберите репозиторий
  3. Установите yarn build как команду сборки и build как папку публикации
  4. Нажмите Deploy site

Поддержка клиентской маршрутизации:

Чтобы поддержать pushState, убедитесь, что вы создали файл public/_redirects с следующими правилами перенаправления:

/*  /index.html  200

При сборке проекта, Create React App поместит содержимое папки public в выходные данные сборки.

Now

Now предлагает нулевое конфигурирование и однокомандное развертывание. Вы можете использовать now для бесплатного развертывания вашего приложения.1. Установите командную строку now либо через рекомендованное установочное приложение, либо через Node.js с помощью npm install -g now.

  1. Соберите ваше приложение, запустив npm run build.

  2. Перейдите в папку сборки, запустив cd build.

  3. Запустите now --name your-project-name из папки сборки. Вы увидите URL-адрес now.sh в вашем выводе, например:

    > Готово! https://your-project-name-tpspyhtdtk.now.sh (скопировано в буфер обмена)

    Вставьте этот URL-адрес в ваш браузер после завершения сборки, и вы увидите ваше развернутое приложение.

Дополнительные сведения доступны в этой статье.### S3 и CloudFront

Чтобы развернуть ваше приложение React на Amazon Web Services S3 и CloudFront, ознакомьтесь с этой статьей.

Surge

Установите Surge CLI, если еще не сделали этого, запустив npm install -g surge. Запустите команду surge и войдите в свой аккаунт или создайте новый.

Когда вас спросят о пути к проекту, убедитесь, что вы укажете папку build, например:

       путь к проекту: /путь/к/проекту/build
Обратите внимание, что для поддержки маршрутизации с использованием API pushState HTML5, вы можете переименовать файл index.html в папке build на 200.html перед развертыванием на Surge. Это гарантирует, что каждый URL будет переходить к этому файлу.## Расширенная конфигурацияВы можете настроить различные параметры разработки и производства, установив переменные окружения в вашей оболочке или с помощью .env. Переменная Развитие Производство Использование
BROWSER :white_check_mark: :x: По умолчанию Create React App откроет системный браузер, предпочтительно Chrome на macOS. Укажите браузер, чтобы переопределить это поведение, или установите его на none, чтобы полностью отключить его. Если вам нужно настроить способ запуска браузера, вы можете указать скрипт node.js. Все аргументы, переданные npm start, также будут переданы этому скрипту, и URL, где ваше приложение будет размещено, будет последним аргументом. Имя файла вашего скрипта должно иметь расширение .js.
HOST :white_check_mark: :x: По умолчанию веб-сервер разработки привязывается к localhost. Вы можете использовать эту переменную, чтобы указать другой хост.
PORT :white_check_mark: :x: По умолчанию веб-сервер разработки попытается прослушивать порт OnClickListener 3000 или предложит попробовать следующий доступный порт. Вы можете использовать эту переменную, чтобы указать другой порт.
HTTPS :white_check_mark: :x: При установке значения true Create React App запустит веб-сервер разработки в режиме https.
PUBLIC_URL :x: :white_check_mark: Create React App предполагает, что ваше приложение размещено на корневом уровне или в подпуть, указанном в [package.json].json (homepage`)](#building-for-relative-paths). Обычно Create React App игнорирует хост-имя. Вы можете использовать эту переменную, чтобы заставить ресурсы ссылаться на URL, который вы предоставили (включая хост-имя). Это может быть полезно при использовании CDN для размещения вашего приложения.
CI :large_orange_diamond: :white_check_mark: При установке значения true Create React App будет считать предупреждения как ошибки сборки. Также это делает тестовый запуск непостоянным. Большинство CI-систем по умолчанию устанавливают этот флаг.
REACT_EDITOR :white_check_mark: :x: При сбое приложения в режиме разработки вы увидите оверлей с ошибкой и кликабельным трассированием стека. При нажатии на него Create React App попытается определить редактор, который вы используете, на основе запущенных процессов, и откроет соответствующий файл исходного кода. Вы можете отправить pull request для обнаружения вашего редактора. Установка этой переменной окружения переопределяет автоматическое обнаружение. Если вы это делаете, убедитесь, что переменная окружения PATH вашего системы указывает на папку bin вашего редактора. Вы также можете установить её на none, чтобы полностью отключить её.
CHOKIDAR_USEPOLLING :white_check_mark: :x: При значении true watcher работает в режиме опроса, что необходимо внутри виртуальной машины. Используйте эту опцию, если npm start не обнаруживает изменения.GENERATE_SOURCEMAP
NODE_PATH :white_check_mark: :white_check_mark: То же самое, что и NODE_PATH в Node.js, но разрешены только относительные пути. Может быть полезно для эмуляции монорепозитория, устанавливая NODE_PATH=src. ## Устранение неполадок### npm start не обнаруживает изменения

Когда вы сохраняете файл, запущенный npm start, браузер должен обновиться с новым кодом.
Если этого не происходит, попробуйте один из следующих методов устранения неполадок:

  • Если ваш проект находится в папке Dropbox, попробуйте переместить его.
  • Если watcher не видит файл index.js и вы ссылаетесь на него по имени папки, вам нужно перезапустить watcher из-за бага Webpack.
  • Некоторые редакторы, такие как Vim и IntelliJ, имеют функцию "безопасного сохранения", которая в настоящее время ломает watcher. Вам нужно отключить её. Следуйте инструкциям в настройке вашего текстового редактора.
  • Если путь к вашему проекту содержит скобки, попробуйте переместить проект в путь без них. Это вызвано багом watcher Webpack.
  • На Linux и macOS вам может потребоваться настроить системные параметры, чтобы разрешить больше watcher.
  • Если проект запущен внутри виртуальной машины, такой как (Vagrant-настроенная) VirtualBox, создайте файл .env в директории проекта, если он ещё не существует, и добавьте CHOKIDAR_USEPOLLING=true в него. Это гарантирует, что следующий раз, когда вы запустите npm start, watcher будет использовать режим опроса, как это необходимо внутри виртуальной машины.Если ни один из этих решений не помогает, пожалуйста, оставьте комментарий в этом треде.

npm test зависает на macOS Sierra

Если вы запускаете npm test и консоль зависает после вывода react-scripts test --env=jsdom, возможно, у вас есть проблема с вашей Watchman установкой, как описано в facebookincubator/create-react-app#713.

Мы рекомендуем удалить node_modules в вашем проекте и запустить npm install (или yarn, если вы используете его) сначала. Если это не помогает, вы можете попробовать один из множества упомянутых в этих тредах методов устранения неполадок:

Отчеты указывают, что установка Watchman 4.7.0 или более поздней версии устраняет проблему. Если вы используете Homebrew, вы можете выполнить следующие команды для обновления:

watchman shutdown-server
brew update
brew reinstall watchman

Вы можете найти другие методы установки на странице документации Watchman.

Если это все еще не помогает, попробуйте выполнить команду launchctl unload -F ~/Library/LaunchAgents/com.github.facebook.watchman.plist.

Также есть отчеты, что удаление Watchman устраняет проблему. Поэтому, если ничего другого не помогает, удалите его из вашей системы и попробуйте снова.### Команда npm run build завершается слишком рано

Отчеты указывают, что npm run build может завершиться ошибкой на машинах с ограниченной памятью и отсутствием swap-пространства, что часто встречается в облачных средах. Даже с небольшими проектами эта команда может увеличить использование RAM в вашей системе на сотни мегабайт, поэтому если у вас менее 1 ГБ доступной памяти, ваша сборка вероятно завершится с сообщением:

Сборка завершилась ошибкой, так как процесс завершился слишком рано. Это, вероятно, означает, что система исчерпала память или кто-то вызвал kill -9 на процессе.

Если вы уверены, что не завершали процесс, рассмотрите возможность добавления swap-пространства к машине, на которой вы выполняете сборку, или выполните сборку проекта локально.

Команда npm run build завершается ошибкой на Heroku

Это может быть проблемой с чувствительностью к регистру имен файлов. Пожалуйста, обратитесь к этому разделу.

Локали Moment.js отсутствуют

Если вы используете Moment.js, вы можете заметить, что по умолчанию доступна только английская локаль. Это потому, что файлы локали очень большие, и вам, вероятно, требуется только подмножество всех локалей, предоставляемых Moment.js.Чтобы добавить конкретную локаль Moment.js в ваш пакет, вам нужно явно импортировать её. Например:

import moment from 'moment';
import 'moment/locale/fr';

Если вы импортируете несколько локалей таким образом, вы можете позже переключаться между ними, вызывая moment.locale() с именем локали:

import moment from 'moment';
import 'moment/locale/fr';
import 'moment/locale/es';
moment.locale('ru');

Это будет работать только для локалей, которые были явно импортированы до этого.

npm run build не может минифицировать

Некоторые сторонние пакеты не компилируют свой код в ES5 перед публикацией на npm. Это часто вызывает проблемы в экосистеме, так как ни браузеры (кроме большинства современных версий), ни некоторые инструменты в настоящее время не поддерживают все возможности ES6. Мы рекомендуем публиковать код на npm как ES5 по крайней мере на несколько лет.

Чтобы разрешить эту проблему:1. Откройте issue в трекере проблем стороннего пакета и попросите, чтобы пакет был опубликован предварительно скомпилированным.

  • Примечание: Create React App может использовать как CommonJS, так и ES модули. Для совместимости с Node.js рекомендуется, чтобы основной входной пункт был CommonJS. Однако они могут дополнительно предоставлять входной пункт ES модуля с помощью поля module в package.json. Обратите внимание, что даже если библиотека предоставляет версию ES Modules, она всё ещё должна предварительно скомпилировать другие возможности ES6 в ES5, если она намерена поддерживать более старые браузеры.2. Создайте форк пакета и опубликуйте исправленную версию самостоятельно.
  1. Если зависимость достаточно мала, скопируйте её в папку src/ и обрабатывайте как приложение.

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

Альтернативы Ejecting

Ejecting позволяет настроить всё, но после этого вам придётся самостоятельно поддерживать конфигурацию и скрипты. Это может быть устрашающим, если у вас много похожих проектов. В таких случаях вместо ejecting мы рекомендуем создать форк react-scripts и любых других пакетов, которые вам нужны. Эта статья подробно описывает, как это сделать. Вы можете найти больше обсуждений в этом issue.

Что-то пропущено?

Если у вас есть идеи для дополнительных рецептов "Как это сделать", которые должны быть на этой странице, скажите нам или внесите свой вклад!

Комментарии ( 0 )

Вы можете оставить комментарий после Вход в систему

Введение

Использование React Full Stack + AntD для разработки системы управления бэкендом сервиса по прокату велосипедов. Развернуть Свернуть
Отмена

Обновления

Пока нет обновлений

Участники

все

Недавние действия

Загрузить больше
Больше нет результатов для загрузки
1
https://api.gitlife.ru/oschina-mirror/tiansongbo-react-antd-manager.git
git@api.gitlife.ru:oschina-mirror/tiansongbo-react-antd-manager.git
oschina-mirror
tiansongbo-react-antd-manager
tiansongbo-react-antd-manager
master