Upload
jakob-heuser
View
3.182
Download
2
Embed Size (px)
DESCRIPTION
Given at the Front End Developers United Meetup in Mountain View, CA
Citation preview
©2012 LinkedIn Corporation. All Rights Reserved.
INJECTJakob Heuser – maintainer@InjectJS
©2012 LinkedIn Corporation. All Rights Reserved. 2
©2012 LinkedIn Corporation. All Rights Reserved. 3
©2012 LinkedIn Corporation. All Rights Reserved.
©2012 LinkedIn Corporation. All Rights Reserved.
©2012 LinkedIn Corporation. All Rights Reserved.
©2012 LinkedIn Corporation. All Rights Reserved.
LINKEDIN UED©2012 LinkedIn Corporation. All Rights Reserved. 8
LinkedIn’s Web Development
6+ Vertical Engineering Groups 80+ Web Developers (horizontal) linkedin.com
– Main Site– Tools for Recruiters– Mobile Products
Performance is a shared goal in the frontend
©2012 LinkedIn Corporation. All Rights Reserved.
Performance has Come a Long Way
LINKEDIN UED©2012 LinkedIn Corporation. All Rights Reserved. 10
LINKEDIN UED©2012 LinkedIn Corporation. All Rights Reserved. 11
In The Beginning
<script type="text/javascript" src="jquery.js"></script> <script type="text/javascript" src="shared.js"></script> <script type="text/javascript" src="app.js"></script></body></html>
LINKEDIN UED©2012 LinkedIn Corporation. All Rights Reserved. 12
In The Beginning
Blocking (less painful in the footer) Very manual May not have needed everything you were loading
LINKEDIN UED©2012 LinkedIn Corporation. All Rights Reserved. 13
Async loading
var load = ['jquery.js', 'shared.js', 'app.js'];var head = document.getElementById('head')[0];var scr;for (var i = 0, len = load.length; i < len; i++) { scr = document.createElement('script'); scr.type = 'text/javascript'; scr.src = load[i]; head.appendChild(scr);}
LINKEDIN UED©2012 LinkedIn Corporation. All Rights Reserved. 14
Async Loader Libraries
LINKEDIN UED©2012 LinkedIn Corporation. All Rights Reserved. 15
Things got better
$LAB .script("jquery.js") .script("shared.js").wait() .script("app.js").wait(function() { // all code loaded });
LINKEDIN UED©2012 LinkedIn Corporation. All Rights Reserved. 16
Framework natives
// in your app code...YUI({ modules: { 'shared': { fullpath: 'http://example.com/js/shared.js', requires: ['get', 'node'] } }}).use('shared', function(Y) { // In YUI, "Y" is decorated with functionality});
// in shared.js...YUI.add('shared', function(Y) { // add function to the "Y" object});
LINKEDIN UED©2012 LinkedIn Corporation. All Rights Reserved. 17
Framework natives
// note, this is Dojo 1.7// Dojo 1.8 uses AMD and we're getting to that!dojo.require('shared.js');dojo.ready(function() { // custom code});
LINKEDIN UED©2012 LinkedIn Corporation. All Rights Reserved. 18
LINKEDIN UED©2012 LinkedIn Corporation. All Rights Reserved. 19
And We Brought it to the Browser
LINKEDIN UED©2012 LinkedIn Corporation. All Rights Reserved. 20
Browser Packaging Solutions
Put together discrete pieces into one payload Support the asynchronous require() method
– I want “X”, so… var x = require(“X”); Excellent single page application solutions
LINKEDIN UED©2012 LinkedIn Corporation. All Rights Reserved. 21
The CommonJS Standard
var myVar = require(“string”)– Returns the “string” module’s items assigned to the module’s “exports”
variable– Require is a global variable (always available)
require.ensure(dependencies, function() {})– The “Asynchronous/A” Draft– Download all of the dependencies (an array)– Then run the callback function (second param)– Available off the require function
LINKEDIN UED©2012 LinkedIn Corporation. All Rights Reserved. 22
Asynchronous Module Definition
LINKEDIN UED©2012 LinkedIn Corporation. All Rights Reserved. 23
The AMD Standard
define(moduleId, dependencies, function() {})– Name this download “moduleId” [optional]– Before running, download & execute dependencies (array, [optional])– Then run the callback function (“dependencies” are arguments)– If you depend on “require” or “exports”, they will work like their
CommonJS counterparts
LINKEDIN UED©2012 LinkedIn Corporation. All Rights Reserved. 24
Harmony Modules in ECMAScript!
Nested virtualization State isolation Dynamic loading Global namespace isolation Compilation hooks http://wiki.ecmascript.org/doku
.php?id=harmony:modules_examples
Some day
©2012 LinkedIn Corporation. All Rights Reserved.
Let’s Talk INJECT
LINKEDIN UED©2012 LinkedIn Corporation. All Rights Reserved. 26
In A Slide
Inject is a Dependency Management Framework for the browser Supports CommonJS and AMD specifications Works cross-domain (CDNs) Does not require precompilation in order to function
LINKEDIN UED©2012 LinkedIn Corporation. All Rights Reserved. 27
For Libraries That Aren’t Inject
“AMD” examples still work for browsers Telling the framework where files are differs The “run” command will be slightly different
LINKEDIN UED©2012 LinkedIn Corporation. All Rights Reserved. 28
LINKEDIN UED©2012 LinkedIn Corporation. All Rights Reserved. 29
Our Files
inject.js – the main inject file (that’s all we need for now)
program_cjs.js – load a “math” library, and add 2 + 3 program_amd.js – same thing, with AMD syntax
math_cjs.js – exposes an “add” function for adding numbers math_amd.js – same thing, with AMD syntax
©2012 LinkedIn Corporation. All Rights Reserved.
1. Get Inject
LINKEDIN UED©2012 LinkedIn Corporation. All Rights Reserved. 31
http://www.injectjs.com
Download Inject (Big Yellow Button) Documentation and Howtos Source code Mailing List
©2012 LinkedIn Corporation. All Rights Reserved.
2. Build Site Structure
LINKEDIN UED©2012 LinkedIn Corporation. All Rights Reserved. 33
Directory Structure
<site_root>/js– inject.js– /modules/
program_amd.js program_cjs.js math_amd.js math_cjs.js
LINKEDIN UED©2012 LinkedIn Corporation. All Rights Reserved. 34
program_*.js
// program_cjs.jsvar math = require('math_cjs');alert('math_cjs:' + math.add(2, 3));
// program_amd.jsdefine(['math_amd'], function(math) { alert('math_amd:’ + math.add(2, 3));});
LINKEDIN UED©2012 LinkedIn Corporation. All Rights Reserved. 35
math_*.js
// math_cjs.jsexports.add = function(a, b) { return a + b;};
// math_amd.jsdefine(function() { return { add: function(a, b) { return a + b; } }});
©2012 LinkedIn Corporation. All Rights Reserved.
3. Add Inject, Call Program
LINKEDIN UED©2012 LinkedIn Corporation. All Rights Reserved. 37
Inject’s Script Tag and Inject.run()
<head> <script src="/js/inject.js"></script></head><body> <!-- ... --> <script type="text/javascript"> Inject.setModuleRoot('/js/modules'); // run CommonJS Code... require.run('program_cjs'); // math_cjs: 5 // ... or AMD Code require.run('program_amd'); // math_amd: 5 </script></body>
LINKEDIN UED©2012 LinkedIn Corporation. All Rights Reserved. 38
©2012 LinkedIn Corporation. All Rights Reserved.
INJECT API
LINKEDIN UED©2012 LinkedIn Corporation. All Rights Reserved. 40
Inject.setModuleRoot Where do I find files?
setModuleRoot(String)– String: a URL path where files can be found.
/js/modules http://example.com/js/modules
If using a CDN (Advanced) use a full URL
LINKEDIN UED©2012 LinkedIn Corporation. All Rights Reserved. 41
Inject.setExpires How long to store files?
setExpires(integer)– Integer: how long in minutes to preserve the cache
Built in localStorage module to improve caching Older items from Inject are automatically dropped to make room Inject.setExpires(0) can create a “dev” environment
LINKEDIN UED©2012 LinkedIn Corporation. All Rights Reserved. 42
Inject.reset The ultimate escape hatch
Clears Inject’s localStorage Removes all in-JS memory of currently loaded items Acts as if it hasn’t seen a module yet
©2012 LinkedIn Corporation. All Rights Reserved.
INJECT Advanced API
LINKEDIN UED©2012 LinkedIn Corporation. All Rights Reserved. 44
Inject.addRule Change the Behavior of a Module
addRule(Regex|String, Integer?, Object)– Regex|String: if the module matches the regular expression / string,
any alterations in Object will be applied– Integer (optional): allows you to dynamically reorder the rules by
assigning them weights– Object: a set of alterations to perform
“Lock” a module’s identifier to a URL Turn on/off the automatic attachment of “.js” to module IDs when
converted to a URL Rewrite the code before it is executed
LINKEDIN UED©2012 LinkedIn Corporation. All Rights Reserved. 45
addRule Lock a Module’s Path
Inject.addRule('module/path', { path: 'http://example.com/external/module.js'});
Inject.addRule('module/anotherPath', { path: ’/local_directory/library/module.js'});
LINKEDIN UED©2012 LinkedIn Corporation. All Rights Reserved. 46
addRule Turn on/off the “.js” Suffix
// module/path.jsInject.addRule('module/path', { useSuffix: true});
// module/pathInject.addRule('module/path', { useSuffix: false});
LINKEDIN UED©2012 LinkedIn Corporation. All Rights Reserved. 47
addRule Alter the File (ie non AMD/CJS Code)
// <= 0.4.0Inject.addRule(/^jquery$/, { path: '/path/to/jquery.js', useSuffix: false, pointcuts: { after: function () { module.exports = jQuery.noConflict(); } }});
LINKEDIN UED©2012 LinkedIn Corporation. All Rights Reserved. 48
addRule Alter the File (ie non AMD/CJS Code)
// >= 0.4.1Inject.addRule(/^jquery$/, { path: '/path/to/jquery.js', useSuffix: false, pointcuts: { afterFetch: function (next, text) { next(null, [ text, 'module.exports = jQuery.noConflict();' ].join('\n')); } }});
LINKEDIN UED©2012 LinkedIn Corporation. All Rights Reserved. 49
Inject.plugin Extend Functionality to non-JS Things
plugin(String, Object, Object?)– String: an identifier for the plugin. Automatically creates an addRule()
that matches modules beginning with “<string>!”– Object: this is the same object used in addRule() to modify a module– Object (optional): any functions placed in the 3rd parameter are made
available under Inject.plugins.<string>
An easy interface for addRule to handle non-JS files Inject comes with support for CSS, JSON, and Plain Text
LINKEDIN UED©2012 LinkedIn Corporation. All Rights Reserved. 50
plugin The “text” Plugin
(function () { Inject.plugin('text’, { useSuffix: false, path: function (path) { return path.replace(/^text!\s*/, ''); }, pointcuts: { afterFetch: function (next, text) { next(null, ['', 'var text = "', encodeURIComponent(text), '";', 'module.setExports(decodeURIComponent(text));', ''].join('') ); } } }, {});})();
LINKEDIN UED©2012 LinkedIn Corporation. All Rights Reserved. 51
LINKEDIN UED©2012 LinkedIn Corporation. All Rights Reserved. 52
Roadmap
0.4.1 Final– Robust plugin support– afterFetch non-blocking pointcuts
0.4.2 Librarian Release– Internal library upgrades: Link, Fiber, EasyXDM– Standardize testing framework
0.4.x Planned– localStorage on CDN side– Reduced code base (EasyXDM for IE7 only)– Coffeescript Plugin– Npm “install”-like functionality, global modules
LINKEDIN UED©2012 LinkedIn Corporation. All Rights Reserved.
INJECThttps://github.com/linkedin/inject
LINKEDIN UED©2012 LinkedIn Corporation. All Rights Reserved. 54
Useful Links
http://www.stevesouders.com/blog/2009/04/27/loading-scripts-without-blocking/
http://dojotoolkit.org/documentation/tutorials/1.8/modern_dojo/ http://www.injectjs.com http://requirejs.org https://github.com/amdjs/amdjs-api/wiki/AMD http://www.commonjs.org