How to minify javascript and css files using maven plugin

It is advisable that all the production javascript and css files are minified and most of the javascript libraries do this. This post explains how to minify javascript and css files using maven plugin.I have minified sample javascript and css files using minify-maven-plugin. This sample application uses 1.7.2 version of minify-maven-plugin which requires jdk 7 so it does not work with jdk 6 or prior versions.

In this sample application, I have used embedded jetty web container so minification can be tested from browser as well. Please note that I have tested this sample application on windows with jdk 7 64 bit and maven 3.0.4.

This application contains two sample javascript and two sample css files which will be minified using minify-maven-plugin.

sample1.css

H1 {
	color: white;
	background: teal;
	FONT-FAMILY: arial, helvetica, lucida-sans, sans-serif;
	FONT-SIZE: 18pt;
	FONT-STYLE: normal;
	FONT-VARIANT: normal
}
H2 {
	COLOR: #000000;
	FONT-FAMILY: lucida-sans, sans-serif;
	FONT-SIZE: 12pt;
	FONT-STYLE: normal;
	FONT-VARIANT: normal
}

sample2.css

body {
	COLOR: #000000;
	FONT-FAMILY: lucida-sans, sans-serif; FONT-SIZE: 18pt;
	FONT-STYLE: normal;
	FONT-VARIANT: normal;
	background-color:yellow;
}

Above two sample css files are placed under the $sample-web-appsrcmainwebappstyles.

sample1.js

function popupFromSample1() {
	alert("Hello World from sample 1");
}

sample2.js

function popupFromSample2() {
	alert("Hello World from sample 2");
}

Above two sample javascript files are placed under the $sample-web-app\src\main\webapp\scripts.

I have also created index.jsp page as below to test minified javascripts and css files.

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN">

<link rel="stylesheet" type="text/css" href="/styles/minified/sample1.css" />
<link rel="stylesheet" type="text/css" href="/styles/minified/sample2.css" />

<script type="text/javascript" src="/scripts/minified/sample1.js"></script>
<script type="text/javascript" src="/scripts/minified/sample2.js"></script>

<html>
	<body>
		<H1>Header 1!</H1>
		<H2>Header 2!</H2>

		Something in body

		<button type="button" onclick="popupFromSample1()">Try popup from sample1.js</button>
		<button type="button" onclick="popupFromSample2()">Try popup from sample2.js</button>
	</body>
</html>

Refer following pom.xml.

<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/maven-v4_0_0.xsd">

<modelVersion>4.0.0</modelVersion>
<groupId>com.elitejavacoder</groupId>
<artifactId>sample-web-app</artifactId>
<packaging>war</packaging>
<version>1.0-SNAPSHOT</version>
<name>Sample Maven Web App</name>
<url>http://maven.apache.org</url>

	<build>
		<finalName>sample-web-app</finalName>
		<plugins>
			<plugin>
				<groupId>org.mortbay.jetty</groupId>
				<artifactId>maven-jetty-plugin</artifactId>
				<version>6.1.15</version>
				<configuration>
					<contextPath>/</contextPath>
					<scanIntervalSeconds>2</scanIntervalSeconds>
					<webAppSourceDirectory>${basedir}/target/sample-web-app</webAppSourceDirectory>
				</configuration>
			</plugin>

			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-war-plugin</artifactId>
				<version>2.4</version>
				<configuration>
					<warSourceExcludes>/styles/*.css,/scripts/*.js</warSourceExcludes>
				</configuration>
			</plugin>

			<plugin>
				<groupId>com.samaxes.maven</groupId>
				<artifactId>minify-maven-plugin</artifactId>                   
				<version>1.7.2</version>
				<executions>
					<execution>
						<id>minify</id>
						<phase>process-resources</phase>
						<goals>
							<goal>minify</goal>
						</goals>
						<configuration>
							<charset>utf-8</charset>
							<jsEngine>CLOSURE</jsEngine>
							<skipMerge>true</skipMerge>
							<nosuffix>true</nosuffix>

							<cssSourceDir>styles</cssSourceDir>
							<cssTargetDir>styles/minified</cssTargetDir>
							<cssSourceIncludes>
								<cssSourceInclude>*.css</cssSourceInclude>
							</cssSourceIncludes>

							<jsSourceDir>scripts</jsSourceDir>
							<jsTargetDir>scripts/minified</jsTargetDir>
							<jsSourceIncludes>
								<jsSourceInclude>*.js</jsSourceInclude>
							</jsSourceIncludes>
						</configuration>
					</execution>
				</executions>
			</plugin>
		</plugins>
	</build>
</project>

In the above pom.xml, minify-maven-plugin is the only plugin required and responsible for minification of javascript and css files. maven-jetty-plugin is used to test this application with jetty web container and maven-war-plugin is used to exclude original javascript and css files from the packaged WAR file.

Take a look at the configuration provided for minify-maven-plugin. I have created minified files in a separate directory (refer <cssTargetDir> and <jsTargetDir> elements) as I don’t want any suffix to be added to minified files. I have specified <nosuffix>true</nosuffix> so name of minified file remains same as source file otherwise it creates *.min.css or *.min.js (i.e. sample1.min.css, sample1.min.css).

I have specified <cssTargetDir> and <jsTargetDir> for resultant minified files otherwise minified files are created in the same directory as source file. Please be informed that <nosuffix> with true value won’t create minified files if target directory is not specified, to avoid file overwriting issue.

In the above sample pom file, I have minified all the javascript and css files available in the directory however you can minify some specific files as described below (replace <cssSourceIncludes> element with the following).

<cssSourceFiles>
	<cssSourceFile>sample1.css</cssSourceFile>
	<cssSourceFile>sample2.css</cssSourceFile>
</cssSourceFiles>

<jsSourceFiles>
	<jsSourceFile>sample1.js</jsSourceFile>
	<jsSourceFile>sample2.js</jsSourceFile>
</jsSourceFiles>

One more thing, note that I have specified true for the <skipMerge>true</skipMerge> which stops the plugin to create one single(one merged file for css and one for javascript) file by combining all the files in one. The default value for skipMerge is false so it creates one style.css for all the css files and one script.js file for all the javascript files. If you do not like these names then you can specify merged file names of your choice using jsFinalFile and cssFinalFile element under plugin configuration.

Now run the mvn clean install –DskipTests from command propmpt, check your generated war file. It should have minified javascript and css files.

Run application in Jetty and test from the browser.

Run mvn jetty:run command from command prompt from project base directory. It deploys war file to embedded web container and which will be accessible at http://127.0.0.1:8080/index.jsp.

Now you can check that javascripts and css are minified or not by accessing the following urls.

http://127.0.0.1:8080/styles/minified/sample1.css – Returns minified css as below:

H1{color:white;background:teal;FONT-FAMILY:arial,helvetica,lucida-sans,sans-serif;FONT-SIZE:18pt;FONT-STYLE:normal;FONT-VARIANT:normal}H2{COLOR:#000;FONT-FAMILY:lucida-sans,sans-serif;FONT-SIZE:12pt;FONT-STYLE:normal;FONT-VARIANT:normal}

http://127.0.0.1:8080/styles/minified/sample2.css – Returns minified css as below:

body{COLOR:#000;FONT-FAMILY:lucida-sans,sans-serif;FONT-SIZE:18pt;FONT-STYLE:normal;FONT-VARIANT:normal;background-color:yellow}

http://127.0.0.1:8080/scripts/minified/sample1.js – Returns minified javascript as below:

function popupFromSample1(){alert("Hello World from sample 1")};

http://127.0.0.1:8080/scripts/minified/sample2.js – Returns minified javascript as below:

function popupFromSample2(){alert("Hello World from sample 2")};

If you have any query on this then feel free to ask me by putting comment below.

Sample application is available on GitHub at https://github.com/elitejavacoder/maven-minify-javascript-and-css

One comment on “How to minify javascript and css files using maven plugin

  1. Anonymous says:

    This is awesome, thanks very much for sharing this knowledge!

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>