Normally, when working with the Node.js project, we usually ignore the node_modules directory, which is used to store Node.js dependencies, when committed to source code management systems such as Git, SVN because it’s not necessary. You can use the “npm install” command to install dependencies when you want to run the application on your machine. But one problem is that when you want to deploy CI/CD to your Node.js project, you need everything ready to deploy the application to production, how to automatically install the Node. .js dependencies for this? If your project uses Apache Maven, you can use a plugin called frontend-maven-plugin to do this. How is it in details? Let’s find out in this tutorial.
First, I will create a new Maven project as an example:
Next, I will declare using the frontend-maven-plugin plugin as follows:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.huongdanjava</groupId> <artifactId>maven-nodejs</artifactId> <version>0.0.1-SNAPSHOT</version> <build> <plugins> <plugin> <groupId>com.github.eirslett</groupId> <artifactId>frontend-maven-plugin</artifactId> <version>1.6</version> </plugin> </plugins> </build> </project> |
The first thing you need to know about the frontend-maven-plugin plugin is that it allows us to install Node.js into our project. This means you do not have to install Node.js on your machine.
To do this, first you need to configure the version of Node.js that you need to install:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.huongdanjava</groupId> <artifactId>maven-nodejs</artifactId> <version>0.0.1-SNAPSHOT</version> <build> <plugins> <plugin> <groupId>com.github.eirslett</groupId> <artifactId>frontend-maven-plugin</artifactId> <version>1.6</version> <configuration> <nodeVersion>v9.9.0</nodeVersion> </configuration> </plugin> </plugins> </build> </project> |
then add the execution part with goal “install-node-and-npm” as follows:
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 |
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.huongdanjava</groupId> <artifactId>maven-nodejs</artifactId> <version>0.0.1-SNAPSHOT</version> <build> <plugins> <plugin> <groupId>com.github.eirslett</groupId> <artifactId>frontend-maven-plugin</artifactId> <version>1.6</version> <configuration> <nodeVersion>v9.9.0</nodeVersion> </configuration> <executions> <execution> <id>install node</id> <goals> <goal>install-node-and-npm</goal> </goals> </execution> </executions> </plugin> </plugins> </build> </project> |
At this point, if you run “mvn install”, you will see the results as follows:
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 46 47 |
[INFO] Scanning for projects... [INFO] [INFO] ------------------------------------------------------------------------ [INFO] Building maven-nodejs 0.0.1-SNAPSHOT [INFO] ------------------------------------------------------------------------ [INFO] [INFO] --- frontend-maven-plugin:1.6:install-node-and-npm (install node) @ maven-nodejs --- [INFO] Installing node version v9.9.0 [INFO] Downloading https://nodejs.org/dist/v9.9.0/node-v9.9.0-darwin-x64.tar.gz to /Users/Khanh/.m2/repository/com/github/eirslett/node/9.9.0/node-9.9.0-darwin-x64.tar.gz [INFO] No proxies configured [INFO] No proxy was configured, downloading directly [INFO] Unpacking /Users/Khanh/.m2/repository/com/github/eirslett/node/9.9.0/node-9.9.0-darwin-x64.tar.gz into /Users/khanh/Working/Workspace Eclipse/maven-nodejs/node/tmp [INFO] Copying node binary from /Users/khanh/Working/Workspace Eclipse/maven-nodejs/node/tmp/node-v9.9.0-darwin-x64/bin/node to /Users/khanh/Working/Workspace Eclipse/maven-nodejs/node/node [INFO] Extracting NPM [INFO] Installed node locally. [INFO] [INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ maven-nodejs --- [WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent! [INFO] Copying 0 resource [INFO] [INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ maven-nodejs --- [INFO] Nothing to compile - all classes are up to date [INFO] [INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ maven-nodejs --- [WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent! [INFO] Copying 0 resource [INFO] [INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ maven-nodejs --- [INFO] Nothing to compile - all classes are up to date [INFO] [INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ maven-nodejs --- [INFO] [INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ maven-nodejs --- [INFO] Building jar: /Users/khanh/Working/Workspace Eclipse/maven-nodejs/target/maven-nodejs-0.0.1-SNAPSHOT.jar [INFO] META-INF/maven/com.huongdanjava/maven-nodejs/pom.xml already added, skipping [INFO] META-INF/maven/com.huongdanjava/maven-nodejs/pom.properties already added, skipping [INFO] [INFO] --- maven-install-plugin:2.4:install (default-install) @ maven-nodejs --- [INFO] Installing /Users/khanh/Working/Workspace Eclipse/maven-nodejs/target/maven-nodejs-0.0.1-SNAPSHOT.jar to /Users/Khanh/.m2/repository/com/huongdanjava/maven-nodejs/0.0.1-SNAPSHOT/maven-nodejs-0.0.1-SNAPSHOT.jar [INFO] Installing /Users/khanh/Working/Workspace Eclipse/maven-nodejs/pom.xml to /Users/Khanh/.m2/repository/com/huongdanjava/maven-nodejs/0.0.1-SNAPSHOT/maven-nodejs-0.0.1-SNAPSHOT.pom [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 20.322 s [INFO] Finished at: 2018-06-30T20:17:39+07:00 [INFO] Final Memory: 16M/55M [INFO] ------------------------------------------------------------------------ |
As you can see, the frontend-maven-plugin plugin automatically downloads the version of Node.js we have declared in the <configuration> section from https://nodejs.org/dist/v9.9.0/node- v9.9.0-darwin-x64.tar.gz, then extract the downloaded file to copy the Node.js binary file as “node” into our project directory. A node directory has been created and the file “node” is contained in this directory. The “npm” library has also been downloaded and is located in the node_modules directory of the node directory:
We can change the default directory, the project directory, to another directory in our project. For example, if you want to install Node.js in the target directory of the project, you can add the “installDirectory” configuration as follows:
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 |
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.huongdanjava</groupId> <artifactId>maven-nodejs</artifactId> <version>0.0.1-SNAPSHOT</version> <build> <plugins> <plugin> <groupId>com.github.eirslett</groupId> <artifactId>frontend-maven-plugin</artifactId> <version>1.6</version> <configuration> <nodeVersion>v9.9.0</nodeVersion> <installDirectory>target</installDirectory> </configuration> <executions> <execution> <id>install node</id> <goals> <goal>install-node-and-npm</goal> </goals> </execution> </executions> </plugin> </plugins> </build> </project> |
Run again “mvn install”, you will see the results as follows:
By default, the working directory of Node.js when we use the frontend-maven-plugin as we said above will be the directory of the project.
This means we are going to write code for the Node.js project in this directory and therefore the package.json file, which declares the dependencies that the Node.js project uses, will also be in this directory.
Suppose I now create a package.json file for example with the following content;
1 2 3 4 5 6 7 8 |
{ "name": "maven-nodejs", "version": "1.0.0", "description": "An example of using frontend-maven-plugin", "dependencies": { "express": "^4.16.3" } } |
To be able to install the dependencies declared in this package.json file, we need to declare a new execution with the goal “npm” in the pom.xml file as follows:
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 |
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.huongdanjava</groupId> <artifactId>maven-nodejs</artifactId> <version>0.0.1-SNAPSHOT</version> <build> <plugins> <plugin> <groupId>com.github.eirslett</groupId> <artifactId>frontend-maven-plugin</artifactId> <version>1.6</version> <configuration> <nodeVersion>v9.9.0</nodeVersion> <installDirectory>target</installDirectory> </configuration> <executions> <execution> <id>install node</id> <goals> <goal>install-node-and-npm</goal> </goals> </execution> <execution> <id>npm install</id> <goals> <goal>npm</goal> </goals> </execution> </executions> </plugin> </plugins> </build> </project> |
Now if you run “mvn install”, you will see in the project directory that the node_modules directory contains all the dependencies that we declared in the package.json file and its dependencies as follows:
We can also change the default working directory of Node.js by adding the “workingDirectory” configuration. For example, now I create a folder named “frontend” in the “src/main” directory, move the package.json file above to this directory and configure “workingDirectory” as follows:
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 |
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.huongdanjava</groupId> <artifactId>maven-nodejs</artifactId> <version>0.0.1-SNAPSHOT</version> <build> <plugins> <plugin> <groupId>com.github.eirslett</groupId> <artifactId>frontend-maven-plugin</artifactId> <version>1.6</version> <configuration> <nodeVersion>v9.9.0</nodeVersion> <installDirectory>target</installDirectory> <workingDirectory>src/main/frontend</workingDirectory> </configuration> <executions> <execution> <id>install node</id> <goals> <goal>install-node-and-npm</goal> </goals> </execution> <execution> <id>npm install</id> <goals> <goal>npm</goal> </goals> </execution> </executions> </plugin> </plugins> </build> </project> |
Run again “mvn install”, you will see the results as follows: