Categories
程式開發

用Spring Boot打包你的React應用


先講一講這篇文章的背景故事。之前我的團隊需要在我們需求的基礎架構上節省一些資金,並且由於我們要構建的這個應用程序中,大部分負載都會在客戶端而非服務端上,所以我們決定試驗一下能否將一個Spring應用程序與一個React應用結合起來,並打包成一個war文件。

這篇文章會告訴你如何將Create React App與Spring Boot結合使用,從而為你打包出單個war文件。

Spring Boot和Create React App的基本功能介紹

  • Create React App可幫助你非常快速地啟動React項目。它為你提供了啟動並儘快運行項目所需的全部基本功能。
  • Spring Boot可以幫助你快速而輕鬆地啟動和維護Spring應用程序。

步驟

1.目標

  • 在單一war文件中包含前端和後端,具有優化的生產構建
  • 保留Create React App所提供的好處,如熱重載等

2.設置

附註:我選擇的IDE是IntelliJ。當使用React代碼時,我通常會切換到VS Code。你可以隨意使用自己習慣的方法

  • 在Github上創建一個空的倉庫,並添加自述文件、gitignore和許可證等。
  • 轉到(https://start.spring.io)創建你的Spring應用程序,並下載到本地。 Group和Artifact也可以隨意設置。

用Spring Boot打包你的React應用 1

GroupId:e.the.awesome

Artifact:spring-react-combo-app

3.將下載的項目解壓縮到你的git目錄中並提交。

你的SpringReactComboAppApplication看起來應該像這樣。

package e.the.awesome.springreactcomboapp;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;

@SpringBootApplication
public class SpringReactComboAppApplication  extends SpringBootServletInitializer{

public static void main(String[] args) {
SpringApplication.run(SpringReactComboAppApplication.class, args);
}

}

4.現在創建一個基本服務。

我們將其稱為DadJokesController。這應該在與SpringReactComboAppApplication文件所在的文件夾中創建。我知道這不是正確的Rest API格式,但現在暫時忽略它。

package e.the.awesome.springreactcomboapp;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class DadJokesController {
    @GetMapping("/api/dadjokes")
    public String dadJokes() {
        return "Justice is a dish best served cold, if it were served warm it would be just water.";
    }
}

5.在你的終端運行

mvn spring-boot:run

然後在瀏覽器中檢查http://localhost:8080/api/dadjokes。你應該會看到我們添加到控制器中的dad joke。

6.要創建你的React應用,只需在根目錄中運行

npx create-react-app basic-frontend-app

你可以隨心所欲地調用它,我這裡只調用我的basic-frontend-app

7.要運行前端應用程序:

cd basic-frontend-app
npm start

8.解決代理問題

由於我們要將Dad Jokes服務集成到前端,因此首先我們要解決代理問題。你可能已經註意到了,你的服務從localhost:8080開始,而前端從localhost:3000開始。如果我們嘗試從前端調用服務,具體取決於你的瀏覽器,你可能會收到一個CORS錯誤。

用Spring Boot打包你的React應用 2

解決此問題的最簡單方法是讓前端代理處理從端口3000到8080的所有請求。此更改將在package.json文件中進行:

{
  "name": "basic-frontend-app",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "react": "^16.3.1",
    "react-dom": "^16.3.1",
    "react-scripts": "1.1.4"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test --env=jsdom",
    "eject": "react-scripts eject"
  },
  "proxy": {
    "/api": {
      "target": "http://localhost:8080",
      "ws": true
    }
  }
}

將以下內容添加到你的前端App.js文件中

import React, {Component} from 'react';
import logo from './logo.svg';
import './App.css';

class App extends Component {

    state = {};

        componentDidMount() {
            this.dadJokes()
        }

    dadJokes = () => {
        fetch('/api/dadjokes')
            .then(response => response.text())
            .then(message => {
                this.setState({message: message});
            });
    };

    render() {
        return (
            
logo

{this.state.message}

To get started, edit src/App.js and save to reload.

);     } } export default App;

如果你也遇到了下圖的這個錯誤,我的做法是:首先刪除了package-lock.json 文件;其次在node_modules 文件夾中重新安裝了npm包並再次運行;然後重新啟動前端,問題就解決了。

用Spring Boot打包你的React應用 3

9.你的應用程序現在應該看起來像這樣。

你可以看到dad jokes API調用的結果。

用Spring Boot打包你的React應用 4

10.創建生產版本

現在我們的基本前端和後端已經完成,該創建生產版本和單個war文件了。

下添加



com.github.eirslett
frontend-maven-plugin
1.6

在pom文件的部分下,我們將添加以下命令,這些命令將在運行mvn clean install時執行以下操作。

  • npm安裝指定版本的node
  • 運行我們前端的生產構建
  • 存放生產構建

   com.github.eirslett
   frontend-maven-plugin
   1.6
   
      basic-frontend-app
      target
   
   
      
         install node and npm
         
            install-node-and-npm
         
         
            v8.9.4
            5.6.0
         
      
      
         npm install
         
            npm
         
         
            install
         
      
      
         npm run build
         
            npm
         
         
            run build
         
      
   


   maven-antrun-plugin
   
      
         generate-resources
         
            
               
                  
               
            
         
         
            run
         
      
   

附註:對於你的插件來說,順序正確是很重要的,因此請確保在復制構建文件執行之前執行node/npm安裝

11.運行 mvn clean install

添加此命令後,運行mvn clean install,並驗證target/classes目錄同時包含了前端文件和Java文件。這裡你應該是一路暢通的。

最後看一下我的pom文件:

https://github.com/Emmanuella-Aninye/Spring-Boot-ReactJS-Starter/blob/master/pom.xml

這就是我的方法。如果你想看看repo或使用它,可以在我的Github上找到它:

https://github.com/Emmanuella-Aninye/Spring-Boot-ReactJS-Starter

延伸閱讀:

https://hackernoon.com/package-your-react-app-with-spring-boot-a-how-to-guide-cdfm329w