Контекст
Я развертываю приложение на основе 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 для экспорта маршрутов более простым способом, чем использование предложенного выше сценария.