Thursday, 18 October 2012

Modifying and Patching production installations of Fusion

Here's a long overdue post because I see this problem all too often and I don't think many are aware of what the actual proper solution actually is.

When you load any of the 5 fusion templates, you'll most likely (actually you should) see this file being loaded.

What is this fusionSF-compressed.js file? This file is the combined and compressed version of:

  • fusion.js
  • Its supporting libraries (jxLib, OpenLayers, etc)
  • All the fusion widget js files
All these files are combined into fusionSF.js. fusionSF-compressed.js is this fusionSF.js file run through the YUI compressor to strip out whitespace and other extraneous characters to give us a minified, production-ready version of fusion.

Why do we do this? Why don't the templates just link fusion.js and demand load the remaining scripts?
  • Download size. Minified scripts (combined with web server compression) results in the smallest possible amount of data that needs to travel through the wire. Compare a 515KB download of fusionSF-compressed.js vs a 1MB download of fusion.js and all of its supporting scripts.
  • Reduces the number of HTTP requests made. Doing a single request for a minified and compressed version of fusion beats doing 30-odd requests for fusion.js and all of its supporting scripts, especially when you then multiply the number of concurrent users and factor in network latency
So it's clear that fusionSF-compressed.js, is a good thing. So what's the problem?

What if we want to modify fusion? Suppose we want to roll in some enhancements or fixes for fusion. What files would we actually edit?
  1. fusionSF-compressed.js?
  2. fusionSF.js?
  3. fusion.js and/or its supporting js files?
I hope you all answered 3. If you answered 1, just take a look at fusionSF-compressed.js

If the gibberish nature of the file contents didn't give it away, you're not supposed to edit this file. This file is effectively the "compiled" version of fusion. For those who answered 2, yes the file in question is no longer gibberish but this is nothing more than an intermediate file that gets turned into the final fusionSF-compressed.js. Even if your templates are linked against fusionSF.js you would still be serving out an un-minified version of fusion. Remember why the templates are linked to fusionSF-compressed.js by default. Minimal requests and minimal download size.

You wouldn't edit the raw bits of an program executable by hand would you? No. You want to be editing the source code and then re-compile a new executable, which is the same thing you want to be doing with fusion as well. So the correct answer is indeed 3. You want to edit fusion.js and/or its supporting js files with your enhancements and/or fixes (temporarily switching your template to use fusion.js to identify these bugs, fixing the appropriate files, and testing your changes) and when everything's all good, "compile" a new fusionSF-compressed.js that incorporates your changes.

So how would you go about compiling such changes? Well this is why this post is long overdue. Because before the 2.4 release of MapGuide Open Source, there was no simple way to re-compile a new compressed version of fusion on a production installation. You would've had to:
  • Do an actual SVN checkout of the fusion source
  • Switch over or have this checkout version running side-by-side with your production fusion.
  • Try to reproduce the problem there, or to test your enhancements there.
  • Build a new compressed version of fusion
  • Re-test your changes against the compressed version of fusion
  • Deploy this new build of fusion to your production installation.
For people who have strong backgrounds in web/software development, this is your run-of-the-mill build process that's not overly fancy. For those who don't, you'd probably be confused with what I just listed.

So for the 2.4 release of MapGuide, we've provided the fusion build tools in a zip file. This zip file can be extracted into your production fusion installation and you have all the necessary build scripts and utilities needed to "re-compile" a new version of fusionSF-compressed.js that incorporates any customizations you have made. All the build tools require is that you have a copy of Apache Ant installed. Please do read up some of the ant documentation so you know how this tool works.

So with these build tools extracted to your fusion installation and Apache Ant installed, the workflow for patching/modifying fusion is as follows:
  • Switch your template(s) over to fusion.js so you are working against the raw source files
  • Perform your modifications to fusion.js and/or its supporting js files
  • Once your modifications are working and verified, run this command in a command prompt from the root directory of your fusion installation:
ant compress
  • This will combine and compress fusion.js and its supporting files into a new fusionSF-compressed.js
  • Switch your template(s) back over to fusionSF-compressed.js
  • Congratulations. You have now successfully patched/modified a production Fusion installation!
Hopefully this post (and the release of the fusion build tools with MGOS 2.4) will greatly help you understand how this whole business of modifying Fusion is supposed to work.


Jason Birch said...

I'm pretty sure there's still an option to the build script that allows you to append a JSON-ified and compressed version of the app def into the single file.

This is only really useful for sites that have a process around staging from development to production and if you're willing to rev the directory for fusion every time you upgrade, but it did improve load time of the map measurably in my testing.

May not be as important (or even exist) in later releases...

From the build notes in Trac, it looks something like:

ant singleFile -DappDef=templates\mapguide\standard\ApplicationDefinition.xml

PNH said...


What about CSS ? How do you advice to update it and compress it again ?

Jackie Ng said...

To my knowledge, CSS is not compressed and is not part of this single-file build process. This is probably due to various libs and widgets having their own css files, which would cause some havoc when combined into one file (namely, libs and widgets don't currently know programmatically whether they are part of a single-file build or not)

Mitchell Hastings said...

Would this process be the same for an installation of AIMS2014 with IIS?

Jackie Ng said...

Yes it should work if you overlay the for the *2.5* release of MGOS into your AIMS 2014 Fusion installation.

David said...

Quick tip: I'm recommend emptying your "build" folder in the "fusion" folder before running "ant compress". If you've removed any obsolete files from your "fusion" folder, an old copy can exist in your "build" folder and that will be included when running "ant compress". Clearing your "build" folder will guarantee that you're getting a fresh copy from your "fusion" folder.