Добавить приложение React в фреймворк Elixir Phoenix может быть очень просто, если вы понимаете, как они взаимодействуют.

Перед началом убедитесь, что у вас есть все зависимости:

Для начала используем генератор феникса по умолчанию. Вы можете называть его как хотите, вместо response_phoenix.

mix phx.new react_phoenix

После установки зависимостей мы просто следуем инструкциям на экране, поэтому добавляем конфигурацию нашей базы данных Postgres в config/dev.exs. Затем выполните перечисленные команды:

cd react_phoenix
mix ecto.create
mix phx.server

И теперь вы должны увидеть красивый шаблон Phoenix по адресу localhost:4000:

Чтобы добавить React, мы должны понимать, как Phoenix отображает эту страницу.

Итак, клиентские файлы существуют в двух местах. Отрисованный HTML находится в каталоге шаблонов. А статические файлы (css, js, robots.txt), которые вы редактируете, находятся в папке с ресурсами. Но когда вы действительно запускаете сервер, webpack соберет ресурсы и поместит их в папку priv/static.

Итак, один из подходов к добавлению React - создать отдельную папку с приложением create-response-app или что-то в этом роде и заменить папку /priv/static на результат процесса сборки. Я буду использовать более простой подход - отредактировать данную папку с активами.

React - это просто библиотека npm, которую мы можем установить и добавить, как любой другой пакет. Нам просто понадобится элемент в DOM (index.html), который будет корнем нашего дерева React и некоторой конфигурации веб-пакета. Итак, у нас есть три основных шага: 1) Настройка React в статическом файле javascript 2) Добавление корневого элемента в шаблон. 3) Настройте Webpack / Babel для обработки React и JSX

  1. Настройте React в статическом файле javascript
cd assets
npm install react react-dom

Давайте определим простой компонент React в новом файле assets/js/Main.js:

import React, { useEffect, useState } from "react";
export default function Main(props) {
  return <div>MAIN</div>;
}

А затем отрендерить его в assets/js/app.js:

// ... leave boilerplate ... and add this to the bottom
import React from "react";
import ReactDOM from "react-dom";
import Main from "./Main.js";
ReactDOM.render(<Router />, document.getElementById("root"));

2. Добавьте корневой элемент в шаблон.

Давайте удалим этот заголовок Phoenix из базового макета. Удаление заголовка должно оставить в templates/layout/app.html.ex следующее:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8"/>
  <meta http-equiv="X-UA-Compatible" content="IE=edge"/>
  <meta name="viewport" content="width=device-width, initial-scale=1.0"/
  <title><%= assigns[:page_title] || "ReactPhoenix · Phoenix Framework" %></title>
  <link rel="stylesheet" href="<%= Routes.static_path(@conn, "/css/app.css") %>"/>
  <%= csrf_meta_tag() %>
</head>
<body>
  <main role="main" class="container">
    <p class="alert alert-info" role="alert"><%= get_flash(@conn, :info) %></p>
    <p class="alert alert-danger" role="alert"><%= get_flash(@conn, :error) %></p>
    <%= render @view_module, @view_template, assigns %>
  </main>
  <script type="text/javascript" src="<%= Routes.static_path(@conn, "/js/app.js") %>"></script>
</body>
</html>

Все шаблоны страниц будут отображаться вместо этой <%= render строки. Теперь измените templates/page/index.html.eex на однострочное корневое div:

<div id="root"></div>

3. Настройте Webpack / Babel для работы с React и JSX.

Добавить транспиляцию React так же просто, как добавить предустановленный плагин babel. Сначала установите его как зависимость разработчика:

npm i --save-dev @babel/preset-react

Затем добавьте его в .babelrc:

{
  "presets": ["@babel/preset-env", "@babel/preset-react"]
}

И вот это

Вероятно, есть две последние проблемы, которые вы захотите исправить. В настоящее время вы не сможете импортировать изображения, как в приложении create-react-app. И контроллер будет отображать index.html только для маршрута /. Это создаст проблемы, если вы позже будете использовать response-router для нескольких страниц.

Чтобы импортировать изображения в React, я в основном изменил это из приложения create-react-app. Нам понадобятся эти два пакета:

npm i --save-dev url-loader file-loader

Затем отредактируйте assets/webpack.config.js на:

Теперь assets/static автоматически включается в финальную сборку в priv. Чтобы вместо этого разрешить импорт изображений через веб-пакет, переместите папку изображений с assets/static/images на assets/images. Затем вы можете импортировать изображения в React, как обычно (import px from “../images/phoenix.png”;).

Что касается исправления маршрута контроллера, это однострочное изменение в router.ex с:

get "/", PageController, :index

to

get "/*path", PageController, :index

Когда вы позже добавите область /api в router.ex, убедитесь, что она находится выше этой / области. Если вы этого не сделаете, Phoenix отправит ВСЕ запросы на index.html, включая ваши /api запросы.

И все, удачи в путешествии!