One of the really great aspects of ExtJS 4 is the ability to configure how dependencies in your application are loaded, using asynchronous loading, synchronous loading, or a combination of both. This flexibility lets you really dig into detail when debugging, and you are able to file-by-file see where errors are occurring, where processes can be improved, etc. But even more, you can specify very granularly which files you want–and need–while excluding those you don’t.

Of course, all of this is really meant for your development environment. While it’s fine to load 70+ individual JavaScript files while working out your app’s functionality, you *definitely* do not want to impose such a monstrous load on your site’s actual visitors. This, after all, is why everyone uses ext-all.js. It’s the whole framework, smashed down into a single, minified file. But the problem is that it’s still the *whole* thing. There are probably a bunch of bits of ExtJS that you don’t need. This is where the Sencha SDK tool’ can help create a custom build that includes everything you need for your application to run, without the overhead of all the stuff you don’t.

In what follows, I’m going to outline my first ExtJS 4 build using the SDK tools. As a disclaimer, this is my first go, so take it with a grain of salt. If I’ve missed some important bits, or am just plain wrong on any part, please let me know in the comments. And of course, any constructive criticism as to how I can go about this better/more efficiently/etc. is most welcome.

Good? Okay, on we go!

Getting the SDK Tools Setup

First things first. Grab a copy of the SDK tools (for this walkthrough, I’m using v1.2.3). I simply installed them to the default directory. On my Mac, this is /Applications/SenchaSDKTools-1.2.3.

Ok, as we move on I’m going to assume you already have an ExtJS-based application more or less running on your development machine. For me, my application’s path is like so: /Applications/sites/gloss/. In this directory, I have my app structured according to the guidelines outlined in Sencha’s MVC introduction. I’m going to assume that you do as well :)

Before moving on, here’s a quick look at the index.html file of my app: you’ll notice I’m using the ext-debug.js file and my custom app.js (per the MVC Architecture recommendations).

<html>
<head>
    <title>Gloss</title>
    <link rel="stylesheet" type="text/css" href="resources/css/ext-all-gray.css">
    <script type="text/javascript" src="extjs/ext-debug.js"></script>
    <script type="text/javascript" src="app.js"></script>
</head>
<body>
    ....
</body>
</html>

Creating the JSB3 File

The first real step to creating our custom build is to use the Sencha SDK tools to generate a .jsb3 file. This will be used to tell the SDK tools precisely which resources (.js files) need to be included/smashed/minified/obfuscated. This file is generated in one step, and the actual build is created in another. There’s a good reason for this, namely that you can modify the .jsb3 file (if needed) before finalizing the build (more on this later).

To create the .jsb3 file, open up Terminal. Navigate to your application’s root. For me, this looks like:

cd /Applications/sites/gloss/

You should now be in your application’s root folder.

Next, we need to run the Sencha create command to generate the .jsb3 file. I’ll include the command first, then describe it a bit:

sencha create jsb -a http://127.0.0.1/gloss/index.html -p app.jsb3

The most important part, really, is the address in the middle. According to the docs, you can use either the file name relative to your application (e.g., “index.html”), or the URL of your application (e.g., “http://127.0.0.1/gloss/index.html”). I didn’t have luck with the relative path, but the full URL worked well for me. Give it a try both ways, and see what result you get.

If you didn’t run into any errors, you should now see a new file in your application’s root, based on whatever name you specified in the “create” command above (for this example, it’s simply called app.jsb3). If you open it up, you should notice something like the following:

{
    "projectName": "Project Name",
    "licenseText": "Copyright(c) 2011 Company Name",
    "builds": [
        {
            "name": "All Classes",
            "target": "all-classes.js",
            "options": {
                "debug": true
            },
            "files": [
                {
                    "path": "extjs/src/util/",
                    "name": "Observable.js"
                },
                {
                    "path": "app/controllers/",
                    "name": "MyController.js"
                },
                ....a lot more here....
            ]
        },
        {
            "name": "Application - Production",
            "target": "app-all.js",
            "compress": true,
            "files": [
                {
                    "path": "",
                    "name": "all-classes.js"
                },
                {
                    "path": "",
                    "name": "app.js"
                }
            ]
        }
    ],
    "resources": []
}

The .jsb3 specifies that two “builds” will be created. One will be all-classes.js, which will be a smashi-fication of all the needed ExtJS resources, as well as your custom files. This will be a human-readable collection of all the possible ExtJS and custom scripts that your application uses.

The next, app-all.js, will be a concatenation of all-classes.js and your main, custom app.js file (or whatever you called it). This file will be the one that you ultimately deploy to production…but let’s not get ahead of ourselves.

A few important points here. First, you should take a quick glance through the first “build” to ensure that it does, in fact, have both ExtJS files AND your custom application files. If it doesn’t, there’s something misconfigured in how your application is setup, and you should fix that before moving forward. Second, you’ll notice the placeholders for naming your build. Go ahead and fill that out so your smashed files will have good, meaningful documentation on them.

Everything look good? Excellent! Now it’s time to build some files!

Building app-all.js

After verifying that our app.jsb3 file looks correct and filling out the necessary documentation, we’re now ready to complete the build.

To do that, open Terminal back up again, and make sure that you’re back at your application’s root. To create the build, simply enter the following commands:

sencha build -p app.jsb3 -d .

Simple enough: the “build” command grabs the app.jsb3 file we already created, and uses it as a manifest for creating the build files. Once everything completes without error, you should now notice two additional JavaScript files in your application’s root: all-classes.js and app-all.js.

Now that the build has completed, you can go into your index.html file and replace ext-debug.js with ext.js, and app.js with app-all.js. Open up your application, test, and if everything looks good, you should be ready to deploy with your new minified file.

Here’s what my final index.html file looks like:

<html>
<head>
    <title>Gloss</title>
    <link rel="stylesheet" type="text/css" href="resources/css/ext-all-gray.css">
    <script type="text/javascript" src="extjs/ext.js"></script>
    <script type="text/javascript" src="app-all.js"></script>
</head>
<body>
    ....
</body>
</html>

Something of a Caveat

While the build worked without error for me, I did notice one issue. When I loaded up my app to test, I still saw a few additional JavaScript files being synchronously loaded. Sure, it wasn’t the 70+ from before the build, but it was still a handful–in addition to the main ext.js and app-all.js files.

As I looked closer at *which* files they were, however, I noticed that they seemed to mostly deal with the resources needed for my Viewport. Curious, I opened up my original app.js file, and sure enough, noticed the following:

Ext.application({
    name: "Gloss",
    appFolder: "app",
    autoCreateViewport: true,
    ....
});

While I’m not sure I can verify that this is true, it seems like the issue has to do with the “autoCreateViewport” setting. Perhaps because of the way that the internals of the dependency negotiator works, it misses some of these files while creating the .jsb3 file. Your guess is as good as mine.

Fortunately, there is a pretty dang easy way to fix it. I simply opened up Terminal again and re-ran the .jsb3 create command while leaving the app-all.js file set on my index.html page. When the new .jsb3 file was generated, it included only the resources which were missed in the first go. I simply copied the contents of this .jsb3 file, merged them into my original, and re-ran the build. Voila, no more extra files!

Wrapping Up

Overall, I found the build process to be really nice. Notwithstanding the issue which came from how my application is structured, the steps are very straightforward–it’s much better than the efforts I’ve used in the past.

I hope this walkthrough is helpful to someone, and by all means be sure to let me know if there are areas I can improve upon, corrections I can make, etc.