[英]How to add static files to jar using Gradle build in Spring Boot + Angular 2 project
I have a Spring Boot + Angular 2 project. 我有一个Spring Boot + Angular 2项目。 I want to deploy it to Heroku.
我想将它部署到Heroku。 I'm able to run the npm build then copy the generated files over to the public folder (src/resources/public) manually, then run the backend build.
我能够运行npm构建,然后手动将生成的文件复制到公共文件夹(src / resources / public),然后运行后端构建。 What I want to do is to set up a gradle build that will do all of that at once.
我想要做的是设置一个gradle构建,它将立即完成所有这些。 What I have so far is a gradle build that will build the front end, build the backend, however it does not copy the static files before generating the jar.
到目前为止我所拥有的是一个gradle构建,它将构建前端,构建后端,但是在生成jar之前它不会复制静态文件。 Since the jar does not contain said static files, it won't work on Heroku.
由于jar不包含所述静态文件,因此它不适用于Heroku。
Here's the project folder structure: 这是项目文件夹结构:
root
backend
src/main/java
src/main/resources
frontend
--> angular files go here
build/libs -> where the JAR file goes
The gradle build file: gradle构建文件:
buildscript {
repositories {
mavenCentral()
}
dependencies {
// spring
classpath('org.springframework.boot:spring-boot-gradle-plugin:1.5.2.RELEASE')
classpath('org.springframework:springloaded:1.2.6.RELEASE')
}
}
plugins {
id "com.moowork.node" version "1.2.0"
}
// gradle wrapper
task wrapper(type: Wrapper) {
gradleVersion = '3.4'
}
// configure gradle-node-plugin
node {
version = '8.1.4'
npmVersion = '5.0.3'
download = true
workDir = file("${project.projectDir}/node")
nodeModulesDir = file("${project.projectDir}/")
}
// clean node/node_modules/dist
task npmClean(type: Delete) {
final def webDir = "${rootDir}/frontend"
delete "${webDir}/node"
delete "${webDir}/node_modules"
delete "${webDir}/dist"
delete "${webDir}/coverage"
delete "${rootDir}/backend/src/main/resources/public"
}
// clean task for npm
task copyFiles {
doLast {
copy {
from "${rootDir}/frontend/dist"
into "${rootDir}/backend/src/main/resources/public"
}
}
}
// build task for npm
task frontendBuild {}
frontendBuild.dependsOn(npm_install)
frontendBuild.dependsOn(npm_run_build)
npm_install {
args = ['--prefix', './frontend']
}
npm_run_build {
args = ['--prefix', './frontend']
}
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'idea'
apply plugin: 'org.springframework.boot'
sourceSets {
main {
java {
srcDirs = ['backend/src/main/java']
}
resources {
srcDirs = ['backend/src/main/resources']
}
}
}
copyFiles.dependsOn(frontendBuild);
compileJava.dependsOn(frontendBuild);
task backendBuild {}
backendBuild.dependsOn(compileJava)
backendBuild.dependsOn(jar)
jar.dependsOn(copyFiles)
repositories {
mavenCentral()
}
eclipse {
classpath {
containers.remove('org.eclipse.jdt.launching.JRE_CONTAINER')
containers('org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8')
}
}
idea {
module {
inheritOutputDirs = false
outputDir = file("${buildDir}/classes/main/")
}
}
jar {
baseName = 'expense-splitter'
version = '0.0.1'
}
sourceCompatibility = 1.8
targetCompatibility = 1.8
configurations {
dev
}
dependencies {
// spring
compile('org.springframework.boot:spring-boot-starter-web:1.5.2.RELEASE')
compile('org.springframework.boot:spring-boot-starter-data-jpa:1.5.2.RELEASE')
compile('org.springframework.boot:spring-boot-starter-security:1.5.2.RELEASE')
compile('org.apache.commons:commons-lang3:3.3.2')
// to make hibernate handle java 8 date and time types correctly
// it's marked as deprecated but we need to keep it until
// spring boot jpa starts using hibernate 5.2
compile('org.hibernate:hibernate-java8:5.1.0.Final')
// json web tokens
compile ('io.jsonwebtoken:jjwt:0.7.0')
compile 'mysql:mysql-connector-java'
// google gson
compile('com.google.code.gson:gson:2.8.0')
// jackson - parsing of java 8 date and time types
compile('com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.8.7')
// spring dev tools
dev('org.springframework.boot:spring-boot-devtools:1.5.2.RELEASE')
// testing
testCompile('org.springframework.boot:spring-boot-starter-test:1.5.2.RELEASE')
}
// run spring boot app
bootRun {
//addResources = true
classpath = sourceSets.main.runtimeClasspath + configurations.dev
jvmArgs = ["-Xdebug -agentlib:jdwp=transport=dt_socket,address=8080,server=y,suspend=n"]
}
// run all task
task runAll {}
runAll.dependsOn(bootRun)
Thanks in advance, 提前致谢,
Try a different approach. 尝试不同的方法。 Instead of manually copying the resources, tell Gradle that when it processes resources for the JAR, also take into consideration what is in
frontend/dist/
: 而不是手动复制资源,告诉Gradle当它处理JAR的资源时,还要考虑
frontend/dist/
:
processResources {
from ('frontend/dist/') {
into 'public'
}
}
This should result in a JAR containing a public/
directory, with the contents of frontend/dist/
inside of it. 这应该导致JAR包含一个
public/
目录,其内容为frontend/dist/
。
Gradle configuration for Spring Boot 1.5\\2.x + Angular 2-6 Spring Boot 1.5 \\ 2.x + Angular 2-6的Gradle配置
Angular in sub-folder frontend
子文件夹
frontend
角度
Frontend module 前端模块
Crate build.gradle
: Crate
build.gradle
:
plugins {
id "com.moowork.node" version "1.2.0"
}
node {
version = '8.11.3'
npmVersion = '5.6.0'
download = true
workDir = file("${project.buildDir}/node")
nodeModulesDir = file("${project.projectDir}")
}
task build(type: NpmTask) {
args = ['run', 'build']
}
build.dependsOn(npm_install)
Note for Angular 6 Angular 6的注释
Update outputPath
value in angular.json
to 'dist' 将
angular.json
中的outputPath
值更新为'dist'
Backend module 后端模块
Edit build.gradle
for backend module: 编辑后端模块的
build.gradle
:
Spring Boot 2.X: Spring Boot 2.X:
bootJar {
archiveName = "yourapp.jar"
mainClassName = 'com.company.app.Application'
from('frontend/dist') {
into 'static'
}
}
Spring Boot 1.5.X: Spring Boot 1.5.X:
jar {
archiveName = "yourapp.jar"
manifest {
attributes 'Main-Class': 'com.company.app.Application'
}
from('frontend/dist') {
into 'static'
}
from {
configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }
}
}
Finally execute bootRepackage
or bootJar
task and check results in builds/libs
最后执行
bootRepackage
或bootJar
任务并检查builds/libs
结果
Assume that front end is located at the following folder: src/main/webapp/fe-ui/
, the following solution for the Spring Boot version 2.1.1.RELEASE could be considered: 假设前端位于以下文件夹:
src/main/webapp/fe-ui/
,可以考虑以下Spring Boot版本2.1.1.RELEASE的解决方案:
bootJar {
baseName = 'jar-name'
version = '0.1.0'
from('src/main/webapp/fe-ui/build') {
into 'public'
}
}
task installFeDependencies(type: NpmTask) {
args = ['install']
}
task buildFe(type: NpmTask) {
args = ['run', 'build']
dependsOn installFeDependencies
}
compileJava {
dependsOn buildFe
}
Running gradlew build
will install, build front end as well as will invoke bootJar
. 运行
gradlew build
将安装,构建前端以及将调用bootJar
。 The latter will package built front end bundle. 后者将打包构建的前端捆绑。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.