语境
我正在将基于 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"
},
问题
如果我们有类似/abcReact 的路由。这需要在客户端渲染。问题是,如果有人为路线添加书签,或分享路线,或将路线发布到搜索引擎等......然后如果浏览器/abc在 NGINX 中请求,那么它找不到/abc位置块或文件,因此会导致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 或 react JS/reach 脚本的某些功能以比使用我上面建议的脚本更简单的方式导出路由的更好方法。