How to setup angular 4 inside a maven based java w

2019-01-13 04:11发布

问题:

I'm becoming a bit crazy because I can't find a guide to setup an angular 4 app inside a java war project that will be built with maven. This is because I want to run it into a wildfly server.

Any help?

Thanks

回答1:

I had similar requirement to have one source project which has java web-services project as well as angular project(an angular-cli based project) and maven build should create a war with all angular files in it. I used maven-frontend-plugin with few configuration changes for base path.

The goal was to create a war file with all the java code in it plus all the aot compiled angular code in root folder of war, all this with single command mvn clean package.

One more thing for all this to work is to avoid conflict between angular-app router urls and your java application urls, You need to use HashLocationStrategy. one way set it up in app.module.ts like below

app.module.ts -

providers: [
    { provide: LocationStrategy, useClass: HashLocationStrategy },

]

Folder structure for Angular App is below-

angular-project

  • dist
  • e2e
  • node_modules
  • public
  • src
    • app
    • assets
    • environments
    • favicon.ico
    • index.html
    • main.ts
    • polyfills.ts
    • style.css
    • tsconfig.json
    • typings.d.ts
    • etc-etc
  • tmp
  • .angular-cli.json
  • .gitignore
  • karma.conf.js
  • package.json
  • README.md
  • tslint.json
  • etc - etc

Maven Project -

  • src
    • main
      • java
      • resources
      • webapp
        • WEB-INF
        • web.xml
  • angular-project (place your angular project here)
  • node_installation
  • pom.xml

Add maven-frontend-plugin configuration to pom.xml

 <properties>
    <angular.project.location>angular-project</angular.project.location>
    <angular.project.nodeinstallation>node_installation</angular.project.nodeinstallation>
</properties>

 <plugin>
            <groupId>com.github.eirslett</groupId>
            <artifactId>frontend-maven-plugin</artifactId>
            <version>1.0</version>
            <configuration>
                <workingDirectory>${angular.project.location}</workingDirectory>
                <installDirectory>${angular.project.nodeinstallation}</installDirectory>
            </configuration>
            <executions>
                <!-- It will install nodejs and npm -->
                <execution>
                    <id>install node and npm</id>
                    <goals>
                        <goal>install-node-and-npm</goal>
                    </goals>
                    <configuration>
                        <nodeVersion>v6.10.0</nodeVersion>
                        <npmVersion>3.10.10</npmVersion>
                    </configuration>
                </execution>

                <!-- It will execute command "npm install" inside "/e2e-angular2" directory -->
                <execution>
                    <id>npm install</id>
                    <goals>
                        <goal>npm</goal>
                    </goals>
                    <configuration>
                        <arguments>install</arguments>
                    </configuration>
                </execution>
                <!-- It will execute command "npm build" inside "/e2e-angular2" directory 
                    to clean and create "/dist" directory -->
                <execution>
                    <id>npm build</id>
                    <goals>
                        <goal>npm</goal>
                    </goals>
                    <configuration>
                        <arguments>run build</arguments>
                    </configuration>
                </execution>
            </executions>
        </plugin>

        <!-- Plugin to copy the content of /angular/dist/ directory to output 
            directory (ie/ /target/transactionManager-1.0/) -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-resources-plugin</artifactId>
            <version>2.4.2</version>
            <executions>
                <execution>
                    <id>default-copy-resources</id>
                    <phase>process-resources</phase>
                    <goals>
                        <goal>copy-resources</goal>
                    </goals>
                    <configuration>
                        <overwrite>true</overwrite>
                        <!-- This folder is the folder where your angular files 
                        will be copied to. It must match the resulting war-file name.
                        So if you have customized the name of war-file for ex. as "app.war"
                        then below value should be ${project.build.directory}/app/ 
                        Value given below is as per default war-file name -->
                        <outputDirectory>${project.build.directory}/${project.artifactId}-${project.version}/</outputDirectory>
                        <resources>
                            <resource>
                                <directory>${project.basedir}/${angular.project.location}/dist</directory>
                            </resource>
                        </resources>
                    </configuration>
                </execution>
            </executions>
        </plugin>

As above plugin call 'npm run build' internally, make sure package.json should have build command in script like below -

package.json

"scripts": {
    -----//-----,
    "build": "ng build --prod",
   -----//------
}

index.html should always be loaded when someone hit application from browser that's why make it a welcome file . For web services lets say we have path /rest-services/* will explain this later.

web.xml -

<welcome-file-list>
    <welcome-file>index.html</welcome-file>
</welcome-file-list>

<servlet-mapping>
    <servlet-name>restservices</servlet-name>
    <url-pattern>/restservices/*</url-pattern>
</servlet-mapping>

The above configuration is enough if your application does not have any context path and is deployed on root path on server. But if your application has any context path like http://localhost:8080/myapplication/ then make changes to index.html file as well -

angular-project/src/index.html - Here document.location will be myapplication/ (the context path of your app otherwise / if application has no context path )

The purpose of making context path a base path for angular-app is that whenever you make ajax http call from angular, it will prepend base path to url. for example if i try to call 'restservices/persons' then it will actually make calls to 'http://localhost:8080/myapplication/restservices/persons'

index.html

 <!doctype html>
 <html lang="en">
 <head>
   <meta charset="utf-8">
   <title>E2E</title>
   <script>document.write('<base href="' + document.location + '" />');     </script>

   <meta name="viewport" content="width=device-width, initial-scale=1">
   <link rel="icon" type="image/x-icon" href="favicon.ico">
 </head>
 <body>
   <app-root></app-root>
 </body>

After all above changes once you run mvn clean package it will create required war. Check if all the content of angular 'dist' folder is in root of war file.



回答2:

I have a similar issue : I have a maven web application module named Tourism-Services containing the web services and a maven project containing the angular project (I created the angular project with CLI in the src/main/angular5/tourism folder)

contrary to this post and accordingly to the following link (how to integrate Angular 2 + Java Maven Web Application) that was given by Parth Ghiya, I think that The angular project should be placed in the webapp folder of Tourism-Services module project. Considering this I have further questions :

  1. Normally, all the compilation result in dist folder should be placed under webapp folder. But in dist folder, there are not all the Angular project ressources (as images, css that should be present in angular assets folder, am I right ?)

  2. Considering the angular dependencies that are in node_modules, should we integrate them also in webapp folder ? There is one obstacle : first there are Typescript files and sould be also compiled to be interprated by the server, but maybe there are compiled and added when they are imported in the custom application angular files ? What is the solution ?

  3. Should we includes other type of ressources coming from the angular project in webapp folder ? (like typings folder as suggested Scrambo in the above link post)