I have a web project built using Maven, and I'm trying to find a better way to compile JavaScript files using the RequireJS compiler (this question can apply to any / minifier compiler as well).
I have a setting that works, but it needs to be improved:
I have packaged third-party JavaScript libraries and they are loaded as dependencies and then added with the WAR Overlay plugin.
I have an exec plugin task that runs the RequireJS compiler inside the target directory. I am currently running manually exec:exec after running the target (and therefore the contents of the WAR are placed in the target directory).
Instead, I would like to make the JS compilation part of the main (Java) compilation. The JS compiler (Require JS) itself is loaded as a dependency during the WAR overlay phase that occurs after compilation. So, I need the required JS files to be downloaded and unpacked, and I need to start compiling JS using these files before / during / after compiling Java.
I am sure there can be several ways to do this. I am looking for the most elegant solution.
Update: Existing POM Snippets
I have JavaScript dependencies that I pinned and added to our repository manager:
<dependency> <groupId>org.requirejs</groupId> <artifactId>requirejs</artifactId> <version>0.22.0</version> <classifier>repackaged</classifier> <type>zip</type> <scope>runtime</scope> </dependency> <dependency> <groupId>com.jqueryui</groupId> <artifactId>jquery-ui</artifactId> <version>1.8.7</version> <classifier>repackaged</classifier> <type>zip</type> <scope>runtime</scope> </dependency>
Note that RequireJS itself (which is required to compile the rest of the libraries) also loads as an external dependency. So, firstly, I need this dependency to load and unpack before I start compiling RequireJS.
These dependencies are added to WAR using the WAR Overlay plugin:
<plugin> <artifactId>maven-war-plugin</artifactId> <configuration> <overlays> <overlay> <groupId>org.requirejs</groupId> <artifactId>requirejs</artifactId> <classifier>repackaged</classifier> <type>zip</type> <targetPath>lib</targetPath> <includes> <include>requirejs/require.js</include> <include>requirejs/require/*</include> <include>requirejs/build/**</include> </includes> </overlay> <overlay> <groupId>com.jqueryui</groupId> <artifactId>jquery-ui</artifactId> <classifier>repackaged</classifier> <type>zip</type> <targetPath>lib</targetPath> </overlay> </overlays> </configuration> </plugin>
Although I do not need requirejs/build/** to complete the WAR, I include it as part of the overlay to get the Unpacked RequireJS build scripts unpacked, simply because I did not understand a better way.
Then I have an exec plugin task that compiles. But keep in mind that this task was not added to the normal compilation workflow: I need to manually call it using mvn exec:exec after packing the WAR:
<plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>exec-maven-plugin</artifactId> <version>1.1</version> <executions> <execution> <goals> <goal>exec</goal> </goals> </execution> </executions> <configuration> <executable>lib/requirejs/build/build.bat</executable> <workingDirectory>${project.build.directory}/${project.artifactId}</workingDirectory> <arguments> <argument>name=bootstrap</argument> <argument>out=combined.js</argument> <argument>baseUrl=scripts</argument> <argument>optimize=closure</argument> <argument>excludeShallow=plugins/manifest</argument> </arguments> </configuration> </plugin>
So, some questions:
- How can I extract the different parts of one archived dependency for compilation and WAR assembly steps? Or do I need to create two zip files, one with a runtime file, and the other for compilation scripts?
- I would like to include
exec:exec ideally at compile time, and if not, before packing the WAR. How to do it?
I actually tried a bunch of things without success, so I hope that I donβt appear as lazily laying out a huge piece of code and waiting for answers :) It's just that I didnβt quite turn around like Maven goals / phases, etc.