Symfony 4, как настроить SPA (одностраничное приложение) с React?

Я не смог заставить Symfony 4 работать должным образом в настройке SPA.

В частности, при навигации по ссылкам на React-роутер все работает как надо.

Но если я пытаюсь получить доступ к любому из маршрутов (кроме домашнего) напрямую, Symfony перехватывает его и, конечно, выдает ошибку для маршрута, который не найден.

Альтернатива размещения Symfony в поддомене и использования его только в качестве API нежизнеспособна, поскольку мне нужны все инструменты управления пользователями и сеансами, предоставляемые платформой.

Конечно, мне понадобится маршрутизация Symfony для всех вызовов API на сервере.

Я использую стандартную структуру каталогов Symfony 4, добавляя только каталог / клиент на верхнем уровне для всего кода реагирования / избыточности.

Код сборки находится в / public / build.

Я также попытался поместить файл .htaccess в / public с приведенным ниже кодом, но это не помогло.

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

Спасибо

2

Решение

Решение может быть следующим.

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

namespace App\Controller;

use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\Routing\Annotation\Route;

class DefaultController extends Controller
{
/**
* @Template("default/index.html.twig")
* @Route("/{reactRouting}", name="index", requirements={"reactRouting"=".+"}, defaults={"reactRouting": null})
*/
public function index()
{
return [];
}
}

Если у вас есть маршруты, которые не должны обрабатываться по реакции, ваша аннотация может исключить их следующим образом — все маршруты, начинающиеся с api, не будут обрабатываться по реакции:

@Route("/{reactRouting}", name="index", requirements={"reactRouting"="^(?!api).+"}, defaults={"reactRouting": null})

Шаблон Twig, с корневым элементом:

{% extends 'base.html.twig' %}

{% block stylesheets %}
<link rel="stylesheet" href="{{ asset('build/js/app.css') }}">
{% endblock %}

{% block body %}
<div id="root"><div>
{% endblock %}

{% block javascripts %}
<script type="text/javascript" src="{{ asset('build/js/app.js') }}"></script>
{% endblock %}

Реагировать на индексный файл:

import React from 'react';
import ReactDOM from 'react-dom';
import {BrowserRouter, Route, Switch} from 'react-router-dom';

import Home from "./containers/Home";
import AboutUs from "./containers/AboutUs";


ReactDOM.render(
<BrowserRouter>
<Switch>
<Route path="/" component={Home}/>
<Route path="/about-us" component={AboutUs}/>
</Switch>
</BrowserRouter>,
document.getElementById('root'));

И мой конфигурационный вызов на бис:

var Encore = require('@symfony/webpack-encore');

Encore
// the project directory where compiled assets will be stored
.setOutputPath('public/build/')
// the public path used by the web server to access the previous directory
.setPublicPath('/build')
.cleanupOutputBeforeBuild()
.enableSourceMaps(!Encore.isProduction())
// uncomment to create hashed filenames (e.g. app.abc123.css)
// .enableVersioning(Encore.isProduction())

// uncomment to define the assets of the project
// .addEntry('js/app', './assets/js/app.js')
// .addStyleEntry('css/app', './assets/css/app.scss')

// uncomment if you use Sass/SCSS files
// .enableSassLoader()

// uncomment for legacy applications that require $/jQuery as a global variable
// .autoProvidejQuery()

.enableReactPreset()
.addEntry('js/app', './react/index.js')
.configureBabel((config) => {
config.presets.push('stage-1');
})
;

module.exports = Encore.getWebpackConfig();
2

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

Я считаю, что нашел возможную настройку.

Включите маршруты реакции-маршрутизатора в файле Symfony rout.yaml, все они указывают на тот же контроллер, который генерирует корневой компонент React.

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

//config/routes.yaml
//all routes handled by PWA(react-router) pointing to same controller
home:
path: /
controller: App\Controller\IndexController::index

account:
path: /account
controller: App\Controller\IndexController::index

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

0

По вопросам рекламы [email protected]