• page

Thank you for contributing!

Bugs and Feature Requests

Bugs and feature requests should be submitted to steal for issues with module loading and steal-tools for issues building.

The best issues are those submitted with tests. Learn about how to setup a test in the "Developing" sections below.

Developing steal

To develop steal, fork and clone steal. Make sure you have NodeJS installed. Then:

  1. Install npm modules

    > npm install
  2. Install bower modules

     > bower install
  3. Setup grunt watch

     > grunt watch

This will automatically build steal.js and steal.production.js when anything in src changes.

To test, open test/test.html, and make sure everything passes.

Understanding steal's code

steal.js packages two other projects:

And steal.js includes everything in the src folder. On a high level, steal.js is organized like:

/* ES6ModuleLoader */
    /* - Promise polyfill */
!function(e){"object"==typeof ...}
    /* - Loader Polyfill */
    /* - System Polyfill */

/* SystemJS */
(function(__$global) {
  /* meta, register, core, global, cjs, amd, map, 
     plugins, bundles, versions, depCache extensions */

/* start.js
 * - wraps everything in a closure
 * - helpers that are useful everywhere
    // helpers
    var camelize, each, map, isString, extend, parseURI;
/* normalize.js
 * - standalone normalize function
    var normalize = function(){}
/* core.js
 * - starts `makeSteal` that makes `steal`.
    var makeSteal = function( System ){
        var steal = function(){ ... }
/* system-extension-ext.js
 * - the System.ext extension
        var addExt = function(loader) { .. };
/* system-extension-forward-slash.js
 * - module names that end in /
        var addForwardSlash = function(loader) { ... };
/* config.js
 * - overwrites System.config
 * - sets up System.env, System.stealPath, System.bundlesPath
        var setterConfig = function(...){...}
        setterConfig(System,{ ... });
/* startup.js
 * - defines startup code
        var getScriptOptions = function () { ... }
        steal.startup = function(config){ ... }
/* make-steal-end.js
 * - closes `makeSteal`
/* system-format-steal.js
 * - a System extension that adds the `steal` syntax
    function addSteal(loader) { ... }
/* end.js
 * - 
    if (typeof window != 'undefined') {
        window.steal = makeSteal(System);
        window.steal.startup( oldSteal );
    } else {
        global.steal = makeSteal(System);
})(typeof window == "undefined" ? global : window);

Writing a steal test

All tests are in test/test.js. Most tests create an iframe that opens another page like:

asyncTest("test description", function(){

That page typically uses steal to import some modules and when complete calls to the parent window's QUnit assertion methods. For example:

<!-- page.html -->
   <script src='../../steal/steal.js'

window.parent.QUnit.ok(true, "test-module-loaded");

Developing steal-tools

To develop steal, fork and clone steal-tools. Make sure you have NodeJS installed. Then:

  1. Install npm modules

    > npm install
  2. Install bower modules

     > bower install
  3. Install mocha

     > npm install -g mocha

To test, run:

    > mocha test/test.js


Note that if you are using Windows you first need to install a couple of things before you npm install.

  1. Install Python 2.7. You'll want to add the directory to your PATHS (likely C:\Python27).

  2. Install Microsoft Build Tools or Visual Studio Express 2013 depending on which version of Windows you are using. Try the Build Tools but VSE might be needed.

See the Contributing on Windows guide for full instructions.

Understanding steal-tools code

On a high level, steal-tools uses lib/trace.js to figure out all of the dependencies for a module and arange them into a graph. It then transforms that graph into bundles and finally writes out the bundles so they can be loaded by the client in production.

A dependency graph that trace.js produces looks like:

  moduleName: Node({
    load: Load({
      name: moduleName,
      source: SOURCE
    dependencies: [moduleName,...],
    // which [System.bundle] moduleNames this module is a dependency of.
    bundles: [bundleName,...],

Here's an example:

  "jquery": {
    load: {
      name: "jquery",
      source: "jQuery = function(){ ... }"
    dependencies: [],
    bundles: ["profile","settings","login", ...]
  "can/util": {
    load: {
      name: "can/util",
      source: "define(['jquery'], function($){ ... })" 
    dependencies: ["jquery"],
    bundles: ["profile","login"]

A Load is a ES6 load record.

A Node is an object that contains the load and other useful information like the modules:

  • dependencies
  • bundles
  • transformed and/or minified source

The build tools only write to Node to keep Load from being changed. They manipulate this graph and eventually creates "bundle" graphs. Bundle graphs look like:

   // How many bytes this bundle is minified
   size: 231231,
   // The Nodes (and therefore modules) this bundle contains
   nodes: [node1, node2, ...],
   // The [System.bundle] moduleNames this bundle is a dependency of
   bundles: [bundleName1, bundleName2]  

steal-tools code is organized in folders around certain concepts:

  • build - high level build modules like the multi build and pluginify.
  • buildTypes - utitlies for specific buildTypes (like CSS or JS).
  • bundle - transformations around bundle objects.
  • configuration - utility for getting derived configuration values.
  • graph - graph creation and transformation utilities.
  • node - utilities around a node in a graph

Website and Documentation

steal's gh-pages branch contains's code. It uses DocumentJS to produce the website. To edit the docs:

  1. Fork/Clone

     > git clone -b gh-pages
  2. Install NPM dependencies:

     > npm install
  3. Install steal and steal-tools submodules:

     > git submodule init
     > git submodule update
  4. Edit markdown files in steal/docs or steal-tools/doc

  5. Regenerate site and check changes

     > ./node_modules/.bin/documentjs
  6. Checkin and push markdown changes to steal or steal-tools.

  7. Checkin and push gh-pages branch changes.