【问题标题】:Spring-React frontend-maven-plugin not workingSpring-React frontend-maven-plugin 不起作用
【发布时间】:2020-07-16 01:14:47
【问题描述】:

我正在关注https://spring.io/guides/tutorials/react-and-spring-data-rest/ 的文档来构建一个使用 Spring 的 React 应用程序。弹簧部分很好,直到它到达建议使用插件安装节点和 npm 模块的部分。我的问题是这个插件没有做它应该做的事情。我检查了文档并建立了一些执行(我真的不知道插件是如何工作的)。我介绍了这些执行,但我仍然看不到 React 应用程序在浏览器中的 localhost:8080 呈现。

这是他们在 spring 文档中使用的插件。就这样。我希望任何学习过本教程的人都可以帮助我。

<plugin>
    <groupId>com.github.eirslett</groupId>
    <artifactId>frontend-maven-plugin</artifactId>
</plugin>

【问题讨论】:

    标签: reactjs spring spring-boot spring-mvc


    【解决方案1】:

    您可以在同一端口上运行 React 前端和 SpringBoot 后端并将它们打包为单个工件!

    这是我要去的演示项目的Github链接 在这里解释

    Spring Boot 可以提供来自 src/main/resources/static 文件夹的静态内容。我们将利用 Spring Boot 的上述特性来服务于 react 项目的单页。我们将从目标目录中的静态文件夹中提供一个 html 页面,而不是在源目录中。

    项目结构-

    首先,使用https://start.spring.io 创建一个spring boot 项目。添加 Web 依赖项。将 groupId 和 artifactId 设置为您想要的任何内容。生成项目并将其解压缩到您的项目目录中。

    或者,如果您使用的是 Spring Tools Suite,您只需点击 File-&gt;New-&gt;Spring Starter Project 并提及创建 Spring Boot 项目所需的详细信息。

    src/main 内的 frontend 文件夹应该让您的 react 应用程序使用 create-react-app 构建。

    所以,有两个步骤-

    1. 创建前端的生产版本。
    2. 将生产版本复制到 ${target/classes/}。

    我们将使用两个 maven 插件和 Thymleaf

    1. frontend-maven-plugin 第 1 步。
    2. maven-resources-plugin 第 2 步。

    对于frontend-maven-plugin 在步骤 1-- 如果您仔细查看 pom.xml 那里我提到了 src 目录 frontend-maven-plugin 将从那里获取文件,创建生产构建并将内容放在提到的输出目录中(在src/main/frontend/build 内)。

     <workingDirectory>${frontend-src-dir}</workingDirectory>
     <installDirectory>${project.build.directory}</installDirectory>
    

    对于第 2 步的 maven-resources-plugin-- 它将采用 frontend-maven-plugin 刚刚创建的生产版本并将其放置在您的根目录中,然后是 target/classes/static

    然后我们将使用 Thymleaf 来提供来自 target/classes/static 的静态内容,并使用控制器中的休息端点。否则你必须输入html file的名字,比如http://localhost:8080/index.html

    您的 pom.xml 应该如下所示-

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>2.4.2</version>
            <relativePath /> <!-- lookup parent from repository -->
        </parent>
        <groupId>com.springreact</groupId>
        <artifactId>demo</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <name>demo</name>
        <description>Run React Frontend and SpringBoot Backend on the same port.</description>
        <properties>
            <java.version>1.8</java.version>
            <frontend-src-dir>${project.basedir}/src/main/frontend</frontend-src-dir>
            <node.version>v14.15.4</node.version>
            <yarn.version>v1.16.0</yarn.version>
            <frontend-maven-plugin.version>1.7.6</frontend-maven-plugin.version>
        </properties>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <optional>true</optional>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId> 
                <artifactId>spring-boot-starter-thymeleaf</artifactId>
            </dependency>
        </dependencies>
    
        <build>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                    <configuration>
                        <excludes>
                            <exclude>
                                <groupId>org.projectlombok</groupId>
                                <artifactId>lombok</artifactId>
                            </exclude>
                        </excludes>
                    </configuration>
                </plugin>
                <plugin>
                    <groupId>com.github.eirslett</groupId>
                    <artifactId>frontend-maven-plugin</artifactId>
                    <version>${frontend-maven-plugin.version}</version>
    
                    <configuration>
                        <nodeVersion>${node.version}</nodeVersion>
                        <yarnVersion>${yarn.version}</yarnVersion>
                        <workingDirectory>${frontend-src-dir}</workingDirectory>
                        <installDirectory>${project.build.directory}</installDirectory>
                    </configuration>
    
                    <executions>
                        <execution>
                            <id>install-frontend-tools</id>
                            <goals>
                                <goal>install-node-and-yarn</goal>
                            </goals>
                        </execution>
    
                        <execution>
                            <id>yarn-install</id>
                            <goals>
                                <goal>yarn</goal>
                            </goals>
                            <configuration>
                                <arguments>install</arguments>
                            </configuration>
                        </execution>
    
                        <execution>
                            <id>build-frontend</id>
                            <goals>
                                <goal>yarn</goal>
                            </goals>
                            <phase>prepare-package</phase>
                            <configuration>
                                <arguments>build</arguments>
                            </configuration>
                        </execution>
                    </executions>
                </plugin>
                <plugin>
                    <artifactId>maven-resources-plugin</artifactId>
                    <executions>
                        <execution>
                            <id>position-react-build</id>
                            <goals>
                                <goal>copy-resources</goal>
                            </goals>
                            <phase>prepare-package</phase>
                            <configuration>
                                <outputDirectory>${project.build.outputDirectory}/static</outputDirectory>
                                <resources>
                                    <resource>
                                        <directory>${frontend-src-dir}/build</directory>
                                        <filtering>false</filtering>
                                    </resource>
                                </resources>
                            </configuration>
                        </execution>
                    </executions>
                </plugin>
            </plugins>
        </build>
    </project>
    

    这是控制器代码。

    package com.springreact.demo.controller;
    
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.servlet.ModelAndView;
    
    @Controller
    public class IndexController {
    
        @GetMapping("")
        public ModelAndView home() {
            ModelAndView mav=new ModelAndView("index");
            return mav;
        }
    
    }
    

    如果您按照上述步骤操作,您应该会看到您的 React 应用程序正在http://localhost:8080/ 上启动。

    如果您仍有疑问,可以查看我在上面写的综合博客。以下是两个不同平台上的博客链接,你可以选择你喜欢的。

    开发社区-https://dev.to/arpan_banerjee7/run-react-frontend-and-springboot-backend-on-the-same-port-and-package-them-as-a-single-artifact-14pa

    中等-https://arpan-banerjee7.medium.com/run-react-frontend-and-springboot-backend-on-the-same-port-and-package-them-as-a-single-artifact-a790c9e10ac1

    【讨论】:

      【解决方案2】:

      如果您的项目结构如下所示:

      frontend/ -> React application
      src/ -> Spring Boot application
      

      您可以使用以下配置将 React 应用程序与 frontend-maven-plugin 捆绑在一起:

      <build>
          <resources>
            <resource>
              <directory>${project.basedir}/frontend/build</directory>
              <filtering>false</filtering>
              <targetPath>public/</targetPath>
            </resource>
            <resource>
              <directory>${project.basedir}/src/main/resources</directory>
              <filtering>false</filtering>
            </resource>
          </resources>
          <plugins>
            <plugin>
              <groupId>org.springframework.boot</groupId>
              <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
            <plugin>
              <groupId>com.github.eirslett</groupId>
              <artifactId>frontend-maven-plugin</artifactId>
              <version>1.8.0</version>
              <executions>
                <execution>
                  <id>install node and npm</id>
                  <goals>
                    <goal>install-node-and-npm</goal>
                  </goals>
                  <phase>generate-resources</phase>
                </execution>
                <execution>
                  <id>npm install</id>
                  <goals>
                    <goal>npm</goal>
                  </goals>
                  <phase>generate-resources</phase>
                  <configuration>
                    <arguments>install</arguments>
                  </configuration>
                </execution>
                <execution>
                  <id>npm build</id>
                  <goals>
                    <goal>npm</goal>
                  </goals>
                  <phase>generate-resources</phase>
                  <configuration>
                    <environmentVariables>
                      <CI>true</CI>
                    </environmentVariables>
                    <arguments>run build</arguments>
                  </configuration>
                </execution>
              </executions>
              <configuration>
                <workingDirectory>frontend</workingDirectory>
                <nodeVersion>v12.18.0</nodeVersion>
              </configuration>
            </plugin>
          </plugins>
        </build>
      

      如果您的项目结构不同,您必须调整workingDirectory 和第一个资源配置并将其指向您的文件夹。

      这个插件基本上执行几个 npm 命令来测试和构建你的 React 应用程序,并且使用 resources 配置,你可以扩展标准目录以包含在你的 .jar 中。然后可以通过http://localhost:8080 访问您的前端应用程序。

      您可以找到此here 的运行示例。

      【讨论】:

        【解决方案3】:

        我遵循相同的教程并停留在同一点:frontend-maven-plugin 似乎无法正常工作。此外,作者提供的代码库在我看来组织得不好,例如两个pom.xml 文件,一个在项目根文件夹,另一个在基本文件夹。

        这是我想出来的,终于奏效了:

        1. pom.xml 中添加frontend-maven-pluginplugins 以及您希望它执行的脚本。确保包含版本标签并提供最新版本(您可以在Maven Repository 中找到版本信息),否则将无法解析插件。
        <build>
            <plugins>
                <!-- For the sake of simplicity, -->
                <!-- other plugins are omitted. -->
                <plugin>
                    <groupId>com.github.eirslett</groupId>
                    <artifactId>frontend-maven-plugin</artifactId>
                    <version>1.12.0</version>
                    <configuration>
                        <installDirectory>target</installDirectory>
                    </configuration>
                    <executions>
                        <execution>
                            <id>install node and npm</id>
                            <goals>
                                <goal>install-node-and-npm</goal>
                            </goals>
                            <configuration>
                                <nodeVersion>v14.17.3</nodeVersion>
                                <npmVersion>7.18.1</npmVersion>
                            </configuration>
                        </execution>
                        <execution>
                            <id>npm install</id>
                            <goals>
                                <goal>npm</goal>
                            </goals>
                            <configuration>
                                <arguments>install</arguments>
                            </configuration>
                        </execution>
                        <execution>
                            <id>webpack build</id>
                            <goals>
                                <goal>webpack</goal>
                            </goals>
                        </execution>
                    </executions>
                </plugin>
            </plugins>
        </build>
        
        1. 在项目根文件夹中创建package.json文件,即与pom.xml相同的位置并粘贴以下内容:
        {
          "name": "spring-data-rest-and-reactjs",
          "version": "0.1.0",
          "description": "Demo of ReactJS + Spring Data REST",
          "repository": {
            "type": "git",
            "url": "git@github.com:spring-guides/tut-react-and-spring-data-rest.git"
          },
          "keywords": [
            "rest",
            "hateoas",
            "spring",
            "data",
            "react"
          ],
          "author": "Greg L. Turnquist",
          "license": "Apache-2.0",
          "bugs": {
            "url": "https://github.com/spring-guides/tut-react-and-spring-data-rest/issues"
          },
          "homepage": "https://github.com/spring-guides/tut-react-and-spring-data-rest",
          "dependencies": {
            "react": "^16.5.2",
            "react-dom": "^16.5.2",
            "rest": "^1.3.1"
          },
          "scripts": {
            "watch": "webpack --watch -d --output ./target/classes/static/built/bundle.js"
          },
          "devDependencies": {
            "@babel/core": "^7.1.0",
            "@babel/preset-env": "^7.1.0",
            "@babel/preset-react": "^7.0.0",
            "babel-loader": "^8.0.2",
            "webpack": "^4.19.1",
            "webpack-cli": "^3.1.0"
          }
        }
        
        1. 在项目根文件夹中创建webpack.config.js文件,即与pom.xml相同的位置并粘贴以下内容:
        var path = require('path');
        
        module.exports = {
            entry: './src/main/js/app.js',
            devtool: 'sourcemaps',
            cache: true,
            mode: 'development',
            output: {
                path: __dirname,
                filename: './src/main/resources/static/built/bundle.js'
            },
            module: {
                rules: [
                    {
                        test: path.join(__dirname, '.'),
                        exclude: /(node_modules)/,
                        use: [{
                            loader: 'babel-loader',
                            options: {
                                presets: ["@babel/preset-env", "@babel/preset-react"]
                            }
                        }]
                    }
                ]
            }
        };
        
        1. 将同一目录中的client.js 和整个api 文件夹复制到您的项目中。 app.js 使用 client.js,它使用 api 文件夹中的两个 .js 文件。这三个文件的源码可以在the tutorial repository找到。

        2. 现在您应该拥有一切以使 React 在这个项目中工作。虽然取决于您使用的 IDE,但它可能仍然“不工作”。让我进一步解释一下我的意思:

          1. 如果您使用命令行运行项目,只需在项目根文件夹中键入./mvnw spring-boot:run,它应该会像一个魅力一样工作。
          2. 如果您像我一样使用绿色小三角形在 IntelliJ 中运行应用程序,您必须编辑运行/调试配置才能使其工作;否则应用程序可以成功运行,但不会生成任何bundle.js

          首先,打开 IntelliJ -> 运行 -> 编辑配置

          其次,点击Before Launch部分中的+按钮并选择Run Maven Goal

          第三,在命令行中输入generate-resources,点击确定。我们选择frontend-maven-plugin git repo 中提到的这个命令,如果不指定,目标在generate-resources 阶段执行。

          最后,您可以创建一个 Maven 目标以在构建之前清理所有内容。这是Before launch 的样子:

          现在单击绿色三角形运行应用程序,您将获得与教程中提到的相同的结果(除了员工列表中没有寄宿生,因为我们没有.css 文件)。

        一些最后的想法:

        1. 您添加frontend-maven-plugin 以在您的项目中使用nodenpm
        2. 您添加 package.json 以安装必要的 JavaScript 模块,例如React.js。
        3. 您添加webpack.config.js 以指示webpack 将javascript 文件转换为一个名为bundle.js 的文件并将其输出到项目的静态文件夹中
        4. 您在pom.xml 中添加了许多executiongoal 标签以自动执行第2 步和第3 步。
        5. 您执行 maven 目标以启动自动化过程。

        【讨论】:

          猜你喜欢
          • 2019-11-03
          • 1970-01-01
          • 1970-01-01
          • 2020-05-20
          • 2016-09-27
          • 1970-01-01
          • 2016-12-08
          • 1970-01-01
          • 2019-04-11
          相关资源
          最近更新 更多