Sharing front-end assets and modules
Current in-house web projects
- Shareplan Web
- Crashplan Console
- Crashplan Console In-app Purchase
- code42.com
- code42.com/crashplan
- code42.com/enterprise-store
- Sales42
- Several others and more to come
Sharing is built in the open source ecosystem
We have our own ecosystem here
Sharing needs to be built into our ecosystem

39 repos extracted to be shared
Things are improving
Room for improvement
- Built in assumptions about load order
- Built in assumptions about framework
- Poor documentation
- Documentation is hard w/out something like gh-pages
- Poor test coverage
- No test automation (need CI server)
- No code linting as part of test automation
- Load order assumptions
- Unknown dependencies
- Peer dependency assumptions
- Inconsistent directory structure
- Inconsistent style
- "Nobody" owns the code
- This "Nobody" jerk is a terrible maintainer
Sources for sharing front-end assets
- npm
- bower
- github/bitbucket/stash repo
- rubygems
- rails-assets
- CDN script tag (haha)
Methods for sharing front-end assets
Modules value propositions
- Well known dependencies
- Well known exports
- Fewer/Zero Globals
- Avoids namespacing
- Shareable pieces of code
- Testable pieces of code
- Necessary for organization of a large codebase
There's a lot of controversy on the topic, (10m searching)
There are several implementations
Sync Modules - CommonJS (browserify, webpack, node)
// example.js
exports.hello = function() {
return 'Hello World'
};
// consumer.js
var example = require('./example.js');
example.hello();
- ↑: very easy to reason about load order
- ↑: easy to understand dependencies
- ↓: requires dependencies to already be loaded
- ↓: requires a specific load order
Async Modules - AMD (RequireJS, Almond, curl.js)
// example.js
define(function(){
return {
hello: function() {
return 'Hello World';
}
};
});
// consumer.js
require(['example'], function(example){
example.hello();
});
- ↑: easy to understand dependencies
- ↑: fine-grained control over code loading
- ↑: has potential to be faster in certain cases
- ↓: definitely harder to reason about
Globals w/namespacing
// example.js
window.example = {
hello: function() {
return 'Hello World';
}
};
// consumer.js
window.example.hello();
- ↑: very easy to reason about
- ↓: hidden dependencies
- ↓: can be clobbered by other third-party libs
- ↓: requires dependencies to already be loaded
- ↓: every module creates a global unless namespaced
ES6 Modules
// jquery.js
// ...
export var $;
System.paths['jquery'] = '//code.jquery.com/jquery-1.10.2.min.js';
System.import('jquery').then(function($) {
// ...
});
Similar upsides and downsides as AMD
Less ceremony around defining the module
ES6 Final Draft slated for 2015
Takeaways
- Using any modules is better than using globals
- Doesn't really affect Angular-only libraries/apps
- Does affect framework agnostic libraries
- Sharing code can be harder than it sounds
- We have to make it as easy as possible to share
Recommended Reading
