web-dev-qa-db-fra.com

Comment ajouter des fichiers statiques à jar en utilisant la construction Gradle dans Spring Boot + Angular 2 projet

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,

5
fpezzini

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.

13
nickb

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

4
Evgeny Lebedev

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.

0
mr.M