I have a javascript file that is used to track events using Google analytics. I have created different accounts for the staging and production environment. The script to invoke GA code has a place holder for my account Id. The account Ids have been specified in the filter files. Using the webResources element in the maven-war plugin, we are able to successfully replace the property in the final WAR file.
Now, we are also using maven-yuicompressor plugin to minify and aggregate all our javascript files. The problem is that if I attach the execution of minify goal to the package phase, the WAR is created before the Javascript has been minified. If I attach the minify goal to anything earlier, the filter has been not applied till the time of minification producing an invalid file.
So, I am looking for a way to run the minify goal between the WAR plugin copying the filtered JS files and creating the WAR file. Here are the relevant portions of my pom.xml:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.1.1</version>
<configuration>
<webResources>
<resource>
<directory>src/main/webapp/js</directory>
<targetPath>js</targetPath>
<filtering>true</filtering>
</resource>
</webResources>
</configuration>
</plugin>
<plugin>
<groupId>net.alchim31.maven</groupId>
<artifactId>yuicompressor-maven-plugin</artifactId>
<version>1.1</version>
<executions>
<execution>
<goals>
<goal>compress</goal>
</goals>
<phase>package</phase>
</execution>
</executions>
<configuration>
<linebreakpos>-1</linebreakpos>
<nosuffix>true</nosuffix>
<force>true</force>
<aggregations>
<aggregation>
<output>${project.build.directory}/${project.build.finalName}/js/mysite-min.js</output>
<inputDir>${project.build.directory}/${project.build.finalName}/js</inputDir>
<includes>
<include>jquery-1.4.2.js</include>
<include>jquery-ui.min.js</include>
<include>ga-invoker.js</include>
</includes>
</aggregation>
</aggregations>
</configuration>
</plugin>
Great question, great anwser by artbristol, which i voted up. It helped me a lot. For future reference i post a complete solution:
src/main/resources/js
(or whatever fits your needs)src/main/resources/css
(or whatever fits your needs)target/classes/js/
src/main/webapp
jetty:run
. Jetty is picking up the compressed and aggregated files in src/main/webapp
src/main/webapp
.svnignore
or .cvsignore
file into src/main/webapp
to exclude all.js
from your favourite SCM tool.The excludes section is necessary to avoid compressing anything in src/main/resources and src/main/webapp. yui should just pickup already filtered files for aggregation.
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
<plugins>
<plugin>
<groupId>net.alchim31.maven</groupId>
<artifactId>yuicompressor-maven-plugin</artifactId>
<version>1.1</version>
<executions>
<execution>
<goals>
<goal>compress</goal>
</goals>
</execution>
</executions>
<configuration>
<excludes>
<exclude>*/*</exclude>
</excludes>
<force>true</force>
<nosuffix>true</nosuffix>
<removeIncluded>true</removeIncluded>
<aggregations>
<aggregation>
<insertNewLine>true</insertNewLine>
<output>${project.basedir}/src/main/webapp/js/all.js</output>
<includes>
<include>${project.build.directory}/classes/js/file1.js</include>
<include>${project.build.directory}/classes/js/file2.js</include>
</aggregation>
<aggregation>
<insertNewLine>true</insertNewLine>
<output>${project.basedir}/src/main/webapp/css/all.css</output>
<includes>
<include>${project.build.directory}/classes/css/file1.css</include>
<include>${project.build.directory}/classes/css/file2.css</include>
</aggregation>
</aggregations>
</configuration>
</plugin>
Why would you want filtering of css files?
i use it to reference my images like this
div.header {
background-image: url(/img/background.${project.version}.png)
}
Maven filters my project version into my css files. Any incoming request on our imageserver is filtered like this
protected void doHttpFilter ( HttpServletRequest request, HttpServletResponse response, FilterChain chain ) throws IOException, ServletException
{
String uri = request.getRequestURI();
if (isStaticRequest(uri))
{
String uriWithoutVersion = stripVersionString(uri);
String versionRequested = getVersionString(uri);
if (version.equals(versionRequested))
{
response.setHeader(CACHE_CONTROL_HEADER_NAME, CACHE_CONTROL_HEADER_VALUE);
response.setHeader(EXPIRES_HEADER_NAME, EXPIRES_HEADER_VALUE);
}
RequestDispatcher dispatcher = request.getRequestDispatcher(uriOhneVersionsnummer);
dispatcher.forward(request, response);
} else {
chain.doFilter(request, response);
return;
}
}
this way the browser caches each file forever. but when i upload a new version all file reference have a new version number, so the browser is fetching the image or css again. this helped us a lot to reduce traffic.
Can you put the filtered js files in src/main/resources/filtered-js, use the resources plugin instead, which binds to process-resources
, then point the webresources config of the maven-war-plugin to target/classes/filtered-js
?
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