I have a Scripts folder, that includes all the .js files used in the project. Using the Ajax Minifier task, I generate .min.js files for each one.
Depending on whether the application is running in debug or release mode, I include the original .js file, or the minified one.
The Scripts folder looks like this:
Scripts/script1.js
Scripts/script1.min.js // Outside the project, generated automatically on build
Scripts/script2.js
Scripts/script2.min.js // Outside the project, generated automatically on build
The .min.js files are outside the project (although in the same folder as the original files), and they are not copied into the destination folder when we publish the project.
I have no experience whatsoever using build tasks (well, apart from including the minifier task), so I would appreciate if anyone could advise me as to which would be the correct way to:
- Copy the .min.js files to the destination folder when I publish the app from Visual Studio.
- Delete / Not copy the original js files (this is not vital, but I’d rather not copy files that will not be used in the app).
Thanks,
Edit: From the responses, I see that I missed some details, and that maybe I’m looking for the wrong solution to the problem. I’ll add the following details to the question:
- If possible, we’d rather not create copy scripts in the build process of the solution. Sure, we considered it, but we were using Web deployment projects up until now, and we’d rather start using the new Publish feature of VS2010 (which is supposed to replace these projects) than manually adding copy commands to the build task.
- The *.min.js files are not included in the project because they can’t be in the Source control system (TFS at this moment). They are files generated during compilation, and it would be akin to including the ‘bin’ folder in the TFS (including the problems it would cause). Maybe we should create the min files in a different folder and treat it like ‘bin’? (Is that even possible?)
Edit (2012 October): ASP.NET 4.5 now includes Bundling and minification. The current version doesn’t support dynamic javascript generation very well, but it’s otherwise pretty usable and for instance does watch the filesystem to live changes as described below; before rolling your own compression, try that!
Old answer:
Rather than implement this at build time, I suggest you do so at runtime. This has a number of advantages:
This is the rough outline of the process I follow:
FileSystemWatcherto watch for changes.00_jquery.js10_init.jsetc. helps control order here). The list of filenames is stored for debug purposes.GZipStream. A version specific token is computed either by newest last-modified date or by the hash of the result.lock). If the file system watcher detects an update, step 2 starts again and runs in the background until the compression completes – hence the locking.IHttpHandler. All Uri’s include the version-specific token in the querystring – this is ignored both by the IIS static file handler and the custom http handler for the combined minified version, but makes caching easy.context.Response.OutputStream.Using that approach, you won’t need to fiddle with web.config options whenever you add or remove a script file; you can update scripts while the app is running and clients will request these on the very next page view – but you still will get optimal cache behavior since browsers won’t even send an If-Not-Modified request due to the expiry header. Usually, compressing scripts should take a second or so and the compressed result should be so small that the memory overhead of the static variable is negligible (at most a few 100 KB for a truly large amount of scripting / css).