An Introduction to Inject

54
INJECT Jakob Heuser – maintainer @InjectJS ©2012 LinkedIn Corporation. All Rights Reserved.

description

Given at the Front End Developers United Meetup in Mountain View, CA

Transcript of An Introduction to Inject

Page 1: An Introduction to Inject

©2012 LinkedIn Corporation. All Rights Reserved.

INJECTJakob Heuser – maintainer@InjectJS

Page 2: An Introduction to Inject

©2012 LinkedIn Corporation. All Rights Reserved. 2

Page 3: An Introduction to Inject

©2012 LinkedIn Corporation. All Rights Reserved. 3

Page 4: An Introduction to Inject

©2012 LinkedIn Corporation. All Rights Reserved.

Page 5: An Introduction to Inject

©2012 LinkedIn Corporation. All Rights Reserved.

Page 6: An Introduction to Inject

©2012 LinkedIn Corporation. All Rights Reserved.

Page 7: An Introduction to Inject

©2012 LinkedIn Corporation. All Rights Reserved.

Page 8: An Introduction to Inject

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

Page 9: An Introduction to Inject

©2012 LinkedIn Corporation. All Rights Reserved.

Performance has Come a Long Way

Page 10: An Introduction to Inject

LINKEDIN UED©2012 LinkedIn Corporation. All Rights Reserved. 10

Page 11: An Introduction to Inject

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>

Page 12: An Introduction to Inject

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

Page 13: An Introduction to Inject

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);}

Page 14: An Introduction to Inject

LINKEDIN UED©2012 LinkedIn Corporation. All Rights Reserved. 14

Async Loader Libraries

Page 15: An Introduction to Inject

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 });

Page 16: An Introduction to Inject

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});

Page 17: An Introduction to Inject

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});

Page 18: An Introduction to Inject

LINKEDIN UED©2012 LinkedIn Corporation. All Rights Reserved. 18

Page 19: An Introduction to Inject

LINKEDIN UED©2012 LinkedIn Corporation. All Rights Reserved. 19

And We Brought it to the Browser

Page 20: An Introduction to Inject

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

Page 21: An Introduction to Inject

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

Page 22: An Introduction to Inject

LINKEDIN UED©2012 LinkedIn Corporation. All Rights Reserved. 22

Asynchronous Module Definition

Page 23: An Introduction to Inject

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

Page 24: An Introduction to Inject

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

Page 25: An Introduction to Inject

©2012 LinkedIn Corporation. All Rights Reserved.

Let’s Talk INJECT

Page 26: An Introduction to 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

Page 27: An Introduction to Inject

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

Page 28: An Introduction to Inject

LINKEDIN UED©2012 LinkedIn Corporation. All Rights Reserved. 28

Page 29: An Introduction to Inject

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

Page 30: An Introduction to Inject

©2012 LinkedIn Corporation. All Rights Reserved.

1. Get Inject

Page 31: An Introduction to 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

Page 32: An Introduction to Inject

©2012 LinkedIn Corporation. All Rights Reserved.

2. Build Site Structure

Page 33: An Introduction to Inject

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

Page 34: An Introduction to Inject

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));});

Page 35: An Introduction to Inject

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; } }});

Page 36: An Introduction to Inject

©2012 LinkedIn Corporation. All Rights Reserved.

3. Add Inject, Call Program

Page 37: An Introduction to Inject

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>

Page 38: An Introduction to Inject

LINKEDIN UED©2012 LinkedIn Corporation. All Rights Reserved. 38

Page 39: An Introduction to Inject

©2012 LinkedIn Corporation. All Rights Reserved.

INJECT API

Page 40: An Introduction to Inject

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

Page 41: An Introduction to Inject

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

Page 42: An Introduction to Inject

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

Page 43: An Introduction to Inject

©2012 LinkedIn Corporation. All Rights Reserved.

INJECT Advanced API

Page 44: An Introduction to Inject

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

Page 45: An Introduction to Inject

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'});

Page 46: An Introduction to Inject

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});

Page 47: An Introduction to Inject

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(); } }});

Page 48: An Introduction to Inject

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')); } }});

Page 49: An Introduction to Inject

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

Page 50: An Introduction to Inject

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('') ); } } }, {});})();

Page 51: An Introduction to Inject

LINKEDIN UED©2012 LinkedIn Corporation. All Rights Reserved. 51

Page 52: An Introduction to Inject

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

Page 53: An Introduction to Inject

LINKEDIN UED©2012 LinkedIn Corporation. All Rights Reserved.

INJECThttps://github.com/linkedin/inject

Page 54: An Introduction to 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