运维记录1——解决在Nginx下部署CRA项目,二级目录不能访问的问题

19次阅读

共计 1734 个字符,预计需要花费 5 分钟才能阅读完成。

如果从头开始搭建 React 项目,create-react-app 通常是开发者的首选。毕竟不是谁都有精力去了解 WebPack 的复杂配置,而 CRA 将配置隐藏开箱即用的特性必然会受到普遍欢迎。
根目录访问
到了部署阶段,我通常使用 nginx 作为 web 容器,将项目部署到一个根目录下访问。如
# nginx 配置
server {
listen 80;
server_name my.website.com;

location / {
alias /data/www/react-project/dist;
index index.html
}
}
那么只要我们将项目文件放到对应的目录下,重启 nginx 即可开始访问 web 页面。
二级目录访问
有时我们有多个 web 项目,多个项目不可能同时挂在根目录下,所以我们会划分二级目录来分别访问各个 web 项目。如

http://my.website.com/project1 => 访问 react-project1 项目

http://my.website.com/project2 => 访问 react-project2 项目

问题 1:CSS 等资源加载失败
此时,如果简单将 nginx 配置的 location 改为 /project1,则会出现网页无法访问的错误。
# nginx 配置
server {
listen 80;
server_name my.website.com;

# location / {
location /project1 {
alias /data/www/react-project/dist;
index index.html
}
}
现象
从 dev 工具可以看出,html 文件有取得,但 css、js 等资源引用失败。css 和 js 的文件路径都是 http://my.website.com/static/…(或 css)。
分析
CRA(create-react-app) 的项目配置默认是跑在根目录下的。如果查看 dist 目录下的 html 会发现,所有的 css 或 js 文件的引用路径都是 / 开头的绝对路径。
解决
将打包路径从绝对路径改为相对路径:
# package.json
{

“homepage”: “.”, // 添加 homepage 属性,将路径改为当前目录

}
重新编译后看到,所有的资源文件路径都改过来了。
问题 2:加载成功,网页空白
重新上传到服务器,更新 dist 目录下的文件,重启 nginx 后访问网页。
现象
结果发现,网页仍然是空白一片。查看 html 的渲染结果,发现似乎 js 并没有执行。
分析
在 react-router-dom 的例子中,通常使用的是 BrowserRouter。这种类型的 Router 在向服务器发送请求时,如果相对于二级目录的路由去指向对应的页面路由,就会找不到资源,因此也就不会渲染。
解决
BrowserRouter 有一个属性叫做 basename,就是用于解决此类问题。

import {Route, BrowserRouter as Router, Switch, Redirect} from ‘react-router-dom’;


<Router basename=’/project1′>
<Switch>
<Redirect exact key=’index’ path=’/’ to=’/home’ />
{routes}
</Switch>
</Router>

问题 3:访问成功,刷新后 404
修改以上配置并编译部署,重启 nginx 后可正常访问网页。但刷新后,网页变为一片空白。
现象
网页显示,在请求页面路由如 http://my.website.com/project… 时,该路由的请求状态为 404。
分析
还是因为 BrowserRouter 的问题,之前能正常访问时因为路由中设置了 Redirect,所以能访问到根目录并自动跳转到 /home。但直接访问则会访问失败。
解决
在 nginx 配置中加入 try_files 命令
location /project1 {
alias /data/www/react-project/dist;
# index index.html
try_files $uri /project1/index.html
}
这样,在请求 $uri 时如果找不到对应的资源,会 fallback 回去加载 index.html。
问题解决。

正文完
 0