JS Days 2025 is now live – Join 5,000+ devs for the premier virtual JavaScript event. Register Now

Understanding Sencha Cmd Packages

November 19, 2013 5215 Views
Show

introducing-ext-js-4-2In April of this year, as part of the rollout of Ext JS 4.2 and the new Neptune theme, we introduced support for packages in Sencha Cmd 3.1. At that time, packages were primarily targeted at themes but obviously themes are not the only use case for self-contained bundles of JavaScript, Sass and resources. In this article, we’ll dig into some of the inner workings of packages and see how to leverage them for perhaps their most common use case: to share code between applications.

Setting The Stage

In Sencha Cmd, applications exist in a Workspace. A Workspace is just a root folder of your choice where common things like applications, packages and Sencha frameworks reside. It is common to pick the root folder in source control to be the Workspace, but this is not required. For this article, we will create a test Workspace in an empty folder:

C:Test> md wksp
C:Test> cd wksp
C:Testwksp> sencha generate workspace .
Sencha Cmd v4.0.1.45
...

To get the ball rolling, let’s set up two Ext JS applications in this Workspace. By default, when we run “sencha generate app” we will get a Workspace as well as the application, and they will be in the same folder. That is, unless we generate the application in an existing Workspace, like the one we just created.

The following commands point Sencha Cmd at the Ext JS 4.2.1 downloaded and expanded zip file. The first Ext JS application we generate in the Workspace copies the necessary subset of the Ext JS SDK (or “framework”) into the “ext” folder. The second generated application does not need to do this as it will share the framework already in the Workspace.

C:Testwksp> sencha -sdk ../ext421 generate app ExtApp1 extApps/app1
Sencha Cmd v4.0.1.45
...
[INF] Workspace does not have framework ext at C:Testwksp ... copying
...
C:Testwksp> sencha -sdk ext generate app ExtApp2 extApps/app2
Sencha Cmd v4.0.1.45
...

Now, we have a Workspace, a subset of Ext JS and two empty applications in a folder structure that looks like this:

wksp/
        ext/             (A copy of the necessary files for Ext JS)
                packages/    (Packages provided by Ext JS)
        extApps/
                app1/
                app2/
        packages/        (A folder for non-framework packages)

Let’s Make A Package

Packages can be generated in a manner similar to applications like so:

C:Testwksp> sencha generate package common
Sencha Cmd v4.0.1.45
...

The key difference here is that the new package is placed in the “packages” folder:

wksp/
        ...
        packages/
                common/
                        resources/
                        sass/
                        src/
                        package.json
                        ...

To make use of this package in our applications, we add it to their respective “app.json” files in the “requires” array:

"requires": [
        "common"
]

What Does That Do?

The most obvious thing it does is incorporate the JavaScript payload from the “common” package into the build for these applications. It does it at the level of the “classpath”. In Sencha Cmd, each application (and package) has its own classpath. By default, the applications both have this setting in their respective “.sencha/app/sencha.cfg” files:

app.classpath=${app.dir}/app

And a package has this setting in its “.sencha/package/sencha.cfg” file:

package.classpath=${package.dir}/src

By virtue of the “requires” in “app.json”, the “package.classpath” for each required package is added (along with the “app.classpath”) to the compiler’s internal (total) classpath. All JavaScript files in these locations are scanned by the compiler and available for use.

To streamline these settings for use by applications, the information gleaned by the compiler is exported into what is called the “bootstrap”. If you are already familiar with the “Ext.Loader.setConfig” or “Ext.Loader.setPath” APIs, you won’t be needing them! Instead, you’ll find all the paths needed (and more) in your application’s “bootstrap.js” file.

This is not all that the package dependency accomplishes but that is enough for starters.

Using The Package

What’s next? A common (incorrect) assumption is that we must first build the package using “sencha package build” before it is useful to our applications. In fact, all that Sencha Cmd needs to use a package is knowledge of its classpath.

That means that the correct answer to this question is: we need to “refresh” the application’s bootstrap. If you are using the (new to Cmd v4) “sencha app watch” command then all of the necessary steps will be taken by restarting the watch. Adding package dependencies is not something that “sencha app watch” currently handles internally, so the manual restart is needed for now. As new classes are added to this package, however, app watch will detect these and automatically refresh the bootstrap.

While Sencha Cmd requires Java 6 for most functionality, “sencha app watch” depends on Java 7. If this is an issue, you can alternatively use the command that was available prior to Cmd v4: “sencha app refresh”. This command does exactly and only what is needed for this case. In Cmd v4, this is now just a convenient way to run the “refresh” target of the app build. In other words, “sencha app build” will also refresh the bootstrap… as well as build the Sass and a few other things.

What Does “sencha package build” Do?

The generated build script for packages (the implementation of “sencha package build”) handles two use cases: 1) produce a build of the package source for non-Cmd applications (similar to the “ext-all.js” file) and 2) prepare the package for distribution. Neither of these is required for a local package in a Workspace with Cmd-based applications, so we can ignore package builds entirely for this scenario.

These topics are covered thoroughly in the guides, so check them out for more details.

Packages With Components or Views

We have a Workspace with two (mostly) empty applications, the Ext JS SDK and a package named “common”. The applications are prepared to use any code we add to the common package, but things get interesting when we want to share complex things like custom components or perhaps Views for an MVC application. The complications come from the two “other” types of content needed to share such things: styles and resources (such as images).

Sharing Sass

Given that packages were originally designed to solve the requirements of themes, it should come as no surprise that packages can contain Sass source code (the dialect of “CSS++” used by Sencha frameworks) and that Sencha Cmd understands how to incorporate this code into your application’s build.

Prior to packages, there was no clean way to know the relationship between Sass source files and their corresponding components. This meant manually controlling the inclusion of the *.scss files you needed, based on the current state of the application’s JavaScript code.

With packages, however, Sencha Cmd provides the logic to link JavaScript classes to their associated Sass code. This is done by class name correspondence. For example, the “Ext.button.Button” class would have an associated “button/Button.scss” file or files, depending on your theme.

This has been the recommended way to organize the JavaScript code for these classes, which makes it a natural choice for these other source files. By virtue of this correspondence, the generated CSS file will only contain the styles for those components actually used by your application, and they will cascade from base class to derived class, as you would expect.

There are many other details related to this correspondence covered in the Themes guide. This aspect of packages does not currently apply to Sencha Touch applications.

Sharing Resources

One of the more interesting challenges for composing applications from multiple packages is how to isolate their respective resources. When two packages are written, they will not likely be aware of each other, and yet, they must somehow coexist in applications that want to use them together. In JavaScript, this is done by namespacing, but what about images?

In Ext JS themes, there is a Sass function used to resolve image paths given just the filename: theme-background-image. This function applies the proper prefix and even file type suffix (“.gif” or “.png”) based on other configuration properties. It is used like this:

.foo {
        background-image: theme-background-image('foo');
}

For themes, the “resources” folders of the packages in the theme’s inheritance hierarchy are flattened on top of each other. This allows derived themes to selectively override image assets from base themes. All of these resources are copied into the “resources” folder of the built application, typically in “resources/images”. That is:

build/
        resources/
                app-all.css
                images/
                        foo.gif

The Sass is compiled to produce the CSS file in the “resources” folder. This means that the relative paths generated for theme images will be optimally short: “images/foo.gif”. This is another way Cmd helps cut your download size.

This same method also works for non-theme packages. The only difference is that the “resources” folder for such packages is copied into a subfolder of the application’s “build/resources” folder named by the package:

build/
        resources/
                app-all.css
                images/
                        foo.gif
                common/
                        images/
                                foo.gif

Image paths for non-theme images will be slightly longer: “common/images/foo.gif”.

Does Sencha App Watch Handle All This?

Yes. As files are added or modified in any of the “sass” and “resources” folders, they are automatically picked up. Changes to Sass files trigger incremental Compass builds. Likewise changes to any of the resources folders are synchronized to the build/resources folder. In a matter of a few seconds after the file system settles, the bits should be ready for a reload in the browser.

Packages In Action

Here are some links to Git repositories where you can see some of these things and more in use:

  • This repository has an example theme package and a custom button component package.
  • This repository has the custom button component that uses theme base colors, provides its own Sass mixin and an example application that shows off two different “UIs” made from the mixin.
  • This repository contains two Workspaces with different arrangements of Sencha Touch and Ext JS applications sharing code between each other using packages.

For general information about packages, you can check out the Packages guide.

Recommended Articles

Guide to Estimating ROI When Switching From DIY Libraries to Full Software Development Platforms Like Ext JS

Teams started with Do It Yourself, or DIY, JavaScript tools like jQuery and Bootstrap. But those fall apart as projects scale. Scattered code, user interface…

Top Frameworks Developers Are Using for Custom Software Development in 2025

We’re seeing it more every year; teams aren’t settling for plug-and-play tools anymore. In healthcare, finance, logistics, and other data-heavy industries, there’s a clear shift.…

Meet Sencha AI Coding Companion: Your AI-Powered Assistant for Faster Ext JS Development

Building modern web applications should be exciting. But too often, developers find themselves buried in documentation, endlessly Googling framework quirks, or stuck solving the same…

Ext JS 7.9 & Rapid Ext JS V1.1 Have Arrived

The Sencha team is excited to announce the latest Ext JS version 7.9 and Rapid Ext JS 1.1 release – designed to accelerate development, enhance…

Top 10 JS Grid Customization Tips for a Better UI Experience

Grids are pretty much everywhere in web apps. Working with financial sheets, product details, or users? Then you’ve probably used a JavaScript grid. It makes…

Why Ext JS Framework is the Go-To Framework for Building Scalable and Data-Intensive Web Apps

Web apps are much more advanced now. They deal with large amounts of data and need to stay fast, even with many users. If you’re…

View More

Trusted by Top Developers: Learn how to enhance your development journey — for free

Get the latest newsletter keeping thousands of developers in the loop.

Loved by developers at