[Update(3/17/16): ESRI has released a bower package for the JS API that removes the need for this project.]

Running the Dojo Build System with ESRI's JavaScript API for ArcGIS Server has been a problem that we have been trying to tackle for a very, very, very long time. This post is about one of the key components to our current strategy that allows us to utilize a continuous integration server and obtain that mythical single JavaScript file build.

When version 3.4 of the ESRI JS API was released, an ESRI employee informed us of an undocumented AMD build. It was available on the CDN just like the other builds, https://js.arcgis.com/3.10amd/init.js, but it had one key difference: it contained no layer files. It is vanilla AMD modules that have been optimized by the dojo build system. This simplified working with the build system immensely. With a bit of massaging you can take these modules and create an ESRI package that can be ingested by Dojo's build system with relatively ease. This "bit of massaging" is made trivial with the use of grunt-esri-slurp.

The original solution to this problems was a bash script. However, this only worked well for *nix users so we ported it to a bat file. We then had windows and *nix support but it was another step in the development pipeline and felt like friction. It was also a bit of an issue for running in our TravisCI environment and we ended up checking the slurped code into the repository. This felt wrong. We were using grunt for many other tasks and it seemed like the perfect fit for this task.

There are a few problems that this grunt plugin solves. The first is that the AMD build is intended to be used from a CDN and the Dojo build system expects the packages to exist on disk. grunt-esri-slurp, given a list of modules, will download each resource one at a time from the CDN to the package location for your project. grunt-esri-slurp builds the module list and stores the list for each api version that it supports (3.8+).

The second problem with the vanilla AMD build is that the modules have already been optimized by the dojo build system. These optimizations render the modules incompatible for use with the build system again. For example, the build system concatenates all of an AMD modules dependencies into a single string with a .split(',') on the end like this:

define('dep1,dep2,dep3'.split(','), function(s,G,H){...});

If you tried to use this vanilla AMD module within the build system it will not be able to parse the dependencies and the build will fail. grunt-esri-slurp unwinds the dependencies back into an array of strings like this:

define(['dep1','dep2','dep3'], function(s,G,H){...});

Until now we have been focusing solely on javascript. Optimizing CSS can save trips to your servers and time on your first page load. The dojo build system will optimize all of the CSS found in your packages. Our strategy is to create one top level CSS for our websites and @import the dependencies. The dojo build system will then concatenate these dependencies into the top level CSS and your website will only make one request.

The ESRI AMD build package contains a different file structure than the best practice where the entire dojo framework is nested inside a folder called dojo. grunt-esri-slurp unwinds the CSS file paths to make the dojo, dijit, and dojox packages at the same level as ESRI and your own packages.

If you want to get started using grunt-esri-slurp there are a few prerequisites. You first must install nodejs and then gruntjs. Follow the instructions there and on the readme file for grunt-esri-slurp. There are code examples and links to working examples and boilerplates.