Добавить приложение React в фреймворк Elixir Phoenix может быть очень просто, если вы понимаете, как они взаимодействуют.
Перед началом убедитесь, что у вас есть все зависимости:
- Эликсир и микс
- Феникс и Хекс (пакетный менеджер)
- Узел и npm
- Postgres или размещенная версия, например AWS RDS
Для начала используем генератор феникса по умолчанию. Вы можете называть его как хотите, вместо 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
- Настройте 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
запросы.
И все, удачи в путешествии!