之前公司一直是用node服务器来对react打包后的项目进行服务器部署的,最近有后台小伙伴问可以将打包后的文件丢到tomcat里面部署吗,我回答当然可以。但是在测试部署过程中遇到两个问题。
先说下部署方式,打包后生产的dist文件夹,丢到tomcat下的webapp下面。目录如下图,通过http://localhost:8080/dist/
访问,发现
问题1. 由于用的是全局路由(即在所以路由外面包了一层公共入口),发现部署后只能访问全局路由的内容,所以子路由一片空白,页面上只有一个全局路由的架子。(如果不用全局路由,页面直接就会空白,访问不到)
原因:原来默认我们在本地开发是直接通过http://localhost:8080/
来访问的,现在部署的时候多了dist,路由就找不到了。
解决方案:所以需要在开发过程中添加基础路径。
比如umi框架,只需要在.umirc.js添加base:'/dist'
即可,其他框架,如dva等,需要将createHistory()
改成createHistory({basename:'/dist'})即可。这样页面就可以访问到了。
问题2:但是又发现当我跳转到其他页面时,开始是好的,只要一刷新,页面就报404找不到了。
原因:原来之所以你在开发时候可以由首页跳转到其他路由地址,是因为这是由前端自行渲染的,即在React Router定义了对应的路由,有router更改了location,实际并没有刷新网页访问后台。所以页面没有问题。但是部署到tomcat中,当你刷新时,此时并不是之前的客户端通过router来更改location,而是直接访问的后台该页面地址,然后后台返回页面到浏览器上。并没有经过前台的路由(react所有的路由都是在index.html中来转发,所以必须要任何请求必须要经过index.html),所以就报404了。
解决方案:所以,我们需要对报404的页面进行重定向到index.html,剩下的就会由react-router来进行路径跳转。
我们在部署的dist文件夹中新建一个WEB-INF文件夹,然后新建web.xml文件(web.xml用来初始化工程配置信息,比如说welcome页面,filter,listener,servlet,servlet-mapping,启动加载级别等等。),在其中添加下面代码就行了:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1"
metadata-complete="true">
<error-page>
<error-code>404</error-code>
<location>/index.html</location>
</error-page>
</web-app>
重启tomcat服务器,刷新页面,成功访问。
至此,成功部署。注:上面出现的问题,react-router模式为BrowerRouter才会有这种问题,HashRouter不会出现问题,因为hash路径并没有改变路径,只是在同一个路径增加参数而已