Contributing

  • page
guides.Contributing  

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. Run tests (this will run other scripts needed to set up tests correctly)

     > npm test
    
  4. Setup grunt watch

     > grunt watch
    

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

Understanding steal's code

steal.js core files are located in the src folder, two important folders are:

Other core extensions can be found in this folder:

  • src/json - Provides the JSON module format definition
  • src/env - Adds some special environment functions to the loader

Each of this folders is self contained, meaning, each folder include their own test files; in order to run the tests just find the test html page which should be located at the root of the folder and open it in your browser.

E.g: to run the tests of the src/base extension just open src/base/base_test.html and make sure everything passes.

Please note that when running invidivual test pages you might need to re-build some files to see your changes, run grunt build after saving your changes to update the files.

On a high level, steal.js is organized like:

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

/* StealJS core extensions */
(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
 */
(function(global){
    // 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) { .. };
        addExt(System);
/* system-extension-forward-slash.js
 * - module names that end in /
 */
        var addForwardSlash = function(loader) { ... };
        addForwardSlash(System);
/* 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) { ... }
    addSteal(System);
/* end.js
 * - 
 */
    if (typeof window != 'undefined') {
        window.steal = makeSteal(System);
        window.steal.startup( oldSteal );
        ...
    } else {
        require('systemjs');
        global.steal = makeSteal(System);
        ...
    }
})(typeof window == "undefined" ? global : window);

Writing a steal test

Most tests create an iframe that opens another page like:

QUnit.test("test description", function(assert) {
    makeIframe("path/to/page.html", assert);
});

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 -->
<html>
   <script src="../../steal/steal.js"
           main="test-module">
   </script>
</html>

// test-module.js
window.parent.assert.ok(true, "test-module-loaded");
window.parent.done();

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

Windows

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 stealjs.com's code. It uses DocumentJS to produce the website. To edit the docs:

  1. Edit markdown files in steal/docs or steal-tools/doc

  2. Fork/Clone https://github.com/stealjs/stealjs:

     > git clone https://github.com/stealjs/stealjs.git
    
  3. Install NPM dependencies:

     > npm install
    
  4. Regenerate site and check changes

     > npm run document
    
  5. Checkin and push gh-pages branch changes.

This workflow requires that the markdown changes to steal or steal-tools made in the first step were published to npm; if the changes are only local, you could use npm link to use the steal with the updated markdown files.