I have a Java web project that uses Maven standard directory layout: java files gets into java
(actually: /src/main/java
), resources into resources
, web content into webapp
.
Then we wanted to improve our web layer, by adding bower, sass, gulp etc. Our gulp build compiles scss, minimize javascripts, optimize images etc, everything what you would expect. But this introduced 1) another build tool, gulp and 2) generated files by gulp.
Question is how to organize such project? One way could be:
In this solution, all javascript,images,scss files are stored in /src/main/assets
and gets build into the /src/main/webapp
. Both sources and gulp-generated files gets committed to the git. The gradle build is independent from gulp, and it is ok for the users that does not have gulp installed - like those who needs to work only on backend. Also, CI servers does not depend on gulp stuff.
In this solution, gulp is called from gradle. Gradle therefore builds everything. And you must use gradle every time when you want to try something. Also, every developer needs to have gulp installed, what may be a problem for developers using windows (as i've been told). Also CI server should know how to run gulp.
My team is torn between these two options. Does anyone have any working experience with either of these solutions?
maven-project/src/main – contains source code and resources that become part of the artifact. maven-project/src/test – holds all the test code and resources. maven-project/src/it – usually reserved for integration tests used by the Maven Failsafe Plugin.
The target directory is used to house all output of the build. The src directory contains all of the source material for building the project, its site and so on. It contains a subdirectory for each type: main for the main build artifact, test for the unit test code and resources, site and so on.
Maven project structure and contents are declared in an xml file, pom. xml, referred as Project Object Model (POM), which is the fundamental unit of the entire Maven system.
I'm currently using Java + Grunt + Maven. I've found there are two ways of packaging your frontend with your backend and the same will certainly apply to Gulp.
In the end it's up to what's best for your project/team. From my experience I usually use option B when working with others since the decoupling is easily worth the other issues. When I'm doing my own side projects I always go for option A because it's just easier to launch one webserver and to run a local environment closer to what DEV/PROD is like.
A) Put your frontend into the webapp folder (ex. https://github.com/kdubb1337/maven-grunt-webapp)
Benefits - You can launch your backend and do development all in one place and working with Spring security is a snap, even without OAUTH. Fewer issues working with two webservers up on your local environment when they would normally be bundled into one port on other environments.
B) Keep your frontend in a different folder, or even in a different repo that you clone into the root folder of your backend repo. (ex. https://github.com/kdubb1337/maven-grunt) see the 'yo' folder
Benefits - Fantastic decoupling so front end developers can live in joy without having to even install java locally or worry about recompiling your backend. Works great if you want Travis (or your favourite CI app) to do unit tests on the backend and the frontend.
EDIT I've found this awesome plugin you can use with maven/gradle to build the frontend https://github.com/eirslett/frontend-maven-plugin. Seems like the way to go, will be refactoring my starter projects with this guy for grunt and gulp
The current best practice here is to treat your frontend build as a separate project and put it in its own Maven or Gradle module. Have your Java build system invoke the JavaScript tooling (e.g., with the maven-exec-plugin
) and save the output into the appropriate directory in target
or build
. Bundle up the results in a jar and serve off the classpath.
If you're using Bower, you only need the base Node install on your CI server, and your Java build can invoke the necessary build process from there, fetching JS packages as needed. Don't forget to (1) use --save
and (2) exclude the JS modules directory from source control.
In addition, I suggest looking at RaveJS, which manages your JavaScript build and keeps you from having to configure watchers and such during development.
My recommended best practice is using the com.github.eirslett.frontend-maven-plugin (or the maven grunt plugin) to call the grunt/gulp build from mvn (in process resources goal). When CI builds, it's all integrated, even npm etc can be installed in mvn's target so you don't have bother to configure your CI server for npm.
When developers build, then mostly still just use one maven command. For JS/CSS/HTML developers, after mvn clean install, they can run grunt/gulp "watch" in the background to get their JS changes reflected immediately in the browser without incurring any maven overhead (just the wicked fast gulp/grunt tasks).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With