在tomcat中部署React单页应用

一、简介

    tomcat通常用来做应用服务器,但也可以用来做web服务器。

    对于小型web应用(尤其是当后端用java开发时),将前端程序和后台程序都放在tomcat中非常方便,省去了配置web服务器、配置跨域、配置代理等步骤。

    下面是一个后台用java开发,前端用React框架(Create React App工具)开发的单页应用的部署方式(这里假设前端代码打包后放在tomcat根目录下的myApp文件夹中,后台代码打包后放在tomcat根目录的myServer文件夹中)。

二、部署前端程序

    Create React App的官方文档告诉了我们前端配置方式。下面是一张官网的配置说明截图。

    

    简单翻译如下:

        默认情况下,Create React App假设应用被托管在服务器根目录下,可以通过在package.json文件中设置homepage字段来修改。例如:

"homepage": "http://mywebsite.com/relativepath",

        这项配置可以让Create React App正确的“推测”出生成的HTML文件中使用的“根路径“。这里,“根路径”是指:打包后生成的HTML文件中用到的.js、.css文件等该去哪个目录下寻找。

        注意:如果使用的react-router 4以上版本,可以给<Router>元素设置basename prop来修改<Link>元素的根路由,例如:

<BrowserRouter basename="/calendar"/>
<Link to="/today"/>    //将被渲染为<a href="/calendar/today">

    因此,前端代码打包前需要两项配置

        1.在package.json文件中增加“homepage”字段,字段值为前端工程的所在文件夹路径。这一配置决定了打包后的生成的HMTL中script标签的src属性值、link标签的href属性值。

        例如,要将前端工程部署在myApp文件夹下,需要进行如下配置。

"homepage": "/myApp"

        配置好后,运行npm run build,打包生成的html文件中的script标签如下:

<script src="/myApp/static/js/main.3ad4d914.chunk.js"></script>

        如果未设置homepage属性,打包后的html文件中的script标签如下:

<script src="/static/js/main.3ad4d914.chunk.js"></script>

        可见,如果打包后的前端代码位于根目录下的myApp文件夹中,但package.json中未设置homepage字段,服务器就会到根目录中(即tomcat的webapp文件夹)寻找项目中所需的js文件和css文件,很明显找不到。

        因此,homepage配置是用于告诉服务器去那个文件夹下寻找所需的脚本文件和样式文件。

        2.为<Router>元素设置basename prop,其值亦为前端工程所在的文件夹路径。这一配置是为了让前端路由能够正确命中。

        经过步骤1的配置后,在浏览器中输入正确的地址,页面以及js文件和css文件都能够正确的加载,但页面中却显示一片空白,是因为没有命中任何前端路由。

        举例说明如下:

<Route exact path="/">
    <Home />
</Route>

        假设前端工程部署在服务器的myApp文件夹下,在浏览器中输入http://localhost:8080/myApp,页面可以正确加载,但不会命中上面这个<Route>,因为此时“路由”是“/myApp”,而不是“/”。为了让前端路由能够正确命中,需要修改<Router>元素。如下图。

<Router basename="/myApp">
<App /> </Router>

        修改完之后,再次输入http://localhost:8080/myApp,就可以正确匹配<Route exact path="/">,进而渲染<Home />组件。

        这里有一个最佳实践,Router元素不应该写成示例中那样,其basename prop应该保存在一个变量中,这个变量的值则保存在配置文件中。这样,当前端项目要部署在其他文件夹中的时候,只需要修改package.json文件以及配置文件,而不需要修改代码。

        设置好package.json和Router后,运行npm run build命令打包(打包后的文件一般保存在build文件夹下)。打开build文件夹,将其中的文件全部复制到tomcat根目录中的myApp文件夹下。

        经过前述配置后,在浏览器中输入正确的地址,即可加载页面,同时各项路由也能正确命中。但“浏览器刷新”问题还没有解决。

        这个问题需要通过tomcat配置来解决。Create React App官网中没有直接给出tomcat的配置说明,不过在tomcat下的解决方法和在其他服务器中类似:当找不到页面时(404),返回首页(即index.html)。

        配置方法为:在前端程序所在的文件夹中(myApp文件夹),新建“WEB-INF“文件夹。在“WEB-INP”文件夹下,新建web.xml文件,其中的内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<!--
 Licensed to the Apache Software Foundation (ASF) under one or more
  contributor license agreements.  See the NOTICE file distributed with
  this work for additional information regarding copyright ownership.
  The ASF licenses this file to You under the Apache License, Version 2.0
  (the "License"); you may not use this file except in compliance with
  the License.  You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
-->
<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_4_0.xsd"
  version="4.0"
  metadata-complete="true">

  <display-name>myApp</display-name>
  <description>
     Welcome to myApp
  </description>
  <error-page>
   <error-code>404</error-code>  
   <location>/index.html</location> 
  </error-page>
</web-app>

        上述代码的重点是<error-page>标签,这个标签告诉tomcat,当发生404错误时,返回index.html页面。

        至此,前端程序部署完毕。

 三、部署后台程序

        后台程序打包为war包后,重命名为myServer,然后复制到tomcat的根目录下即可。

        由于前后端处于同一个域中,因此不需要设置跨域、代理等。

        启动tomcat,浏览器中输入正确的地址,即可访问完整的应用。     

        

posted @ 2021-07-29 17:21  奔_gis  阅读(1604)  评论(0编辑  收藏  举报