How does a minimum build configuration for dojo look like?
Asked Answered
S

1

11

I studied the build tutorial, found the web build (1.7.2 only), and tested several examples - however, I could not find an easy explanation of the build system.

Let's say my app is a single web page:

<script src="./js/App/other_non_amd_stuff_working_independently.js">
<script src="./js/lib/dojo/dojo.js" data-dojo-config="async: true"></script>
<script src="./js/App/Main.js">

The Dojo SDK is in ./lib/, Main.js contains the Dojo config + app boot:

require({
    packages:[{
        name:"App",
        location:"../../App"
    }]
},  
[ "dojo/query",
  "dijit/layout/BorderContainer", 
  "App/Foo",
  "dojo/domReady!"], function(query, BorderContainer, Foo) { ... });

My question now is as simple as this: How can I create one single script file out of all my Dojo/AMD stuff? I just want to replace

<script src="./js/lib/dojo/dojo.js" data-dojo-config="async: true"></script>
<script src="./js/App/Main.js">

with a single

<script src="./js/Main.minified.js">

Getting the build system to work on this seems somewhat non-trivial. It either trys to convert all files in ./App/ to AMD modules (that's not what I want .. yet) or fails to find App/Main. I tried building a build profile (app.profile.js), but I don't get the point of this except that it's adding (IMO unnecessary) complexity. How can I make the build system just concatenate my App/Main.js incl. dependencies ?

Any hints for better tutorials on understanding the build system are appreciated, too.

Stanhope answered 16/8, 2012 at 13:23 Comment(5)
I'm trying to do the same thing right now. If I make any progress, I'll let you know. Please do the same.Wassyngton
I just gave up after spending several hours on this. A setup a custom build for a dojo based application "back in the day" and it was a pain then. Now, I'm not really trying to build a dojo application. Just an AMD application. I have a few libraries that I am stringing together. I will stick with r.js - the requirejs optimizer script + bash script.Wassyngton
A solution would be highly appreciated. I'll put a 100 bounty on this one as soon as the question is eligible.Stanhope
There's a +1 from me :) Feel free to bounty even though allready get your answer gGReadjustment
PS: for repeat-builds (you change something and need a new release) delete the release-dir (instead of using overwrite) as it will take about 3 times as longReadjustment
R
4

See this QnA for building your layer into the dojo.js file. I might as well share my experiences, as it has taken me a few trial and errors to get my bootstraps working properly. Actually the answer is easily found within the 'dojosdk/util/buildscripts/profiles/baseplus.profile.js' file.

Dojo Custom Build 1.6 into a single file (same setup as new buildsystem, may still undergo a few changes for 2.0 though)

Howto create main application layer sutured together with dojo.js

dependencies ={
  layers:  [
      {
      name: "dojo.js", // overwrites regular dojo.js and ++'s your layer
      dependencies: [
         "app.main"
      ]
  }
}

Remember to prefix locations properly

Since youre having the 'App' module placed outside the dojo SDK root, the same would need to be applied as you assign packages in dojoConfig. The attribute key though, is instead prefixes for a layer profile.

prefixes: [
    [ "dijit", "../dijit" ],
    [ "dojox", "../dojox" ],
    [ "App", "../../App" ]
]

Howto create sub module layer

You may want to build a sub-module of your App, so that if a popup-dialog for instance requires extra extra - they can be downloaded at runtime in a separate package. To make sure that dependencies, which are allready loaded through your main-module-layer is not included in the sub-module-layer, the attribute key youre looking for is layerDependencies.

It would look like this for a combined result:

dependencies ={
  layers:  [
      {
        name: "../dojo/dojo.js", // overwrites regular dojo.js and ++'s your layer
        dependencies: [
         "app.Main"
        ]
      }, {
        name: "../../App/JITModule.js",
        layerDependencies: [
         "../../App/Main"   // tells this layer that the dependencychain in Main is allready loaded (programmer must make sure this is true ofc)
        ]
        dependencies: [
         "App.JustInTimeDialog"
        ]
      }
  ]
  prefixes: [
    [ "dijit", "../dijit" ],
    [ "dojox", "../dojox" ],
    [ "App", "../../App" ]
  ]
}

This should result in two optimized layerfiles, one with the standard one-line-dojo.js plus a dojo.cache entry, containing the files from your App. Example usage follows. Note, that you still need to call require for any cached modules or they will simply remain in the cache.

Putting it together in HTML

NOTE Putting your dojoConfig into the ./js/App/Main.js file will not work as expected, dojo.js regular contents are loaded above the layers.

<head>
  <script>
     function JITDialog() {
          require([ "App.JITDialog" ], function(dialoglayer)  {
             var dialog = new App.JustInTimeDialog();
             dialog.show();
          });
     }

     var dojoConfig = {
         async: true,
         packages:[{
            name:"App",
            location:"../../App"
         }]
     }
  </script>

  <script src="./js/lib/dojo/dojo.js"></script>

  <script>    
     require("App.Main", function() {
        // loads the layer, depending on the structure of App.Main class,
        // you can call your initializations here
        var app = new App.Main();
        app.run();
     });
  </script>

</head>
<body>
  <button onclick="JITDialog();">
      Download sub-module-layer and show a dialog on user interaction
  </button>
</body>
Readjustment answered 16/8, 2012 at 20:19 Comment(13)
Thanks a lot for the great reply! Anyway, one question: How do you start the build process?Stanhope
basically sh /path/to/dojotoolkit/utils/buildscripts/build.sh --profile <filename>|<profilename> --release <outputdir>Readjustment
That's what I was doing: Using the minified file I get a 404 for localhost/app/js/selector/acme.js - shouldn't that be included in the main file?Stanhope
Except that: I would prefer a 1.7+ buildfile with profiles = {...} - any chance to get this working? Thanks!Stanhope
there will still be a slight amount of browser sniffed stuff. For instance _firebug-lite and like if isDebug flag is set. The acme.js is loaded, If the browser does not support all features of CSS queries which dojo.query supports. Some have native implementation and therefore its a confitional. The 404 error, i dont really get hmm.. Try include selectorEngine:"acme" such that it reads dependencies.selectorEngineReadjustment
Yes, I tried that already. Doesn't work :/ I have experimented with the new profile definition today, which at least compiles now. The problem is the same here - I get a 404 for acme unless I specify it as an explicit dependency in the profile. This problem also occurs for some other classes, and I have no idea why this is happening. Here's my profile. Would you mind having a look what might be wrong? Thanks a lot, I really appreciate your help!Stanhope
you should find acme.js under /dojo-release-1.X.Y-src/dojo/selector/acme.js. I think youre trying to only copy dojo.js file and not the full toolkit? Since youre 404 is on an url: /app/js/dojo.js, this is because dojo.js is found at url: /app/js/dojo/dojo.js right? - and then dojoConfig.baseUrl = '/app/js'.Readjustment
Correct! My situation is a little bit different. I really don't care about requests a lot (everything is localhost), but I care about size. That's why I don't want to ship the whole dojo toolkit with my release (~8mb), only the few files I need (concatenated together if possible).Stanhope
include everything in dojo/ dir then, leave out rest - but remember that language (nls) files are also a just-in-time resourceReadjustment
Hum. This leaves me with my original problem, the dojo/ dir is quite heavy. Any other ways to explore?Stanhope
considered adding it as dependency??Readjustment
Adding what as a dependency? In my understanding, the dojo build script searches for dependencies in my main.js and adds them automatically (+ their deps and so on...). My question is why it doesn't add some packages, e.g. acme. Of course, I can add them all manually, but then whats the point of the buildfile again?Stanhope
@what: 'dojo/selector/acme'. The point is not to avoid having to upload 5k files to server.. the point is to avoid having to load 250 requests each time a page refreshes. If you have a checkout or the -src package extracted - comments and full-variable names gives a lot of overhead. The buildscript takes this away by optimizing scripts. A build profile will run on Your module's dependencies and compile a sutured-cache-file. It will not make include stuff (mentioned in #5 comment) thats only needed for some users (user/browser dependency not module dependency) unless it is told to do so.Readjustment

© 2022 - 2024 — McMap. All rights reserved.