Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular and Spring Boot : configuration to make them work together efficiently

Angular projet build relies on the Angular CLI tool.
Spring boot project build relies on the Spring Boot Maven Plugin.

So how to configure and build a Spring Boot application that hosts an Angular Application on the front-end ?

My requirements are the following :

  • using Maven as Java build tool

  • running the application in a embedded Tomcat instance bootstrapped by Spring Boot.

  • efficient build lifecycle in development environment

  • reliable build for post-development environment

like image 906
davidxxx Avatar asked Mar 08 '23 18:03

davidxxx


1 Answers

Angular Configuration

First, I need to configure the Angular application to make the build of the Angular application available in the source code directory of the Spring Boot Maven project.

A simple way to do it requires 2 simple changes :

  • moving the angular application folder in the root folder of the Spring Boot Maven project.

  • modifying the .angular-cli.json configuration file to change the apps/outDir value that is "dist" by default, by "../src/main/resources/static".

That is :

{
  ...
  "apps": [
    {
      "root": "src",
      "outDir": "../src/main/resources/static",
  ...
}

By default Spring Boot serves static content from a directory called /static (or /public or /resources or /META-INF/resources) in the classpath or from the root of the ServletContext.

In this way, as I execute the ng build command, the angular application bundled by Webpack will be located in the resource directory for static contents of Spring Boot.


Spring Boot configuration

I don't want to perform exactly the same Spring Boot build tasks in development and in post-development environments.
Of course, it doesn't mean that the builds will produce a distinct functional behavior according to the target environments.

In development, I want to have a fast build.
As I modify the source code (Java, JavaScript or anything else), I want a fast feedback. I don't want to package and redeploy the application at each source code modification for example.
I don't want to do some special things at each time the source code is changed either.
I want that changes be reflected in the application fast and automatically.

To build the application for post-development environments, I want to have a reliable build and that contains the final content.
Here the detailed requirements for the post-development environments :

  • I want to perform a full build from scratch of the Angular application (and even of the overall Spring Boot application).
    Incremental updates of the webpack bundled application at each source code modification is fine during development but as I deliver my application, I will really reduce potential side effects at its maximum.
    I don't care if I have to package the application from scratch as I don't create this build frequently and I also leave this task to automatic tools such as the continuous integration.

  • I want to repackage the application in a way where it is autonomous by running itself an embedded Tomcat that deploys it.
    The repackage goal of Spring Boot Maven plugin achieves it.

To be able to switch in a clean/reliable way from a type of build to another one, I want to specify two distinct builds.

Maven (as Gradle) provides a build profile feature that addresses very well this requirement.
So, I use it.

Here is the Maven profile for the development build :

<profile>
    <id>fast-build</id>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <jvmArguments>
                        -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005
                    </jvmArguments>
                    <addResources>true</addResources>
                </configuration>
            </plugin>
        </plugins>
    </build>
</profile>

Some additional notes :

  • In development, I want always have a way to add a break point if I need and without restarting the application.
    The jvmArguments argument of the Spring Boot Maven plugin valued in this way :

    <jvmArguments> -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005 </jvmArguments>

specifies 5005 as port for the debugger listener without being blocking (suspend=n) for the server.

  • To enable the hot refreshing of static resources, I set the addResources to true.

Here is the Maven profile for the post-development build (plus declared properties used by it) :

<properties>
    ...
    <node.version>v6.9.1</node.version>
    <npm.version>3.10.8</npm.version>
    ...
</properties>
    ...
    <profile>
        <id>full-build</id>
        <activation>
            <activeByDefault>true</activeByDefault>
        </activation>
        <build>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                    <executions>
                        <execution>
                            <goals>
                                <goal>repackage</goal>
                            </goals>
                        </execution>
                    </executions>
                </plugin>
                <plugin>
                    <groupId>com.github.eirslett</groupId>
                    <artifactId>frontend-maven-plugin</artifactId>
                    <version>1.2</version>
                    <configuration>
                        <installDirectory>angular-app</installDirectory>
                        <workingDirectory>angular-app</workingDirectory>
                    </configuration>
                    <executions>
                        <execution>
                            <id>install node and npm</id>
                            <goals>
                                <goal>install-node-and-npm</goal>
                            </goals>
                            <configuration>
                                <nodeVersion>${node.version}</nodeVersion>
                                <npmVersion>${npm.version}</npmVersion>
                            </configuration>
                        </execution>
                        <execution>
                            <id>install angular app</id>
                            <goals>
                                <goal>npm</goal>
                            </goals>
                            <configuration>
                                <arguments>install</arguments>
                            </configuration>
                        </execution>                            
                        <execution>
                            <id>npm build</id>
                            <goals>
                                <goal>npm</goal>
                            </goals>
                            <configuration>
                                <arguments>run build</arguments>
                            </configuration>
                        </execution>
                    </executions>
                </plugin>
            </plugins>
        </build>
    </profile>

Some additional notes :

  • angular-app declared here : <workingDirectory>angular-app</workingDirectory> is the directory of the angular application that I copied in the Maven Spring Boot project.

  • <installDirectory>angular-app</installDirectory> is the working folder where the frontend-maven-plugin will install node and required dependencies.
    In itself, the angular-app directory is not directly used to generate the packaged application.
    So using this directory is fine and also allows to run the angular application from Angular CLI.


Angular and Spring Boot command to run the builds

  • For development build :

    • Angular CLI : from the angular-app directory, execute ng build -w. It will build the Angular application and also update incrementally the build (w for watch)
    • Spring Boot : from the base directory of the maven project, execute mvn spring-boot:run -Pfast-build (a script that executes it is welcome)
  • For post-development build :

    • Angular CLI is not required.
    • Spring Boot : from the base directory of the maven project, execute mvn spring-boot:run
like image 194
davidxxx Avatar answered Mar 10 '23 07:03

davidxxx