Возможно ли для приложения-сценария экспортировать маршруты для удобного использования NGINX? - PullRequest
0 голосов
/ 12 мая 2018

Контекст

Я развертываю приложение на основе ReactJS в NGINX для визуализации на стороне клиента. NGINX обслуживает статические файлы следующим образом:

  location / {
    try_files $uri $uri/ =404;
  }

Это прекрасно работает на основном маршруте /, который обслуживает index.html, а затем клиентский маршрутизатор запускает и отображает страницу.

Версия

"dependencies": {
    "react": "^16.3.2",
    "react-dom": "^16.3.2",
    "react-helmet": "^5.2.0",
    "react-router-dom": "^4.2.2",
    "react-scripts": "1.1.4",
    "styled-components": "^3.2.6"
  },

Проблемы

Если у нас есть маршрут, такой как /abc в React. Это должно быть сделано на стороне клиента. Проблема в том, что если кто-то добавит в закладки маршрут, или поделится им, или опубликует его в поисковой системе и т.д. в 404.

Мое текущее предлагаемое решение

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

location /abc {
        try_files $uri $uri/ index.html;
      }

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

location / {
    try_files $uri $uri/ index.html;
  }

Первый подход кажется более приятным, потому что я явно определяю приемлемый маршрут. Таким образом, запрос на /xyz - который не является допустимым маршрутом, приведет к 404 - что я и хочу. Однако требуется, чтобы я определил каждый маршрут, который может стать проблемой обслуживания, если я не смогу эффективно его автоматизировать.

Я предлагаю, чтобы часть сборки CI выполняла что-то вроде:

cat src/components/Routes/Routes.js \
| grep -i route | grep "path" \
| tr '"' "'" \
| grep  -o -E "path=['\"]{1}(.*)['\"]{1}" \
| cut -d "=" -f 2 \
| tr -d "'"

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

while read -r route; do
    echo "    try_files \$uri /index.html;" >> ${ROUTES}
    echo "}" >> ${ROUTES}
done <<< "${ROUTES}"

например. вход как:

class Routes extends Component {
  render() {
    return [
      <Header {...this.props} key='header' />,
      <Switch key='content'>
        <Route exact path="/" component={HomeMVP} />
        <Route exact path='/about' component={About} />
        <Route exact path='/privacy' component={Privacy} />
        <Route component={NotFound} />
      </Switch>
    ];
  }
}

становится:

/
/about
/privacy

Затем я мог бы сгенерировать маршруты NGINX, которые возвращают index.html, чтобы позволить клиентскому маршрутизатору затем включить и отобразить правильную страницу.

Вопрос

Кто-нибудь знает о лучшем подходе: использование NGINX или какой-либо функции сценариев реагирования JS / reach для экспорта маршрутов более простым способом, чем использование предложенного выше сценария.

1 Ответ

0 голосов
/ 12 мая 2018

Я закончил тем, что запустил следующий скрипт в dockerfile во время сборки (nginx:1.14-alpine):

#!/bin/sh
set -euo pipefail
IFS=$'\n\t'

ROUTES_FILE=/etc/nginx/dynamic-routes.conf

# Extract all of the routes (except "/")
ROUTES=$(grep -i route /etc/nginx/routes.js \
| grep "path" \
| tr '"' "'" \
| grep  -o -E "path='(.*)'" \
| grep  -v "'/'" \
| cut -d "=" -f 2 \
| tr -d "'")

# Now the routes contain the URI's, e.g. "/about" and "/privacy" loop through and generate NGINX routes.
echo "Routes are: ${ROUTES}"

for route in ${ROUTES}
do
    echo "Generating location for route: ${route}"
    echo "location ~ ${route}[/]?$ {" >> ${ROUTES_FILE}
    echo "    try_files \$uri /index.html;" >> ${ROUTES_FILE}
    echo "}" >> ${ROUTES_FILE}
done

echo "Dynamic routes are: "
cat ${ROUTES_FILE}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...