J'ai un projet Spring Boot + Angular 2. Je souhaite le déployer sur Heroku. Je peux exécuter la version npm, puis copier manuellement les fichiers générés dans le dossier public (src/resources/public), puis exécuter la version du backend. .] Ce que je veux faire, c'est mettre en place une construction graduelle qui fera tout cela en même temps. Ce que j’ai jusqu’à présent, c’est une construction gradle qui construira le front-end, le backend, mais ne copie pas les fichiers statiques avant la génération du fichier jar. Comme le pot ne contient pas de fichiers statiques, cela ne fonctionnera pas sur Heroku.
Voici la structure du dossier de projet:
root
backend
src/main/Java
src/main/resources
frontend
--> angular files go here
build/libs -> where the JAR file goes
Le fichier de construction 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)
Merci d'avance,
Essayez une approche différente. Au lieu de copier manuellement les ressources, indiquez à Gradle que, lorsqu’il traite des ressources pour le fichier JAR, tenez également compte du contenu de frontend/dist/
:
processResources {
from ('frontend/dist/') {
into 'public'
}
}
Cela devrait aboutir à un fichier JAR contenant un répertoire public/
, avec le contenu de frontend/dist/
à l'intérieur.
Configuration de Gradle pour Spring Boot 1.5\2.x + Angular 2-6
Angulaire dans le sous-dossier frontend
Module frontend
Caisse 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 pour Angular 6
Mettez à jour la valeur outputPath
dans angular.json
en 'dist'
Module Backend
Editez build.gradle
pour le module backend:
Spring Boot 2.X:
bootJar {
archiveName = "yourapp.jar"
mainClassName = 'com.company.app.Application'
from('frontend/dist') {
into 'static'
}
}
Botte à ressort 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) }
}
}
Enfin, exécutez la tâche bootRepackage
ou bootJar
et vérifiez les résultats dans builds/libs
Supposons que l'interface frontale se trouve dans le dossier suivant: src/main/webapp/fe-ui/
, la solution suivante pour la version 2.1.1.RELEASE de Spring Boot peut être envisagée:
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
}
Lancer gradlew build
installera, construira front end et invoquera bootJar
. Ce dernier conditionnera le paquet frontal construit.