<Tech>Brunch


Integrating Node Related Modules With Maven

Angular CLI gives so much flexibility when we are developing Angular applications. So much of boiler plate code gets auto generated if you are using CLI.
What if we require Angular app to get integrated with existing Maven project?

Angular CLI and its command run in the Node environment. The Node environment is very much different from Maven environment.
In Maven, each module describes itself in a pom.xml including its dependencies and the build plugins. Build plugins attach to the project’s lifecycle and execute required tasks and commands. A module may have multiple sub modules and, obviously, a sub module references its parent module. Dependencies are installed to a local Maven repository on the user’s machine.

In Node environment, whether the package manager is npm, yarn or pnpm—dependencies are listed in a package.json. Running the package manager’s install command, e.g. yarn install, resolves dependencies, extracts tarballs from a registry and copies a flattened dependency tree to a local node_modules folder.

The major difference that is quite evident is, a local node_modules folder is on a per-package basis. On the other side, a local Maven repository is on a per-user basis and stores resolvable dependencies.

We have a Frontend Maven Plugin which enables to run Node and related package managers through Maven. The important thing here is that it makes sharing of one node_modules folder across several Maven modules.

In order to make use of this plugin, we need to update our parent pom to have this frontend maven plugin. A sample pom.xml making use of this plugin would be like below. In the similar manner we can have executables for yarn, grunt etc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
<plugin>
<groupId>com.github.eirslett</groupId>
<artifactId>frontend-maven-plugin</artifactId>
<version>@project.version@</version>
<executions>
<execution>
<id>install node and npm</id>
<goals>
<goal>install-node-and-npm</goal>
</goals>
<configuration>
<nodeVersion>v5.3.0</nodeVersion>
<npmVersion>3.3.12</npmVersion>
</configuration>
</execution>
<execution>
<id>npm install</id>
<goals>
<goal>npm</goal>
</goals>
<!-- Optional configuration which provides for running any npm command -->
<configuration>
<arguments>install</arguments>
</configuration>
</execution>
<execution>
<id>npm run build</id>
<goals>
<goal>npm</goal>
</goals>
<configuration>
<arguments>run build</arguments>
</configuration>
</execution>
<execution>
<id>grunt build</id>
<goals>
<goal>grunt</goal>
</goals>
<configuration>
<arguments>--no-color</arguments>
</configuration>
</execution>
</executions>
</plugin>

The plugin has been designed to use a local installation of node. But in my case, even though I had the node installed on my machine, on the first run of ‘install’ it did download executable node. On subsequent runs, as the executable node was already present in the dependencies, it used that one. But I am wondering why it had do download the executable on the first run of install, as my system already had Node installed and configured.
Please let me know in case you know why the plugin behaved this way.