]> juplo.de Git - website/blob
eacc59cdb577d2c91e2be4c8d15de32dff2d3e3d
[website] /
1 ---
2 _edit_last: "2"
3 author: kai
4 categories:
5   - bootstrap
6   - css
7   - grunt
8   - java
9   - less
10   - maven
11   - nodejs
12   - spring
13   - thymeleaf
14 date: "2015-08-26T11:57:43+00:00"
15 guid: http://juplo.de/?p=509
16 parent_post_id: null
17 post_id: "509"
18 title: Integrating A Maven-Backend- With A Nodjs/Grunt-Fronted-Project
19 url: /integrating-a-maven-backend-with-a-nodjsgrunt-fronted-project/
20
21 ---
22 ## Frontend-Development With Nodjs and Grunt
23
24 As I already wrote in [a previous article](/serve-static-html-with-nodjs-and-grunt/ "Serving Static HTML With Nodjs And Grunt For Template-Development"), frontend-development is mostly done with [Nodjs](https://nodejs.org/ "Read more about nodjs") and [Grunt](http://gruntjs.com/ "Read more about grunt") nowadays.
25 As I am planing to base the frontend of my next Spring-Application on [Bootstrap](http://getbootstrap.com/ "Read more about Bootstrap"), I was looking for a way to integrate my backend, which is build using [Spring](http://projects.spring.io/spring-framework/ "Read more about the Springframework") and [Thymeleaf](http://www.thymeleaf.org/ "Read more about Thymeleaf") and managed with Maven, with a frontend, which is based on Bootstrap and, hence, build with Nodjs and Grunt.
26
27 ## Integrate The Frontend-Build Into The Maven-Build-Process
28
29 As I found out, one can integrate a npm-based build into a maven project with the help of the [frontend-maven-plugin](https://github.com/eirslett/frontend-maven-plugin "Read more about the frontend-maven-plugin").
30 This plugin automates the managment of Nodjs and its libraries and ensures that the version of Node and NPM being run is the same in every build environment.
31 As a backend-developer, you do not have to install any of the frontend-tools manualy.
32 Because of that, this plugin is ideal to integrate a separately developed frontend into a maven-build, without bothering the backend-developers with details of the frontend-build-process.
33
34 ## Seperate The Frontend-Project From The Maven-Based Backend-Project
35
36 The drawback with this approach is, that the backend- and the frontend-project are tightly coupled.
37 You can configure the frontend-maven-plugin to use a separate subdirectory as working-directory (for example `src/main/frontend`) and utilize this to separate the frontend-project in its own repository (for example by using [the submodule-functions of git](https://git-scm.com/book/en/v2/Git-Tools-Submodules "Read more about how to use git-submodules")).
38 But the grunt-tasks, that you call in the frontend-project through the frontend-maven-plugin, must be defined in that project.
39
40 Since I am planing to integrate a ‐ slightly modified ‐ version of Bootstrap as frontend into my project, that would mean that I have to mess around with the configuration of the Bootstrap-project a lot.
41 But that is not a very good idea, because it hinders upgrades of the Bootstrap-base, because merge-conflicts became more and more likely.
42
43 So, I decided to program a special `Gruntfile.js`, that resides in the base-folder of my Maven-project and lets me redefine and call tasks of a separated frontend-project in a subdirectory.
44
45 ## Redefine And Call Tasks Of An Included Gruntfile From A Sub-Project
46
47 As it turned out, there are several npm-plugins for managing and building sub-projects (like [grunt-subgrunt](https://www.npmjs.com/package/grunt-subgrunt "Read more about the npm-plugin grunt-subgrunt") or [grunt-recurse](https://www.npmjs.com/package/grunt-recurse "Read more about the npm-plugin grunt-recurse")) or including existing Gruntfiles from sub-projects (like [grunt-load-gruntfile](https://www.npmjs.com/package/grunt-load-gruntfile "Read more about the npm-plugin grunt-load-gruntfile")), but none of them lets you redefine tasks of the subproject before calling them.
48
49 I programmed a simple [Gruntfile](/gitweb/?p=examples/maven-grunt-integration;a=blob_plain;f=Gruntfile.js;hb=2.0.0 "Download the Gruntfile from juplo.de/gitweb"), that lets you do exactly this:
50
51 ```javascript
52
53 module.exports = function(grunt) {
54
55   grunt.loadNpmTasks('grunt-newer');
56
57   grunt.registerTask('frontend','Build HTML & CSS for Frontend', function() {
58     var
59     done = this.async(),
60     path = './src/main/frontend';
61
62     grunt.util.spawn({
63       cmd: 'npm',
64       args: ['install'],
65       opts: { cwd: path, stdio: 'inherit' }
66     }, function (err, result, code) {
67       if (err || code > 0) {
68         grunt.fail.warn('Failed installing node modules in "' + path + '".');
69       }
70       else {
71         grunt.log.ok('Installed node modules in "' + path + '".');
72       }
73
74       process.chdir(path);
75       require(path + '/Gruntfile.js')(grunt);
76       grunt.task.run('newer:copy');
77       grunt.task.run('newer:less');
78       grunt.task.run('newer:svgstore');
79
80       done();
81     });
82   });
83
84   grunt.registerTask('default', [ 'frontend' ]);
85
86 };
87
88 ```
89
90 This Gruntfile loads the npm-taks [grunt-newer](https://www.npmjs.com/package/grunt-newer "Read more about the npm-plugin grunt-newer").
91 Then, it registers a grunt-task called `frontend`, that loads the dependencies of the specified sub-project, read in its Gruntfile and runs redefined versions of the tasks `copy`, `less` and `svgstore`, which are defined in the sub-project.
92 The sub-project itself does not register grunt-newer itself.
93 This is done in this parent-project, to demonstrate how to register additional grunt-plugins and redefine tasks of the sub-project without touching it at all.
94
95 The separated frontend-project can be used by the frontend-team to develop the temlates, needed by the backend-developers, without any knowledge of the maven-project.
96 The frontend-project is then included into the backend, which is managed by maven, and can be used by the backend-developers without the need to know anything about the techniques that were used to develop the templates.
97
98 The whole example can be browsed at [juplo.de/gitweb](/gitweb/?p=examples/maven-grunt-integration;a=tree;h=2.0.0 "Browse the example on juplo.de/gitweb") or cloned with:
99
100 ```bash
101
102 git clone /git/examples/maven-grunt-integration
103
104 ```
105
106 Be sure to checkout the tag `2.0.0` for the corresponding version after the cloning, in case i add more commits to demonstrate other stuff.
107 Also, you have to init and clone the submodule after checkout:
108
109 ```bash
110
111 git submodule init
112 git submodule update
113
114 ```
115
116 If you run `mvn jetty:run`, you will notice, that the frontend-maven-plugin will automatically download Nodejs into a the folder `node` of the parent-project.
117 Afterwards, the dependencies of the parent-project are downloaded in the folder `node_modules` of the parent-project and the dpendencies of the sub-project are downloaded in the folder `src/main/frontend/node_modules` and the sub-project is build automatically in the folder `src/main/frontend/dist`, which is included into the directory-tree that is served by the [jetty-maven-plugin](http://www.eclipse.org/jetty/documentation/current/jetty-maven-plugin.html "Read more about the jetty-maven-plugin").
118
119 The sub-project is fully usable standalone to drive the development of the frontend separately.
120 You can [read more about it in this previous article](/serve-static-html-with-nodjs-and-grunt/ "Read more about the example development-environment").
121
122 ## Conclusion
123
124 In this article, I showed how to integrate a separately developed frontend-project into a backend-project managed by Maven.
125 This enables you to separate the development of the layout and the logic of a classic [ROCA](http://roca-style.org/ "Read more about the ROCA principles")-project nearly totally.