-
Notifications
You must be signed in to change notification settings - Fork 522
Getting Started
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.
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.
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 for your project, and loads plugins for things like Less and CoffeeScript compilation. Once you've install
ed 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>
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.
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 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
});
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 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
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.
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).
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
});
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!
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>
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/