Skip to content
Matthew Phillips edited this page Jun 26, 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.

Start using Steal

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

steal install

Which will create the files stealconfig.js and stealjs/steal.js.

then add a script tag to your page:

<script src="stealjs/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
  • stealjs/
    • steal.js
  • app/
    • app.html
    • app.js
    • adder/
      • adder.js
    • my_module/
      • my_module.js
      • my_module.less

In order to make the creation of your application's skeleton easier you can use a Yeoman generator.

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.

Here's a quick overview of each style. Let's say you defined a steal module called adder.

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 command. Steal will load JavaScript, CoffeeScript, Css and Less, as well as a variety of templates. 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 consultation on steal.syntax for more information.

Building for production

Once you are ready to release your app you should bundle up all of your apps 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).

Alternative, if you use Grunt, there is a grunt task that you can use in your Gruntfile.

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('./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){ ... });
    }
  });
		
}).packages('chat', 'tasks', 'account');

Steal will dynamically generate a depedency map at build time that defines each package along withs it CSS and JavaScript depedencies. The end generated code will resemble something like:

-- production.js -- 
steal.make({ 
	id:"wildcat/packages/chat.css", 
	has:"chat.css", 
	needs: [ "chat-tasks.js", "chat-tasks.css" ] 
});

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="scripts/steal.js"></script>

Convert project

Using steal-convert you can convert your projects to use a different syntax. For example, say you had a steal script that you wanted to convert to CommonJS:

main.js

steal('module1', 'module2', function(module1, module2){ ... })

Then to convert simply run steal convert --to commonjs and your complete dependency tree will be converted. The main.js you defined above will now look like:

var module1 = require('module1')
  , module2 = require('module2');

Create standalone

With Steal you can create create a standalone version of your app that doesn't depend on steal. This is useful if you want to reduce your requests to only 1. To create a standalone type:

steal build --standalone app

or

steal build -s app

Which will produce a single .js file that can be directly inserted into a script tag, like so:

<script src="app.js"></script>
Clone this wiki locally