合并 React 配置文件项目
了解如何生成包含 React 和 Grails 产品工件的 JAR 文件。
作者:Zachary Klein
Grails 版本 3.3.0
1 Grails 培训
Grails 培训 - 为开发人员提供的培训,由创建并积极维护 Grails 框架的人员开发!
2 开始使用
在此指南中,您将创建 React 配置文件中的 server
和 client
项目的组合构建。默认情况下,React 配置文件设置了独立的前端和后端应用,能带来更有效率的开发流程。但这可能无法满足部署需求,特别是如果您的整个应用部署到诸如 Tomcat 之类的 servlet 容器,或者作为“胖”JAR 执行。得益于 Grails 和 Gradle 构建工具的灵活性,我们只需进行一些更改便可以配置 Grails/React 应用的统一构建。
2.1 所需内容
要完成此指南,您将需要以下内容
-
一些时间
-
适当的文本编辑器或 IDE
-
已安装 JDK 1.7 或更高版本,并已正确配置
JAVA_HOME
2.2 如何完成指南
为开始,请执行以下操作
-
下载并解压源代码
或
-
克隆 Git 存储库
git clone https://github.com/grails-guides/react-combined.git
Grails 指南存储库包含两个文件夹
-
initial
初始项目。通常是一个带有附加代码的简单 Grails 应用,让您可以先行一步。 -
complete
已完成的示例。它是按指南介绍的步骤执行并对initial
文件夹应用了更改的结果。
要完成指南,请转到 initial
文件夹
-
cd
至grails-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 捆绑包。我们的第一步是在项目结构顶部,在 client
和 server
子项目之上创建一个新的 build.gradle
文件。
3.1 设置 Gradle
创建一个新的 build.gradle
文件(与 settings.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
文件,并删除以下行
apply plugin:"war"
3.2 更新我们的配置
现在我们有一个统一的 Gradle 构建目标,我们有几个额外的配置更改要做。所有这些更改都与独立的 Grails 和 React 应用程序与我们新的组合部署之间的 URL 差异有关。
默认情况下,已部署 Grails 应用程序中的静态资源会从 /static
基本 URL 提供。那会和我们的 React 应用程序预期相冲突,但幸运的是,这是一个非常简单的更改。
编辑 server/grails-app/conf/application.yml
grails:
resources:
pattern: /**
这简单地设置了静态资源 URL,以设定为根上下文。
按照类似的步骤,我们需要编辑 React 应用程序用于针对 Grails 应用程序进行 REST 调用的 URL。这可在 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
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 产品版本!