Skip to content
Matthew Phillips edited this page Jun 27, 2013 · 85 revisions

Steal

Steal provides infrastructure for managing dependencies in your projects. It allows you to code modularly, with development being as easy as refreshing the browser. Steal's build tools will package all of your app's dependencies together to limit the number of requests in your production environment. Steal is unopinionated on the flavor of module syntax you choose with support for AMD, CommonJS, Steal, and Harmony.

Installation

npm install -g steal

Installing steal gives you steal.js and the steal build tools. Steal.js is the dependency management core of your application. In development it allows you to make changes and see them simply by refreshing the page. The steal build tools are what you'll use to create the production version of your app, or distributable versions of your library.

Start using Steal

To get Steal setup simply type the following command within the root folder of your project:

steal install

This sets up steal.js in your project. Steal.js is the only script tag you'll need in your application. It does dependency management and loads plugins for things like Less and CoffeeScript compilation. Once you've installed steal.js, you can start using it in your project immediately. Just add the script tag to your page:

<script src="steal.js?app"></script>

Building an app

Your app can be structured to fit your needs, but roughly speaking you might have something like:

  • stealconfig.js
  • steal.js
  • app/
    • app.html
    • app.js
    • adder/
      • adder.js
    • my_module/
      • my_module.js
      • my_module.less

In the script tag you set up earlier there is a parameter being passed to steal, app. This tells steal that the starting point for your application (the main file) is at app/app.js. So now let's open up that file and begin coding.

app.js

Steal lets you chose from several popular module loading syntaxes. If you've used node.js before you're probably already familiar with CommonJS. A goal of the steal project is to allow you to code in any style you like, as well as import code that uses other syntaxes into your project. Some of your dependencies may come from NPM, Bower, or the web, and use any number of module syntaxes. It shouldn't be your job to convert each dependency, it should just work.

Here's a quick overview of each style. Let's say you defined a steal module called adder. Adder takes a number a and returns a function that, when called, returns the sum of a + b.

adder.js

steal(function(){
  function adder(a){
    return function(b){
      return a + b;
    };
  }

  return adder;
});

Steal

Steal comes with it's own syntax using the global steal function. Steal adds features on top of traditional dependency management, such as plugins for CoffeeScript and Less. When stealing modules, you can point to a folder, say adder and steal will fetch the file adder.js by default. You can, of course, also point to specific files.

Since steal is able to fetch non-code files like css, whose contents are simply inserted into the dom, those values will be set to undefined in the callback. For this reason, it's better to put your JavaScript dependencies in the front.

steal('./adder', './my_module', './app.css', function(adder, myModule){
  // Use adder, myModule

  var addFive = adder(5);
  addFive(2); // -> 7
});

AMD

Superficially AMD looks similar to steal, with the biggest differences being the use of the global function define which takes an array as the first argument (as opposed to listing the dependencies) as separate arguments. If you are not defining a module, but rather just using other modules (as you would be doing in your main .js file), use require instead.

Listing all of the features of AMD is beyond the scope of this guide, however steal supports the full AMD spec, including loader plugins.

require(['./adder/adder', './my_module/my_module'], function(adder, myModule){
  // Use adder, myModule
  var addFive = adder(5);
  addFive(10); // -> 15
});

CommonJS

CommonJS is different from steal and AMD in that it is flat; no wrapper function is needed. This presents a challenge for module loaders; you can't simply inject the scripts into the page. Some other loaders work around this by requiring a wrapper function that includes the arguments module, exports, and require. However this means you can't bring in dependencies from Node.js (which doesn't require a wrapper script) without modifying them. Other module loaders work around this problem by asking you to build your app every time you make a modification, so you lose the live reload capability.

Steal gives you the best of both works. CommonJS modules are flat, just like in Node, and you can develop your app simply by refreshing the browser.

Building on our adder module, you can use it in your main app.js CommonJS file like so:

var adder = require('./adder/adder')
  , addFive = adder(5);

addFive(3); // -> 8

Others

Alternative syntaxes can be defined as plugins. In fact all of the existing syntaxes are defined this way already. Consult the API on configuring syntax for more information.

Building for production

Once you are ready to release your app you should bundle up all of your app's resources by using Steal's build command. Building is as simple as:

steal build app/app.js

Which will produce app/production.js with all of your JavaScript dependencies and app/production.css with all of your css (if you have any).

Grunt

Alternative, if you use Grunt, there is a grunt task that you can use in your Gruntfile. Here's an example of a simple Grunt configuration for typical applications:

steal: {
   build: ['path/to/app.js', 'path/to/app2/app2.js']
}

Programmatic

Build can also be used programmatically in Node.js. If you wanted to integrate steal-build into your own build process you might use it like so:

var build = require("steal").build;

build("app/app.js", function(){
  // All done
});

Packages

Typical single page applications have one big file download that contains all the JavaScript needed by the application. Steal allows you to break up that one file concise seperate modules and dynamically creates packages for overlapping dependencies and load them on-demand.

For example, say your website has 3 different modules that define your application: tasks, account, chat. Each of these modules probably have overlapping dependencies such as controls like a modal or CSS styles.

		App
		 |
   /     |     \
tasks  chat   account
   \    /
    modal

As the application grows it becomes difficult to manage the shared dependencies and determine the overlap given the different modules. Steal handles this dynamically with the Packages plugin; simply define each top-level package like:

steal.config("packages", ["chat", "tasks", "account"]);

steal('./app', function(App){
	
  return new App({
    '.chat click':function(){
      // say the user clicks chat link, 
      // now we need to load the package
      // based on this logic
      steal('chat', function(Chat){ ... });
    }
  });
		
});

Steal will dynamically generate a depedency map at build time that defines each package along withs it CSS and JavaScript depedencies.

In this example, steal created a shared depedency between chat and tasks that is only downloaded when one of those are invoked. Thats it!

Switching to Steal

Since Steal supports CommonJS and AMD, switching from other module loaders requires minimal effort. Steal supports the data-main attribute that RequireJS uses so you can switch your script from:

<script data-main="scripts/main" src="scripts/require.js"></script>

to:

<script data-main="scripts/main" src="steal.js"></script>

Distributing

Steal makes it easy to distribute your application in a variety of formats depending on your needs. Steal makes it easy to convert your project to other formats. For example, you might develop a library in AMD, but want to distribute it as CommonJS and Steal, creating dist/my_lib.amd.js, dist/my_lib.commonjs.js, and dist/my_lib.steal.js. You can accomplish this by running:

steal build --to commonjs my_lib.js
steal build --to steal my_lib.js

You might also want to build your project with steal.js packaged.

steal build --with-steal my_lib.js

Package your app as a standalone and send to another folder. The standalone can be added to your page in a script tag without needing steal.js.

steal build --standalone app.js --out scripts/app.production.js

Steal also includes a multi-build system that, like packages, allows you to share dependencies between modules. To build with the multi-build, simply pass all of your applications into steal-build:

steal build apps/app1/app1.js apps/app2/app2.js --packages-out packages/

See steal-build's help documentation for the full command line options.

Usage: steal-build [options] <file ...>

Options:

  -h, --help         output usage information
  -V, --version      output the version number
  -o, --out [folder] Name of the application folder
  -t, --to [syntax]  Syntax to convert project to
  -s, --standalone   Create a standalone version without steal
  -w, --with-steal   Package steal along with <files>
Clone this wiki locally