47

I am a newbie with Angular2. My project's technical stack is Angular2 with typescript and spring as backend. I don't want to use node server as directed to compile my frontend but I will need to use TOMCAT and Maven instead. I have a few questions.

  1. I guess node server generates .js and .js.map for every .ts files since browser only understand .js files. Is my understanding correct? How can I accomplish this task using Maven and Tomcat?
  2. I would like to build my application from scratch using Maven. I will prefer bower as the frontend task manager.

Can anyone give me a step by step guide to create an Angular2 + Spring application using 'bower or any other tools for frontend task management such as minification of files, creating application scaffold' and 'Maven for backend task management'? I am open for any suggestions.

hennr
  • 2,632
  • 2
  • 23
  • 26
Gendaful
  • 5,522
  • 11
  • 57
  • 76
  • 1
    The typescript compiler (tsc) generates the .js and map files, not node.js. Once you have your js, css, html, etc. you serve them up just like you would any other web site. – rgvassar Feb 29 '16 at 17:39

2 Answers2

34

I'm using typescript .ts files in my Angular 2 + Spring Boot application with maven. I run npm install for dependencies and npm run tsc for converting .ts files to .js by exec-maven-plugin.

Below is the plugin portion from my pom.xml. In my application, pacakge.json, tsconfig.json and typings.json all under src/main/resources path, so run npm tasks under the path

pom.xml

<parent>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-parent</artifactId>
     <version>1.3.5.RELEASE</version>
</parent>

<packaging>war</packaging>


<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <configuration>
                <source>1.8</source>
                <target>1.8</target>
            </configuration>
        </plugin>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
        <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>exec-maven-plugin</artifactId>
            <executions>
                <execution>
                    <id>exec-npm-install</id>
                    <phase>generate-sources</phase>
                    <configuration>
                        <workingDirectory>${project.basedir}/src/main/resources</workingDirectory>
                        <executable>npm</executable>
                        <arguments>
                            <argument>install</argument>
                        </arguments>
                    </configuration>
                    <goals>
                        <goal>exec</goal>
                    </goals>
                </execution>
                <execution>
                    <id>exec-npm-run-tsc</id>
                    <phase>generate-sources</phase>
                    <configuration>
                        <workingDirectory>${project.basedir}/src/main/resources</workingDirectory>
                        <executable>npm</executable>
                        <arguments>
                            <argument>run</argument>
                            <argument>tsc</argument>
                        </arguments>
                    </configuration>
                    <goals>
                        <goal>exec</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>

My Angular2 + Spring Boot application folder structure is like below

src/main/resources
                  /app          - .ts and converted .js
                  /css
                  /images
                  /js           - systemjs.config.js is also placed here
                  /node_modules - generated by npm install and will include in war
                  /typings
                  application.properties
                  package.json
                  tsconfig.json
                  typings.json

src/main/webapp
               /WEB-INF
                       /jsp     - all .jsp files

On .jsp file head section, include the systemjs.config.js

<script type="text/javascript" src="webjars/zone.js/0.6.12/dist/zone.js"></script>
<script type="text/javascript" src="webjars/reflect-metadata/0.1.3/Reflect.js"></script>
<script type="text/javascript" src="webjars/systemjs/0.19.27/dist/system.js"></script>
<script type="text/javascript" src="js/systemjs.config.js"></script>

Also here is my WebMvcConfigurerAdapter code to mapping path

@Configuration
@EnableWebMvc
@ComponentScan(basePackages = "com.my.controller")
public class WebConfig extends WebMvcConfigurerAdapter {

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        if (!registry.hasMappingForPattern("/webjars/**")) {
            registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
        }
        if (!registry.hasMappingForPattern("/images/**")) {
            registry.addResourceHandler("/images/**").addResourceLocations("classpath:/images/");
        }
        if (!registry.hasMappingForPattern("/css/**")) {
            registry.addResourceHandler("/css/**").addResourceLocations("classpath:/css/");
        }
        if (!registry.hasMappingForPattern("/js/**")) {
            registry.addResourceHandler("/js/**").addResourceLocations("classpath:/js/");
        }
        if (!registry.hasMappingForPattern("/app/**")) {
            registry.addResourceHandler("/app/**").addResourceLocations("classpath:/app/");
        }
        if (!registry.hasMappingForPattern("/node_modules/**")) {
            registry.addResourceHandler("/node_modules/**").addResourceLocations("classpath:/node_modules/");
        }
    }

    @Bean
    public InternalResourceViewResolver internalViewResolver() {
        InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
        viewResolver.setPrefix("/WEB-INF/jsp/");
        viewResolver.setSuffix(".jsp");
        viewResolver.setOrder(1);
        return viewResolver;
    }
}

One thing I want to mention is there some hack on running the exec-maven-plugin on eclipse if the os is Windows or Mac. Linux(Ubuntu) looks no issue at all. When run the build from eclipse on Windows or Mac, the problem is it doesn't understand npm command and try to find such file, even though the maven build is totally fine on Terminal or Command Window.

To solve such issue, I did some tweak. For Mac, making symbolic link for node and npm under /usr/bin path like below. However modifying /usr/bin is not allowed, so I done after rebooting by recovery disk

lrwxr-xr-x     1 root   wheel        17 May 22 03:01 node -> ../local/bin/node
lrwxr-xr-x     1 root   wheel        44 May 22 02:50 npm -> ../local/lib/node_modules/npm/bin/npm-cli.js

For Windows, I made node.bat and npm.bat file under system path like below After doing this, the maven build totally fine from eclipse and command window both on Windows 10.

npm.bat

@echo off
set arg1=%1
set arg2=%2
set arg3=%3
set arg4=%4
C:\Progra~1\nodejs\npm.cmd %arg1% %arg2% %arg3% %arg4%
Steve Park
  • 1,979
  • 27
  • 33
  • 1
    But if you include node_modules you war will be very huge, isn't it? – Mark T Jul 25 '16 at 20:03
  • 1
    Yes, war file will be bigger. My spring boot app was originally using webjar which was also included in war file and designed to be distributed. But you could setup node_module for web server and reverse proxy it. – Steve Park Jul 25 '16 at 20:20
  • I understand you can user bower to reduce the size and include only what you want, but I don't know I understood it right – Mark T Jul 25 '16 at 20:32
  • I was saying one extreme way. Setup node_module path is available as url on an app server (ex. apache Location and Alias setup, so the file path is available as url), then your app will use the url path to get the .js and .css. But this needs extra workflow to update the node_module, since it is outside of build process – Steve Park Jul 25 '16 at 20:48
  • 1
    in version 1.5 of exec-maven-plugin you should use `npm.cmd` instead of `npm`. And than it works fine in IntelliJ on windows without any .bat file. – Daniel Stradowski Aug 10 '16 at 06:09
  • You saved me lots of hours. Thank you very much Steve. – ozeray Dec 03 '16 at 23:05
  • Somebody may be insterested: in AngularJs 2, you may use: ng.cmd build in Windows, instead of using npm run tsc. This will compile your all typescript and some other static files into dist folder. – ozeray Dec 03 '16 at 23:07
  • The reason call npm instead of npm.cmd is to build the project regardless of environment OS. Our jenkins is run on Oracle Linux, but some of developers are on windows, Ubuntu and Mac. npm.cmd is only for windows – Steve Park Sep 07 '17 at 01:47
3

The typescript files, ending in .ts, are compiled with the typescript compiler, not node.js. They are compleatly separate, take a look at http://www.typescriptlang.org/ for more info on typescript itself.

To use Angular2, you don't really need to use typescript, you could write plain old Javascript. Even though the Angular2 team is using Typescript to create the framework.

So to answer your first question, neither are involved. You create your HTML, CSS and Javascript however you want.

As for using bower, Angular2 doesn't actually exist on bower officially, only npm. You can see the discussion behind this here https://github.com/angular/angular/issues/4018. As they say in the discussion you can use the GitHub endpoint if you truly wish to use bower.

bakoyaro
  • 2,550
  • 3
  • 36
  • 63
Namirna
  • 402
  • 2
  • 12
  • Thanks Namirna for your inputs. I am looking for some alternative tools to setup my project which has Angular2 and Spring. Since Bower is not an option for Angular2, i was wondering if there are any other tools which has good integration with Maven? – Gendaful Feb 29 '16 at 22:29
  • Npm is taking over the world it seems :) I haven't looked at its integration with Maven but I can't believe that it isn't there since npm is literally everywhere and more or less the de facto standard for dependencies in web development today... And doing a very very quick google search I find plugins – Namirna Mar 01 '16 at 11:11