The datajs source code includes not only the files for the library itself, but also the files to build from the multiple source files and to run a series of basic tests on them.
The main goals we wanted for our project were the following:
- Ability to produce an efficient, minified codebase.
- Ability to separate our code into different files, to improve maintenance and help understand what’s in there.
- Ability to leverage Visual Studio as an IDE and to run tests and debug from it, and do these same activities from a command line.
- Achieve all of the above with some simple and straightforward.
Here is a quick overview of what happens when you build.
- To build, run
djsbuild.cmd. This will prompt for a number of environment variables to be set, then merges all source files, removes internal flags and produces a minified version.
- The merging takes place in
djsbuildfile.js. Here we start from files that aren’t included from anywhere else (in our case odata.js) and textually include all files that are referenced in an
- The files may include sections of code under a special conditional (so far we only have
ODATA_INTERNALdefined). These blocks are removed during the build process from the merged file.
- The minified file is created if you download and copy the files from http://ajaxmin.codeplex.com/. We didn’t include these in our project to keep things simple – no need to go through extra licenses when getting datajs, or to keep updating ajaxmin (and also to make it easier to isolate and modify the specific minifer used).
datajs ODATA_INTERNAL flag
The datajs sources include special internal flags, typically variables that are checked on the window object such as
The purpose of these flags is to expose additional functions on some globally-reachable object, so other files can use them.
For example, the file
odata-utils.js has a lot of constants and functions that are exposed, such as
parseTimezone. This is done by assigning them to the OData object. The file
OData.parseTimezone to a local variable before the content section, and then uses it whenever it needs to.
When we merge the files to produce a single datajs file, everything goes into the same function, and so can be accessed directly without having to go through a global path. Therefore, you will see that the code always “imports” code before real content, and you will always see that code that “publishes” members inside a conditional block.
The effect is that from a tool that doesn’t know about the build process you can run code that uses datajs simply by including all files – the files will cooperate to share code and data. When we run the build process, the files are all merged together, the members are no longer publicly accessible, and the minifer tools can turn all of those functions into much, much shorter text.