I want to concatenate all my JS files to reduce the number of HTTP requests a browser makes when it goes to my website. Of course, there's still value in keeping these files separate during development. The widely accepted solution is to perform the concatenation as part of the build.
The concatenation part is pretty straightforward.. but what about all the HTML files that still have a bunch of <script src="*.js">
tags referencing the pre-concatenated js files? They need to now point to the single concatenated javascript file.
How can I swap out those references as part of the build?
I want to concatenate all my JS files to reduce the number of HTTP requests a browser makes when it goes to my website. Of course, there's still value in keeping these files separate during development. The widely accepted solution is to perform the concatenation as part of the build.
The concatenation part is pretty straightforward.. but what about all the HTML files that still have a bunch of <script src="*.js">
tags referencing the pre-concatenated js files? They need to now point to the single concatenated javascript file.
How can I swap out those references as part of the build?
Share Improve this question edited Sep 16, 2011 at 1:53 pepsi asked Sep 15, 2011 at 20:50 pepsipepsi 6,8757 gold badges46 silver badges74 bronze badges6 Answers
Reset to default 4An Ant-based solution might be derived from this example. I'll insert the standard disclaimer that 'parsing' HTML with regular expressions may not be a good idea.
The idea is to:
- Either remove or convert to ments all
<script>
tags. - Insert a single
<script>
tag that references your amalgamated Javascript.
I've inserted the single js here just before the </body>
closing tag, but you can adjust that as required.
The source files here are under a directory called 'dirty'; the adjusted files in one called 'clean'.
<property name="single.js" value="single.js" />
<copy todir="clean" overwrite="true">
<fileset dir="dirty" />
<filterchain>
<tokenfilter>
<replaceregex
pattern="(<)(\s*SCRIPT\s+SRC=['"][^'"]+['"]\s*)/(>)"
replace="\1!--\2--\3"
flags="gi"/>
<replaceregex
pattern="(</BODY>)"
replace="<SCRIPT SRC="${single.js}" />${line.separator}\1"
flags="i"/>
</tokenfilter>
</filterchain>
</copy>
One way to do this is to have the html load just one script, but in development that script is just a "wrapper" of sorts that forces loading of the other individual scripts using the technique listed here. In production, the contents of that script is replaced with the union of all scripts (preferably by some server-side concatenation).
Depending on the technology you're using, you could have one JS reference in your html, to a handler which concatenates all of the JS files in a directory into one JS file. Then you can easily manage the individual files during development with the benefit of one HTTP request at runtime. There's plugins out there that will press the JS, remove whitespace and cache the results, but again, depends on your technology.
There is a library called wro4j which can be used as a build time solution (maven plugin) or a run-time solution (filter) and helps you to keep all your resources described in a single location as simple as:
<groups xmlns="http://www.isdc.ro/wro">
<group name="all">
<css>/asset/*.css</css>
<js>/asset/*.js</js>
</group>
</groups>
This way, you can switch all resource references in html from:
<script src="script1.js">
<script src="script2.js">
<script src="script3.js">
...
<script src="script99.js">
to
<script src="all.js">
Disclaimer: This is a biased answer, since I'm working on this project.
There is a Google project called minify: http://code.google./p/minify/ that will probably be exactly what you're looking for.
You could use modconcat which is apache plugin. It helps to concatenate files easily like this.
From:
<head>
<link rel="stylesheet" href="/css/reset.css" type="text/css" media="screen" />
<link rel="stylesheet" href="/css/master.css" type="text/css" media="screen" />
<link rel="stylesheet" href="/css/forms.css" type="text/css" media="screen" />
</head>
To:
<head>
<link rel="stylesheet" href="/css/reset.css,master.css,forms.css" type="text/css" media="screen" />
</head>