显示导航

合并 React 配置文件项目

了解如何生成包含 React 和 Grails 产品工件的 JAR 文件。

作者:Zachary Klein

Grails 版本 3.3.0

1 Grails 培训

Grails 培训 - 为开发人员提供的培训,由创建并积极维护 Grails 框架的人员开发!

2 开始使用

在此指南中,您将创建 React 配置文件中的 serverclient 项目的组合构建。默认情况下,React 配置文件设置了独立的前端和后端应用,能带来更有效率的开发流程。但这可能无法满足部署需求,特别是如果您的整个应用部署到诸如 Tomcat 之类的 servlet 容器,或者作为“胖”JAR 执行。得益于 Grails 和 Gradle 构建工具的灵活性,我们只需进行一些更改便可以配置 Grails/React 应用的统一构建。

2.1 所需内容

要完成此指南,您将需要以下内容

  • 一些时间

  • 适当的文本编辑器或 IDE

  • 已安装 JDK 1.7 或更高版本,并已正确配置 JAVA_HOME

2.2 如何完成指南

为开始,请执行以下操作

Grails 指南存储库包含两个文件夹

  • initial 初始项目。通常是一个带有附加代码的简单 Grails 应用,让您可以先行一步。

  • complete 已完成的示例。它是按指南介绍的步骤执行并对 initial 文件夹应用了更改的结果。

要完成指南,请转到 initial 文件夹

  • cdgrails-guides/react-combined/initial

并按照下一部分中的说明进行操作。

如果你在 grails-guides/react-combined/complete 中进行 cd,你可以直接去往已完成的示例

3 编写应用程序

如果你打开本指南的 initial 项目,你将发现一个从 React 配置文件中生成的简单项目。

我们进行了一个微小的更改。我们将 initial/server/gradle.properties 移至根目录 initial/gradle.properties

server Grails 应用程序和 client React 应用程序都有 production 构建任务设定——你可以运行 ./gradlew server:assemble 来构建一个 WAR 或 JAR 文件,并可以运行 yarn build(或 ./gradlew client:build)来生成一个静态 React/webpack 捆绑包。我们的第一步是在项目结构顶部,在 clientserver 子项目之上创建一个新的 build.gradle 文件。

3.1 设置 Gradle

创建一个新的 build.gradle 文件(与 settings.gradle 同级),并添加以下内容

build.gradle
task copyClientResources(dependsOn: ':client:build') { (1)
    group = 'build'
    description = 'Copy client resources into server'
    doLast {
        copy {
            from project(':client').buildDir.absolutePath
            into "${project(':server').buildDir}/resources/main/public"
        }
    }
}
task assembleServerAndClient(dependsOn: ['copyClientResources', ':server:assemble']) {  (2)
    group = 'build'
    description = 'Build combined server & client JAR'

    doLast {
        copy {
            from fileTree(dir: "${project(':server').buildDir}/libs/") (4)
            into "$rootDir/build/"
        }

        logger.quiet "JAR generated at $rootDir/build/. It combines the server and client projects."
    }
}
task(":server:assemble").mustRunAfter(copyClientResources) (3)
1 copyClientResources 任务将由 yarn build 生成的静态文件复制到 server 项目的资源目录中。
2 assembleServerAndClient 任务将复制步骤绑定到 server 项目的现有 Gradle assemble 任务。这意味着我们只有在运行这个顶级任务时才会得到我们统一的存档(单独运行 server:assemble 将生成一个没有客户端资源的“简单”WAR/JAR 文件)。
3 如果待执行的是 copyClientResources,则它必须在 :server:assemble 之前。这确保了客户端静态文件当 Grails 应用程序被组装时将可用。
4 在组合 JAR 文件创建之后,我们将文件复制到顶级 build 目录中。

在本指南中,我们将使用一个可执行 JAR 文件作为我们的部署目标。要启用这个,编辑 server 项目的 build.gradle 文件,并删除以下行

server/build.gradle
apply plugin:"war"

3.2 更新我们的配置

现在我们有一个统一的 Gradle 构建目标,我们有几个额外的配置更改要做。所有这些更改都与独立的 Grails 和 React 应用程序与我们新的组合部署之间的 URL 差异有关。

默认情况下,已部署 Grails 应用程序中的静态资源会从 /static 基本 URL 提供。那会和我们的 React 应用程序预期相冲突,但幸运的是,这是一个非常简单的更改。

编辑 server/grails-app/conf/application.yml

server/grails-app/conf/application.yml
grails:
    resources:
        pattern: /**

这简单地设置了静态资源 URL,以设定为根上下文。

按照类似的步骤,我们需要编辑 React 应用程序用于针对 Grails 应用程序进行 REST 调用的 URL。这可在 client 项目中的 src/config.js 中完成。

编辑 client/src/config.js

client/src/config.js
import pjson from './../package.json';

const prod = process.env.NODE_ENV === 'production';  (1)

console.log(`Loading ${process.env.NODE_ENV} config...`);

export const SERVER_URL = prod ? '' : 'http://localhost:8080';

export const CLIENT_VERSION = pjson.version;
export const REACT_VERSION = pjson.dependencies.react;
1 process.env.NODE_ENV 是一个 NodeJS 环境变量,它将告诉我们在生产模式还是开发模式下运行。我们使用简单的三元运算符来切换 SERVER_URL 配置属性,以便在开发期间指向我们的独立 Grails 应用程序并在生产中使用根上下文。

3.3 URL 映射

我们的最终修改需要在 UrlMappings.groovy 中进行。如果你还记得,默认情况下,server Grails 应用程序会在根上下文中呈现一些应用程序元数据。但是,为了能让我们的组合版本工作,我们需要在根上下文中加载 React 应用程序。幸运的是,这同样是一个非常简单的改动。

编辑 server/grails-app/controllers/demo/UrlMappings.groovy

server/grails-app/controllers/demo/UrlMappings.groovy
if ( Environment.current == Environment.PRODUCTION ) { (1)
    '/'(uri: '/index.html')
} else {
    '/'(controller: 'application', action:'index')
}
1 我们正在使用 grails.util.Environment class 确定我们在开发模式下运行还是在已部署的工件中运行,并相应地设置 URL 映射。

使用这个新映射配置,当我们构建可执行 JAR 文件时,/ URL 将映射到 /index.html,该文件也碰巧是 React 应用程序的登录页面。

4 运行应用程序

要生成统一可执行 JAR 文件,只需运行以下命令

~ ./gradlew assembleServerAndClient

...
JAR generated at build. It combines the server and client projects.

要运行应用程序,请使用 java -jar 命令

~ java -jar build/server-0.1.jar

...
Grails application running at http://localhost:8080 in environment: production

浏览 http://localhost:8080,你应该可以看到 React 应用程序。

http://localhost:8080/application/ 发出 GET 请求,你应该可以看到来自 Grails 应用程序的应用程序元数据。

恭喜,你拥有了统一的 Grails/React 产品版本!