在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,瀏覽器中輸入正確的地址,即可訪問完整的應用。     

        


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM