Как воссоздать try_files nginx в Play Framework для размещения сайта React

Я пытаюсь разместить сайт React с сервера Play Framework. Внешний интерфейс React разработан в отдельном проекте, а его артефакты сборки (статические файлы html/js/css/и т. д.) копируются в папку public моего проекта Play.

Теперь я попытался перейти, например. /page1 (где это маршрут React), но я получаю 404, потому что, конечно, у сервера нет такого маршрута.

Я хочу воспроизвести функциональность типа try_files $uri /index.html nginx - если запрошенный путь может быть обслужен (т.е. он соответствует активу, о котором знает сервер), он будет обслужен. В противном случае обслуживайте содержимое index.html без перезаписи URL-адреса, чтобы маршрутизация React могла работать.

Я пытался заставить это работать только с файлом routes, а также в качестве контроллера (с if/else). Мне не удалось точно воспроизвести то, что в nginx является однострочным. Как я мог это сделать?


person iraxef    schedule 02.11.2017    source источник


Ответы (2)


Как говорит @vdebergue, вы можете получить упрощенную версию того, что хотите, добавив в нижнюю часть conf/routes файла всеобъемлющее.

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

Я писал об этом в моем блог в июле, но, согласно соглашению Stack Overflow, я также расширю его здесь. По сути, вы можете скопировать это Gist, который объявляет файл FrontEndServingController.

Ключевая функциональность, которую этот контроллер предоставляет по сравнению со встроенным контроллером Assets, заключается в том, что при первом использовании он рекурсивно сканирует ваш каталог public, чтобы найти настоящие файлы, поэтому он знает, когда их обслуживать, а когда подайте index.html (ваше приложение React).

Затем вы используете его в своем файле routes следующим образом:

GET /       controllers.FrontEndServingController.index
GET /*file  controllers.FrontEndServingController.frontEndPath(file)
person millhouse    schedule 03.11.2017
comment
Это отлично работало в режиме разработки, но не работало в режиме производства. В частности, кажется, что вы не можете использовать f.listFiles в строке 25 вашего Gist, он взрывается с NullPointerException. Мне пришлось изменить Gist следующим образом, чтобы заставить его работать как в режиме разработки, так и в режиме производства: github.com/mrubin/211f007508cd90f471d697132727808c - person iraxef; 04.11.2017
comment
Обратите внимание, что вы можете избавиться от явного маршрута index, если захотите, если перепишете маршрут следующим образом: GET /$path<.*> controllers.FrontEndServingController.frontEndPath(path) - person iraxef; 04.11.2017
comment
Спасибо за вклад и предложения @iraxef! - person millhouse; 04.11.2017

Вы можете сделать это просто в файле маршрута. Внизу файла добавьте это правило захвата всех:

# your other routes above
# ...
GET     /$any<.*>                controllers.Assets.at(path="/public", file="index.html")
person vdebergue    schedule 02.11.2017
comment
Это не работает: Compilation error[Missing parameter in call definition: any] [error] GET /$any<.*> controllers.Assets.at(path="/public", file="index.html") - person iraxef; 04.11.2017