若是从头开始搭建React项目,create-react-app一般是开发者的首选。毕竟不是谁都有精力去了解WebPack的复杂配置,而CRA将配置隐藏开箱即用的特性必然会受到广泛欢迎。css
到了部署阶段,我一般使用nginx做为web容器,将项目部署到一个根目录下访问。如html
# nginx配置 server { listen 80; server_name my.website.com; ... location / { alias /data/www/react-project/dist; index index.html } }
那么只要咱们将项目文件放到对应的目录下,重启nginx便可开始访问web页面。react
有时咱们有多个web项目,多个项目不可能同时挂在根目录下,因此咱们会划分二级目录来分别访问各个web项目。如nginx
此时,若是简单将nginx配置的location改成/project1,则会出现网页没法访问的错误。web
# 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)。json
CRA(create-react-app)的项目配置默认是跑在根目录下的。若是查看dist目录下的html会发现,全部的css或js文件的引用路径都是/开头的绝对路径。服务器
将打包路径从绝对路径改成相对路径:react-router
# package.json { ... "homepage": ".", // 添加homepage属性,将路径改成当前目录 ... }
从新编译后看到,全部的资源文件路径都改过来了。app
从新上传到服务器,更新dist目录下的文件,重启nginx后访问网页。dom
结果发现,网页仍然是空白一片。查看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> ...
修改以上配置并编译部署,重启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。
问题解决。