Marco
Marco

Reputation: 23945

Why is dojo build creating all packages as layers?

I am trying to create a build using dojo, which is as simple as it can be.

The only package I have installed is the Arcgis-js-api using bower:

"dependencies": {
    "esri": "arcgis-js-api#3.21.0"
}

my build.profile.js is defined like this:

var profile = {
  basePath: "./src",
  action: "release",
  cssOptimize: "comments",
  mini: true,
  layerOptimize: "closure",
  packages: [
    "app",
    "dijit",
    "dojo",
    "dojox",
    "dstore",
    "dgrid",
    "dgrid1",
    "xstyle",
    "put-selector",
    "esri", {
      name: "moment",
      location: "moment",
      main: "moment"
    }
  ],
  useSourceMaps: false,
  mini: true,
  stripConsole: "warn",
  selectorEngine: "lite",

    layers: [{
      "dojo/dojo": {
        boot: true,
        customBase:true,
        include: [
          "app/main"
        ]
      }
    }]
};

If I understood the dojo documentation on the build system correct, this should create a single output file under dojo/dojo.js which contains all dependencies, yet when I issue a build using this profile I am receiving a folder for each package, that has been defined.

The app/main package consists of a single console.log call:

define([],function(){
    console.log("ratzupaltuff");
});

I am expecting to only get a very small release, since I am esentially using nothing dojo specific.

What do I have to change to get the desired result of a single layer? In its current form the release build is still 114Mb in size, which is certainly way too large.

Upvotes: 4

Views: 268

Answers (2)

Chris Rymer
Chris Rymer

Reputation: 713

I don't know if this is a useful but I have a situation where I am creating a layer which loads from a completely different location to the core dojo app.

This means that I actually don't need the dojo, dijit and dojox to be in my build. I was having the issue of all files being bundled in to my location whether I wanted them or not.

What I have opted for is to change the destination of these files to a folder I can just ignore which is outside of my application folder by using destLocation.

So I have this in my build script

packages: [
        {
          name: "dojo", 
          location: "./dtk/dojo",
          destLocation: '../directory/outside/of/codebase/dojo'
        },
        {
          name: "dijit", location: "./dtk/dijit", 
          destLocation: '../directory/outside/of/codebase/dijit' },
        {
          name: "dojox", 
          location: "./dtk/dojox", 
          destLocation: '../directory/outside/of/codebase/dojox'
        },
        { 
          name: "applayer", 
          location: "./location/of/my/release/folder/", 
          destLocation: './' 
        }
    ],

It's not perfect but it at least keeps the necessary packages out of my directory. I think the idea of bundling all files in to the directory is for the event where you run a require outside of your core layers.

If you did a hotfix for example in the client and you require a dojo module which isn't already in require.cache then this request would fail. If you know that won't happen then you don't need the packages (Hopefully).

Upvotes: 0

Frode
Frode

Reputation: 5710

In the "Creating Builds" tutorial, it says:

You might be asking yourself "if we build everything we need into a layer, why do we worry about the rest of the modules?" If you were to only keep the layer files and not have the rest of the modules available, you would lose that as an option to keep your application working without having to do a whole build again to access those modules.

That said, I agree with you, it would be nice to be able to build a minimal distribution containing only the layers - because even though the browser may only download the dojo/dojo.js layer, it's annoying to have to distribute the big 100MB directory.

However, even if the build script only copied the layer files, the layers may need various resource files which are not declared in the AMD dependency graph (e.g. images or fonts).

In my dojo projects, I've usually resorted to manually specifying and copying the required to a "minimal build" directory at the end of my build script. As long as it's a small application, this is usually manageable. It is certainly a bit annoying and error-prone though, so if anyone knows of a better way to do what you're asking, I'd love to hear about it.

node ../../dojo/dojo.js load=build --profile "$PROFILE" --releaseDir "$DISTDIR" $@
# ... 
FILES=(
    index.html
    myapp/resources/myapp.css
    myapp/resources/logo.svg
    dojo/dojo.js
    dojo/resources/blank.gif
    dijit/themes/claro/form/images/buttonArrows.png
)
for file in ${FILES[*]}; do
    mkdir -p $MINIMAL_DIST_DIR/`dirname $file`
    cp $DISTDIR/myapp/$file $MINIMAL_DIST_DIR/$file
done

(The file myapp.css @imports dojo.css etc, so all the CSS is built into that single file.)

Upvotes: 1

Related Questions