nidhi
nidhi

Reputation: 329

How to deploy angular 6 project and spring boot project as a single deployment unit

I have two projects one is Angular Project(Front End Application ) and another one is Spring boot (Rest Api's). When I run both the projects individually everything works fine. But now I want to generate a single runnable jar file for both these projects in such a way that when i run the jar in the localhost:8081 it should up both the Angular module as well as spring boot module.

I've added the following plugin to my pom.xml file

<plugin>
                <artifactId>maven-resources-plugin</artifactId>
                <executions>
                    <execution>
                        <id>copy-resources</id> 
                        <phase>validate</phase> 
                        <goals>
                            <goal>copy-resources</goal>
                        </goals>                          
                        <configuration>                                   
                            <outputDirectory>${build.directory}/classes/static/</outputDirectory >
                            <resources>
                                <resource>
                                    <directory>../angular6-MyProject/dist</directory>
                                </resource>
                            </resources>
                        </configuration>
                    </execution>
                </executions>
        </plugin>

Upvotes: 0

Views: 10894

Answers (3)

Sameer Mujawar
Sameer Mujawar

Reputation: 9

The back-end server uses Spring Boot with Spring Web MVC for REST Controller and Spring Data JPA for interacting with MySQL database. Front-end side is made with Angular 11, HTTP Client & Router.

– Spring Boot exports REST APIs using Spring Web MVC & interacts with MySQL Database using Spring Data JPA.

– Angular Client sends HTTP Requests and retrieve HTTP Responses using axioms, shows data on the components. We also use Angular Router for navigating to pages.

Steps to follow to set up Angular 11 with Spring Boot Application.

  1. Create Angular 11 Application to run and build successfully.

  2. Create build according to environment like QA, PROD, LOCAL.

  3. from dist. folder collect compiled files through node-js.

  4. Angular runs on node server by using typescript. once you compile code and build angular project in dist. folder you will get .js files. java script files.

  5. We can you as it is js files from dist folder to run any UI application.

  6. Create Spring boot application and write REST apis and compile and build successfully.

  7. create static folder in resource folder.

  8. put static folder path inside application.properties like classpath:"resource/static/".

  9. put all compiled js file in to static folder from dist folder.

  10. create webConfig.java file in spring boot project to routing URL for index.html.

  11. Create build nd compile successfully spring boot project.

  12. if you run the project you will get UI from spring boot project.

  13. Create jar from spring boot project.

  14. Deploy on Azure and run the project successfully.

thank you you can visit my blog for in details.

https://draft.blogger.com/blog/post/edit/preview/8320325077779788397/7601438449518293236

Upvotes: 0

Noel R.
Noel R.

Reputation: 143

I followed this tutorial and it's somehow similar to what Jakub mentioned in his answer. I usually run the mvn spring-boot:run command to launch it in one go. The key to setting up the project is in the pom.xml. Make sure that you are telling the build to copy the Angular dist/ files into the right place. In this case, it needs to copy the compiled JS from Angular's dist/ folder to the server/target/classes/resources so it can host the static content.

The entire build (mvn clean install) can take forever. So during development I just go to the src/main/web directory and run ng-serve from there so I can see my UI changes quickly.

Hope this helps.

Upvotes: 0

Jakub Marchwicki
Jakub Marchwicki

Reputation: 868

Quick answer

You need to copy static files to ${build.directory}/classes/META-INF/resources folder for the servlet container serve them as static files from inside a war/jar file (that's how https://www.webjars.org work).

Handling HTML directly from jar

In the Static Content section of Spring Boot documentation you can find

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

The /META-INF/resources is the "standard" way (though not most intuitive) and it comes directly from the Java Servlet Specification 3.0 (from JavaEE version 6)

A Web application exists as a structured hierarchy of directories. The root of this hierarchy serves as the document root for files that are part of the application. For example, for a Web application with the context path /catalog in a Web container, the index.html file at the base of the Web application hierarchy or in a JAR file inside WEB-INF/lib that includes the index.html under META-INF/resources directory can be served to satisfy a request from /catalog/index.html.

Therefore, setting an appropriate path should do the job.

Treating Angular application as a dependency

The quoted JavaEE spec is also what webjars utilize. Webjars are client-side dependencies packaged into JAR archive files. The primary reason for webjars to exist is to avoid adding and managing client-side dependencies (like Angular, jQuery), which often results in hard to maintain codebases.

But if the Angular can be a webjar, your frontend can be as well. What I tend to do is to pack the Angular application as a jar file and treat it as a dependency.

Frontend application

Driven npm from Maven + create Jar file

<project>

    <groupId>com.examplegroupId>
    <artifactId>myapp-ui</artifactId>
    <packaging>jar</packaging>

    <build>
        <plugins>
           <!-- run the frontend (npm / bower stack) and update dependencies -->
            <plugin>
                <groupId>com.github.eirslett</groupId>
                <artifactId>frontend-maven-plugin</artifactId>
                <configuration>
                    <installDirectory>target</installDirectory>
                </configuration>
                <executions>
                    <execution>
                        <id>install node and npm</id>
                        <goals>
                            <goal>install-node-and-npm</goal>
                        </goals>
                        <phase>generate-resources</phase>
                        <configuration>
                            <nodeVersion>v8.9.1</nodeVersion>
                            <npmVersion>5.5.1</npmVersion>
                        </configuration>
                    </execution>
                    <execution>
                        <id>npm install</id>
                        <goals>
                            <goal>npm</goal>
                        </goals>
                        <phase>generate-resources</phase>
                        <configuration>
                            <arguments>install</arguments>
                        </configuration>
                    </execution>
                    <execution>
                        <id>npm build</id>
                        <goals>
                            <goal>npm</goal>
                        </goals>
                        <phase>generate-resources</phase>
                        <configuration>
                            <arguments>run build</arguments>
                        </configuration>
                    </execution>
                </executions>
            </plugin>

            <!-- copy everything as a webjar -->
            <plugin>
                <artifactId>maven-resources-plugin</artifactId>
                <executions>
                    <execution>
                        <id>copy-resources</id>
                        <phase>process-resources</phase>
                        <goals>
                            <goal>copy-resources</goal>
                        </goals>
                        <configuration>
                            <outputDirectory>${basedir}/target/classes/META-INF/resources</outputDirectory>
                            <resources>
                                <resource>
                                    <directory>dist/</directory>
                                </resource>
                            </resources>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

Backend application

Use the dependency directly

<dependencies>
    <dependency>
        <groupId>com.example<groupId>
        <artifactId>myapp-ui</artifactId>
    </dependency>
</dependencies>

Notices

Some issues and observations I've seen with webjars:

  • I've seen some problems with webjars and web fonts (fonts not being load by the browser when served from inside the jar file)
  • There are ways to build webjars using npm tools and all packages I've seen require and use java underneath anyway. I haven't seen any native JS solution
  • Webjars themselves don't impact the performance of an application, however serving static content from Servlet container is always significantly less performant (regarding possible throughput) than serving it from say nginx

Upvotes: 3

Related Questions