- You can pull in any combination of the above three file types and combine and compress them into the same file.
- You can optionally output pre-gzipped versions of your files in case you are using a CDN which does not support gzipping files natively. This way you can direct users to the gzipped files if their browser supports it.
This would actually just output the contents of myfile.js into combinedfile.js because we aren’t specifying a tool with which to perform the minification. If we wanted to use jsmin we could specify it by passing the "–min=" parameter:
And if we wanted to pull in a file, a directory, a url, and then compress all of it using the Google Closure compiler (which requires Java to be installed and on the path) we could do this:
And remember, when we pull in that directory we might want to specify the order in which we concatenate the files. We can do this by adding a file called ordering.txt and placing it in the directory. It might look something like this:
Overall I’d like to keep this utility fairly simple, and with a few minor exceptions it already fills the needs that I set out to fill. So, what are those exceptions, what features do I want to add to it?
- More console output (with quiet option). It doesn’t really tell you what it is doing currently.
- Error handling. It doesn’t really check much right now.
- Ability to specify file masks when pulling in a directory.
- Use a config file to specify files, compression methods, etc… instead of passing items as command line parameters. I think this would give a bit more flexibility.
- Implement the YUI Compressor.
- Combine and compress css files as well.
- Maybe have an option to pull in standard libraries. Not sure how to work this out with versioning though.
- Anything great ideas that you guys have!
I hope that if you get a chance you’ll check it out and let me know what you think. Also, if you have any great ideas for changes to make, or you want to help out, please leave a comment! Thanks!
Loved the article? Hated it? Didn’t even read it?
We’d love to hear from you.
You might like to check out http://github.com/mvccontrib/MvcContrib/tree/master/src/MvcContrib.IncludeHandling/ and http://github.com/mvccontrib/MvcContrib/tree/bf72e4b0a80b313a2ce72eddeb93b7b365ac7f0e/src/Samples/MvcContrib.Samples.IncludeHandling
Justin, why not use "the bullet train" of JS and CSS compression? http://www.codeplex.com/shinkansen *cough* *cough*
Why use the "bullet train" when you can use the "space shuttle" of JS compressors? 🙂
As long as it’s not the Amtrak of JS compressors. 😀
This is a really complex space and there are a lot of different options and approaches depending upon the environment and your needs.
Would you like something that you can actually debug in your dev workflow? If so, then perhaps you should take a look at "script includers" like LABjs (which requires "cascades" of loads in a script block, instead of manual includes) .. or Machine.Includer, which allows you to specify your dependencies on a script-by-script basis (the way you would with server side code), and then resolve/load it up at request time… both of these options aren’t realistic for performance sensitive scenarios (like production), so we come back to…
Script bundling. Your post and tool provide (one) way to approach this issue. Another is the above-linked shinkansen tool. Really, I think we have to (sigh, once again) take a page from the Ruby playbook and look at some of their tooling approaches, like Sprockets and (especially) Jammit. They are really awesome, IMO (and Shinkansen is in line with them, but I don’t personally jive with their approach.. it can be integrated w/ MVC.. but is pretty fugly).
My major gripe with your tool is that if I have my own scheme for figuring out a piece of markup’s dependencies, then jsbundle.exe is redundant, period (esp. if using the closure compiler which has pretty much the same syntax on the CLI). So the real "value add" would be if you spelled out a convention to specify dependencies (like Sprockets ‘// require’ syntax) and then did that scanning for users when jsbundle.exe is ran, and then did the packaging.
Like, in your .aspx files (which get scanned), you have:
// you can do..
// require /static/scripts/jquery.js
// require /static/scripts/dep1.js
// or something like
The jquery.js dep speaks for itself, but look ing at dep1.js, we might have something at the top of the file like:
// require /static/scripts/dep2.js
This would provide the basis for a tool/script to recursively scan through these files and build up a dependency tree which it can then flatten and remove dups from. You then get an ordered file list which can be passed to the compiler, et al.
I personally already do this (and then execute Google Closure Compiler) using a hand-rolled scanner (python script) as a part of my own build process. So there’s not really anything for me in this tool, atm. It might be something that you could look at to add some value, though. It’s not too crazy. I also think there’s some real value in the server-caching based approaches in tools like Jammit or Shinkasen.
It’s funny that this post happened at this time. This and similar issues have been floating around a lot lately on sites like Ajaxian and Daily.js, as well. I’m also prepping to give several talks on this topic at upcoming code camps in the Northwest.
@Jeff Thanks for your thoughtful comments, and I agree that if you are taking the approach of automating this process using the Closure compiler, then this tool adds little value to your workflow.
On the other hand though, my goal was to provide a tool which can be extended further to allow for many scenarios, such as bundling and minifying for production, but also being able to deploy debug versions of files. I also wanted to have a tool which will support css compression as well.
Again, thanks for the ideas.
Nice post, Justin! We should take the same steps for CSS files. I posted a way of getting started with this line of thinking in ASP.NET MVC: http://www.curtismitchell.com/2b/?p=38
It is not as complete as what you have presented, but it shows a different approach to combining static plain text assets.
@Curtis Yeah, I definitely want to do the same thing for CSS files. Your solution look very good in the way that it easily integrates into the ASP.NET MVC application. I added some asp.net support for my tool, you can check it out here: http://www.codethinked.com/post/2010/02/11/Bundler-Part-2-ASPNET-Integration.aspx
It doesn’t take the same route that your solution does, it is still generating a physical file.
I cannot download JSBundler.exe
The download page become squashit. Need help!
@Daniel JsBundler has been renamed to SquishIt, and the tool has been changed a bit. If you want a command line tool to combine js files, I would check out ajaxmin or YUI compressor on Codeplex.
Leave a comment