Basics
Why it's crazy awesome
- Supports every module format
- Load dependencies from npm and bower
- Build to bundles that optimize for caching and code reuse
- Export your library to every format
- Lots of plugins available; Less, Sass, QUnit, Jasmine, JSX, Conditionals, Cache Busting
- Hot module swapping
- Source maps
Core Projects
Module Loader
- es6-module-loader
- SystemJS
- Steal
- system-npm / system-bower
- steal-css & steal-less
- live-reload
Build Tools
- StealTools
- Transpile
Module Names
- The key (or id) in a registry of modules (like a database)
- Usually resolve to a file in your project (or a dependency)
- Also could reflect modules dynamically created.
- can/map/define/define
-
place-my-order/restaurant/list/list.stache!can/view/stache/system
- place-my-order (package name)
- restaurant/list/list.stache (module path)
- stache
- place-my-order/index.stache!done-autorender
Examples
Module Identifiers
define([
"can",
"./routes",
"@loader",
"form.stache!"
], function(){
});
app.js
Names used to identify modules in the context of another module.
Example
Current module:
Current address:
login
http://localhost/app/login/login.js
// login.js
define(["./form"], function(){
});
Importing:
./form
Normalized name:
form
Address:
http://localhost/app/form.js
Base Url:
http://localhost/app
Name-normalization
{
"login": {
"validation": {}, // -> "login/validation"
"models": {
"user": {}
}
},
"form": {
"submission": {}
}
}
├── login/
| ├── models/
| | ├── user.js
| ├── login.js
| ├── form.js
| ├── validation.js
Better
login/login
login/form
Steal syntax
steal("login");
login/login
app
login/login
steal("./validation");
login/validation
steal("./form.js");
login/form
Configuration
System.configMain
- stealconfig
- config
- my-config
- package.json!npm
- bower.json!bower
Forms
<script src="steal.js" data-config="config.js"></script>
<script src="node_modules/steal/steal.js"></script>
<script src="bower_components/steal/steal.js"></script>
<script src="node_modules/steal/steal.js" data-config="bower.json!bower"></script>
<script src="steal.js" config="package.json!npm"></script>
stealconfig.js
System.config({
"paths": {
"socket.io-client": "lib/packages/socket.io-client.js"
},
"meta": {
"socket.io-client": {
"format": "global"
}
},
"ext": {
"stache": "can/view/stache/system"
}
});
package.json
{
"name": "place-my-order",
"version": "0.0.0",
"system": {
"map": {
"socket.io-client": "socket.io-client/socket.io"
},
"meta": {
"socket.io-client/socket.io": {
"format": "global"
}
}
}
}
Map
- Changes a module name to another module name
- Like an alias
Examples
lodash
System.config({
map: {
underscore: "lodash"
}
});
{
"name": "place-my-order",
"version": "0.0.1",
"system": {
"map": {
"socket.io-client": "socket.io-client/socket.io"
}
}
}
Socket.io
Paths
Specify the location of a module relative to the baseURL
CanJS
System.config({
paths: {
"jquery": "lib/jquery.js",
"can": "lib/can/can.js",
"can/*": "lib/can/*.js"
}
});
Meta
Additional metadata about a module.
Mostly this is for globals
System.config({
meta: {
"jquery-datepicker": {
exports: "jQuery",
deps: ["jquery"]
}
}
});
Example
Ext
Like map, but applies to extensions.
Stache
System.config({
ext: {
stache: "can/view/stache/system"
}
});
define([
"./list.stache!"
], function(listTemplate){
...
});
stealconfig
restaurant/list
system-npm
An extension to load dependencies from node_modules
Crawling algorithm
https://github.com/stealjs/system-npm/blob/master/npm-crawl.js
├── node_modules/
| ├── can
| | ├── package.json (deps: jquery)
| | ├── node_module/
| ├── jquery
| | ├── package.json
| ├── bit-tabs
| | ├── package.json (deps: can)
| | ├── node_modules/
package.json
{
"name": "place-my-order",
"version": "0.0.1",
"dependencies": {
"can": "^2.3.0-pre.8",
"bit-tabs": "0.1.0-pre.1"
},
...
}
place-my-order/
Module names
Needs
- Module names must be distinct
- Module names must be friendly
- Multiple versions presents a problem
// app.js
define(["can"], function(can){
});
// system-npm
var normalize = System.normalize;
System.normalize = function(name, parentName){
var pkg = npmUtils.getPackageByName(name, parentName);
// pkg.name === "can"
// pkg.main === "can.js",
// pkg.version === "2.3.0-pre.7"
return "can@2.3.0-pre.7#can";
};
Parts
can@2.3.0-pre.7#map/map
package name
package version
module path
{
"name": "place-my-order",
"version": "0.0.0",
"system": {
"meta": {
"can/util/vdom/vdom": {
"sideBundle": true
}
}
}
}
Configuration
can@2.3.0-pre.7#util/vdom/vdom
Debugging Tricks
Stack traces
Not pretty, but useful
Who imported me?
<script src="node_modules/steal/steal.js"></script>
<script>
var oldNormalize = System.normalize;
System.normalize = function(name, parentName){
return oldNormalize.apply(this, arguments).then(function(name){
if(name === "my/module") {
console.log(name, "is imported by", parentName);
}
return name;
});
};
</script>
https://gist.github.com/matthewp/1ce67c491fd3e6f18788
StealJS: High Level
By Matthew Phillips
StealJS: High Level
Everything you need to know to use and understand StealJS.
- 809