Skip to content


Subversion checkout URL

You can clone with
Download ZIP
tree: ae9809e080
Fetching contributors…

Cannot retrieve contributors at this time

274 lines (207 sloc) 10.311 kb


The Shaker recipe is one part convention and one part configuration. The convention lies in the structure of a mojit or application's assets directory. The configuration lies in a mojit or application's shaker.json file, which defines rollups and their contents.

Context Dimensions

Before going any further, it is important to understand the core concept of Shaker rollups: context dimensions.

Context dimensions are the basic building blocks of Shaker rollups. Shaker supports the following dimensions by default:

  • common - Resources not specific to any dimension.
  • action - Action-specific resources (it matches the controller action).
  • device - Device-specific resources.
  • skin - Skin-specific resources.
  • region - Region-specific resources.
  • lang - Language-specific resources.

The default dimensions are listed here in ascending priority order. This means that a dimension that appears later in the list is capable of augmenting previous dimensions. In order to create new dimensions, you will have to define your own dimensions.json file, and at runtime set those dimensions to some value since they are not built into Mojito. See the section about Advanced Configuration

Convention: Assets Directory Structure.

Shaker prefers a mojit or application's assets directory be structured according to the context dimensions it is sensitive to. A directory structure that follows these conventions is called conforming. A directory structure that does not follow these conventions is called non-conforming.

A conforming directory structure is quite simple to configure (basically, it does not need any configuration at all). A non-conforming directory structure is also supported, but requires a bit more effort to configure. See the section on Advanced Configuration for more information.

Example: The basic assets directory structure of a conforming mojit.


Example: The assets directory structure of a conforming mojit, FooMojit, that is sensitive to the common and region dimensions.


In the the above example, FooMojit has common CSS regardless of the value of any other dimension. In addition, it has additional CSS when the region dimension value is US or CA.

Example of shaker configuration based on the previous folder structure:

  "dimensions": {
    "common": {},
    "region": {
      "US": {},
      "CA": {}
    "lang": {
      "en": {}

The following table illustrates the content of the rollups for FooMojit for various values of the region dimension.

Region Value Data Type
  • common/foo-common.css
  • common/foo-common.css
  • region/US/foo-US.css
  • common/foo-common.css
  • region/CA/foo-CA.css

In the above example, the region dimension maps directly to a conforming assets directory structure.

Because each dimension is declared with the empty object ({}), Shaker includes all assets found within the corresponding directories (and subdirectories) when generating the corresponding rollup.

For more control over what gets included in a rollup, see the Advanced Configuration section.


The actions section tells Shaker which controller actions (binders) the mojit or application is sensitive to. Shaker also analyzes which dimensions your mojits and actions are sensitive to in order to generate at the necessary rollups.

Actions at mojit level

This is the representation for the default shaker configuration at mojit level:

    "actions": {
        "*": {},
    "order": "common-action-device-skin-region-lang"

If you have any binder in your mojit, shaker will analyze it for you, creating some structure like this:

Example: A mojit sensitive to the index and show controller actions (binders).

    "actions": {
        "*": {},
        "index": {},
        "show": {}
    "order": "common-action-device-skin-region-lang"

**Note that you don't have to write any configuration for any case if you use the default folder structure.

Actions at the app level

The configuration at the app level is exactly the same as at the mojit level, with only one difference: you can specify which mojits you want to bundle per action. Bundling a mojit means that these mojits' assets will be included within the app rollup, avoiding to request additional rollups for those mojits.

Example: App shaker configuration bundling different mojits per action:

    "actions": {
        "*": {
        "appAction1": {
        "appAction2": {

    "order": "common-action-device-skin-region-lang"

Environment Configuration

Shaker allows you to rollup your assets and deploy them in a variety of ways based on the environment context. All that is necessary is to provide a shaker config per environment in your application.json file. A shaker config specifies what task to run and any additional settings the task depends on.

Example: Sample application.json shaker setup using several environments:

    "settings": ["master"]
}, {
    "settings": ["environment:test"],

    "shaker": {
        "task": "local"
        "lint": false
}, {
    "settings": ["environment:stage"],

    "shaker": {
        "task": "s3",
        "images": true,
        "config": {
            "client": {
                "key": "<key>",
                "secret": "<secret>",
                "bucket": "<bucket>"

Shaker Settings

  • task - {string} Name of task to execute (local, s3). Defaults to null which runs in dev mode.
  • compiled_dir - {string} Where to output Shaker generated files. Defaults to assets/compiled/.
  • images - {boolean} Whether to deploy images with rollups. Useful if your CSS contains relative URLs to assets. Defaults to false.
  • parallel - {integer} How many files to deploy in parallel. Defaults to 20.
  • delay - {integer} Add network delay for slow hosts. Defaults to 0.
  • lint - {boolean} Run lint on app files. Defaults to true.
  • minify - {boolean} Minify JS and CSS. Defaults to true.
  • config - {object} Object passed through to task.

To build a particular environment, run the shaker command like so: mojito shake --context environment:<env>

As we saw in the Components section, we have different deployment tasks. Next we will see how to use each based on the example application.json above.

Deploying raw (no rollups, developer mode)

mojito shake --run

Deploying locally (rollups, developer mode)

mojito shake --context environment:test --run

Deploying to S3 (Amazon CDN)

mojito shake --context environment:stage --run

Deploying elsewhere

All tasks are actually Gear.js ( tasks. It's easy to write your own. There are many examples in the Gear source. Simply write your custom task, drop it in the tasks directory, and reference it in the shaker config like any other task. Everything in the tasks directory will be automatically picked up.

Advanced Configuration


If the default directory-based rollup behavior is not desirable, or if the assets directory is non-conforming, it's still possible to configure rollups using the include, exclude and replace settings.

  • include - Include one or more paths or files. (Useful for mojit- and application-level configuration.)
  • exclude - Exclude one or more paths or files. (Useful for application-level configuration.)
  • replace - Replace one or more paths or files with new paths or files. (Useful for application-level configuration.)

Example advanced configuration:

    "dimensions": {

Augmenting Dimensions

Shaker allows you to perform surgical manipulation of the rollups using augmentation. This configuration feature allows you to include/exclude files for a particular dimension which matches some criteria. For example, we want to override a special CSS file only when we are in "region:CA and in lang:en". The syntax follows the example below.

shaker.json example for dimensions augmentation:

            "on": {
                "region": "US",
                "lang": "en",
                "skin": "blue",
                "device": "smartphone",
                "action": "index"
            "exclude": ["lang/"]
Jump to Line
Something went wrong with that request. Please try again.