The Package System and Custom Builds
A Dojo custom build speeds performance by doing the following:
- First, it groups together modules into layers. A layer, which is one big .js file, loads faster than the individual .js modules that comprise it
- Second, it interns external non-JavaScript files. This is most important for Dijit templates, which are kept in a separate HTML file. Interning pulls the entire file in and assigns it to a string.
- Third, it smooshes the layer down with ShrinkSafe. ShrinkSafe removes unneeded whitepsace and comments, and compacts variable names down to smaller ones. This file downloads and parses faster than the original.
- Finally, it copies all non-layered scripts to the appropriate places. While this doesn't speed anything up, it ensures that all Dojo modules can be loaded, even if not present in a layer. If you use a particular module only once or twice, keeping it out of the layers makes those layers load faster.
The catch? You have to designate the modules in each layer with a profile, which is something like a Makefile or Ant script. But that's not too hard if you know your app well.
So the input of the build system is the Dojo source tree, plus any source trees for custom stuff you wish to include ... plus the profile. The output is a Dojo distribution tree which you can copy to your web server. Sweet!
Prerequisites
You need the following installed on your computer to run Dojo's build system:
- Java 1.4.2 or later (Java 1.5 recommended).
- A source build of Dojo, which you can obtain at http://download.dojotoolkit.org/release-1.1.0. The source builds are suffixed with "-src". If you want to download the latest code from the Subversion code repository, see the Use Subversion page.
Creating a Custom Profile
In the util/buildscripts/profiles directory, you will create a profile build file called foo.profile.js like this:
layers: [
{
name: "mydojo.js",
dependencies: [
"dijit.Button",
"dojox.wire.Wire",
"dojox.wire.XmlWire",
"explosive.space.Modulator"
]
}
],
prefixes: [
[ "dijit", "../dijit" ],
[ "dojox", "../dojox" ],
[ "explosive", "../../explosive" ]
]
};
The dependencies section within the layer lists all the modules you call directly. Any referenced modules will also be included, so you don't have to trace back the dependency tree. Also, Dojo base modules are an implicit dependency, so you don't need to list things like "dojo.query". (Dojo core modules, however, do need to be listed.)
The modules for that layer are gathered together to make the "layer" file, in our example: "mydojo.js". Then you just load this layer file in your pages with a SCRIPT tag. Easy!
The prefixes section list any modules that need inclusion. Note our "explosive" module, which is located away from the Dojo tree. You need to list these if you use them, even if you don't want any modules from it in your layer file.
For the 1.0+: If you choose to optimize the JS files in a prefix directory (via the optimize= build parameter), you can choose to have a custom copyright text prepended to the optimized file. To do this, specify the path to a file tha contains the copyright info as the third array item in the prefixes array. For instance:
[ "explosive", "../../explosive", "../../explosive/copyright.txt"]
]
If no copyright is specified in this optimize case, then by default, the dojo copyright will be used.
Running The Build
After specifying a profile file as shown above that statically specifies the resources you want to include, and saving it as /buildscripts/profiles/foo.profile.js, you run the Rhino interpreter on it and specify the profile name as a parameter. For example, from the buildscripts directory:
$ build.sh profile=foo action=release
On Windows PC's, substitute build.bat for build.sh. For both platforms, you may also specify additional build options. Run build.sh to see a list of all supported options. Here is a sample of the supported options:
profile | The name of the profile to use for the build. It must be the first part of the profile file name in the profiles/ directory. For instance, to use base.profile.js, specify profile=base. Default: base |
profileFile | A file path to the the profile file. Use this if your profile is outside of the profiles directory. Do not specify the "profile" build option if you use "profileFile" Default: "", |
action | The build action(s) to run. Can be a comma-separated list, like action=clean,release. The possible build actions are: clean, release Default: "help", |
version | The build will be stamped with this version string Default: "0.0.0.dev", |
localeList | The set of locales to use when flattening i18n bundles Default: "en-gb,en-us,de-de,es-es,fr-fr,it-it,pt-br,ko-kr,zh-tw,zh-cn,ja-jp", |
releaseName | The name of the release. A directory inside 'releaseDir' will be created with this name Default: "dojo", |
releaseDir | The top level release directory where builds end up. The 'releaseName' directories will be placed inside this directory Default: "../../release/", |
loader | The type of dojo loader to use. "default" or "xdomain" are acceptable values." defaultValue: "default", |
internStrings | Turn on or off widget template/dojo.uri.cache() file interning Default: true, |
optimize | Specifies how to optimize module files. If "comments" is specified, then code comments are stripped. If "shrinksafe" is specified, then the Dojo compressor will be used on the files, and line returns will be removed. If "shrinksafe.keepLines" is specified, then the Dojo compressor will be used on the files, and line returns will be preserved. If "packer" is specified, Then Dean Edwards' Packer will be used Default: "", |
layerOptimize | Specifies how to optimize the layer files. If "comments" is specified, then code comments are stripped. If "shrinksafe" is specified, then the Dojo compressor will be used on the files, and line returns will be removed. If "shrinksafe.keepLines" is specified, then the Dojo compressor will be used on the layer files, and line returns will be preserved. If "packer" is specified, Then Dean Edwards' Packer will be used Default: "shrinksafe", |
copyTests | Turn on or off copying of test files Default: true, |
log | Sets the logging verbosity. See jslib/logger.js for possible integer values Default: logger.TRACE, |
xdDojoPath | If the loader=xdomain build option is used, then the value of this option will be used for the path to Dojo modules. The dijit and dojox paths will be assumed to be sibilings of this path. The xdDojoPath should end in '/dojo' Default: "", |
Cross Domain (XDomain) Builds
Doing an xdomain build allows you to load Dojo and your custom modules from another domain. The benefits to doing this are listed in the 0.4 Book page about Cross Domain Resource Loading.
To do an xdomain build:
$ build.sh profile=foo loader=xdomain xdDojoPath=http://my.server.com/path/to/buildoutputdir action=release
xdDojoPath is optional. It just burns in the location of dojo, dijit and dojox into the built dojo.js. If you do not specify that option, then you will need to use djConfig.modulePaths/dojo.registerModulePath() in your HTML page to set the xdomain locations for dojo, dijit and dojox. For your own custom modules, you will have to set djConfig.modulePaths/dojo.registerModulePath() even if you us the xdDojoPath build option.
For 0.9+ there is a bug about loading dojox.gfx with an xdomain build.. If you want to use dojox.gfx with an xdomain build, there are some workarounds until the bug gets fixed:
- Include dojox/gfx.js directly in your page with a script tag in the HTML source, after the dojo.js script tag (do not use gfx.xd.js, use gfx.js).
- Include dojox.gfx in a layer file that you load via a script tag in the HTML source (load the .js layer file, not the .xd.js layer file).
- Printer-friendly version
- Login or register to post comments
- Subscribe post
Bugs / Pitfalls with custom builds
You really do have to do your own custom packaging of dojo in order to get the snappy performance we all want. Generally, what we have done is this:
1.) Added a dojo-build directory to our project, which holds a src version of dojo untarred.
2.) Have two header files, one for dojo-dev, and one for dojo-prod. This allows us to have the standard dojo-release for our development purposes (this file holds the link lines, djconfig, etc) and one for production, which just links to our custom dojo base file, and our custom dijit file. Our build process scrapes out the dojo.require's from our tpl templates. This way, you only have two requests for all of dojo, and your own widgetry. We also scrape out the addModule line, as that is not needed in production.
3.) The profile file as shown above lists all of the dijits , and our own widgets, that are called DIRECTLY. This is important to manage, and should be thought about whenever you add / remove a dijit or custom widget from your app. The prefixes are just dijit, and our own module. Try to embed all of your requires for each custom widget within it's Widget.js file.
For php folk, the concept of a build is pretty foreign. But eventually, as your app gets bigger, you need something like ant or phing in order to build, and deploy, your app. The dojo build process just hooks right into whatever build script you use. We fire the command line build.sh with parameters telling it where our profile file, and deployment dir (right in our js dir) should be.
Like most people, I took the tundra theme, and used it as a base for our own theme. I wanted the theme to be completely seperate from the dojo directory, in our css dir. At the top of tundra.css, you will see a relative link to the base dijit.css file. This bit us hard after our custom build. If you move your theme dir outside the dojo area, a relative link will break in a custom build (since the dojo-1.0.1 dir is not present in the production dist), but firebug cant catch that the dijit.css core file was 404. All dijits were messed up until we changed this. Our production dojo_head.tpl file links to the production custom build's dijit.css, and then our own theme css. e.g.:
How to use a custom build
I've seen a lot of discussion on the boards about how one should use the custom build after you've created a layer file with additional classes compiled in. For a local Dojo build (not XDomain) as listed above, I think the correct HTML code to reference the layers is:
<script type="text/javascript" src="/js/release/dojo/dojo/mydojo.js"></script>
Is this correct? The important thing to note is that you have to reference both the dojo.js and mydojo.js files, I think.
[mis-post]
[deleted]
Build Profile Parameter Descriptions Table
In order to try and fully understand the dojo build profile parameters, I have attempted to describe them in the following table. If there are errors or omissions in what I have posted, please let me know and I will be happy to correct them.
For source code at version 1.0.2, this table assumes a minimal build command of the form:
where you run the command from the path:
Path name is incorrect in 1.0.2
Hi.
Under the header "Creating a Custom Profile", the path name src/buildscripts/profiles should read utils/buildscripts/profiles.
Fixed
I've updated the page. Thanks :)