40
moving to modules @mize

Moving to modules

Embed Size (px)

DESCRIPTION

You believe in the power of JavaScript modules, but you have an existing app, stack or platform infrastructure to keep running. Between maintenance and new features, where do you carve out time to switch over? After a brief overview of modules and why they're great, we'll dig into how to actually migrate a code base, from plotting your approach to implementation tips. Video: http://youtu.be/FbdcdC8mqwE?t=50m51s (watch the entire video from the beginning for other great talks about shadow DOM and competing task runners) Talk from February 19, 2014 NYCHTML5 Meetup: http://www.meetup.com/nychtml5/events/160684962/

Citation preview

Page 1: Moving to modules

moving to modules@mize

Page 2: Moving to modules

hi!@mize

Page 3: Moving to modules

“moving to modules”?

Page 4: Moving to modules

modules: how do they work?

Page 5: Moving to modules

a unit of code…

…with an encapsulated definition

…that explicitly declares its dependencies

…whose instances can be mapped to different identifiers that expose its interface

Page 6: Moving to modules

benefits

• Clean(er) global namespace

• Eases dependency management

• Reusability

• Testability

Page 7: Moving to modules

should i wait for harmony?

Page 8: Moving to modules

—Sean Mize

“nope.”

Page 9: Moving to modules

goals of harmony• Obviate need for globals

• Orthogonality from existing features

• Smooth refactoring from global code to modular code

• Smooth interoperability with existing JS module systems like AMD, CommonJS, and Node.js

• Fast compilation

• Simplicity and usability

• Standardized protocol for sharing libraries

• Compatibility with browser and non-browser environments

• Easy asynchronous external loading

Page 10: Moving to modules

goals of harmony• Obviate need for globals

• Orthogonality from existing features

• Smooth refactoring from global code to modular code

• Smooth interoperability with existing JS module systems like AMD, CommonJS, and Node.js

• Fast compilation

• Simplicity and usability

• Standardized protocol for sharing libraries

• Compatibility with browser and non-browser environments

• Easy asynchronous external loading

Page 11: Moving to modules

no technical excuse not to migrate now

Page 12: Moving to modules

where do i start?

Page 13: Moving to modules

pick your poison

Page 14: Moving to modules

what do i need?format and loader

Page 15: Moving to modules

node.js/* makeItAwesome.js */!var multiplier = require('multiplier').awesome;!!function makeItAwesome(value) {! return value * multiplier;!}!!exports = module.exports = makeItAwesome;

Page 16: Moving to modules

node.js/* makeItAwesome.js */!var multiplier = require('multiplier').awesome;!!function makeItAwesome(value) {! return value * multiplier;!}!!exports = module.exports = makeItAwesome;!!!!/* app.js */!var makeItAwesome = require('makeItAwesome');!var everything = require('status').good;!!everything = makeItAwesome(everything);

Page 17: Moving to modules

exports = module.exports = ?/* makeItAwesome.js */!var multiplier = require('multiplier').awesome;!!function makeItAwesome(value) {! return value * multiplier;!}!!exports = module.exports = makeItAwesome;!!!!/* Imagine this require() implementation */!function (module, exports) {! exports = some_func;! // re-assigns exports, exports is no longer a shortcut,! // and nothing is exported.! module.exports = some_other_func;!} (module, module.exports);

Page 18: Moving to modules

AMD/* makeItAwesome.js */!define(['multiplier/awesome'], function (multiplier) {! function makeItAwesome(value) {! return value * multiplier;! };!! return makeItAwesome;!});

Page 19: Moving to modules

AMD/* makeItAwesome.js */!define(['multiplier/awesome'], function (multiplier) {! function makeItAwesome(value) {! return value * multiplier;! };!! return makeItAwesome;!});!!!!/* app.js */!define(['makeItAwesome', 'status/good'], function (makeItAwesome, everything) {! everything = makeItAwesome(everything);!});

Page 20: Moving to modules

which?Moving to Node?

☛ Node variant of CommonJS

Primarily in the browser? ☛ AMD + RequireJS, curl.js or similar

Need to share logic across both? ☛ You’ll need help.

Page 21: Moving to modules

ok, but what about…

Page 22: Moving to modules

1. shave fewer yaks 2. choose approach 3. apply consistently

& clearly

Page 23: Moving to modules

pick your battles

Page 24: Moving to modules

useful questions• What are your goals? What would be most

useful for your near-term needs?

• How quickly/completely can/do you need to convert?

• F/E benefits or code reuse across stack?

• Are there other consumers of your libs?

Page 25: Moving to modules

migrate!

Page 26: Moving to modules

migrate!1. Map your dependencies

Page 27: Moving to modules

migrate!1. Map your dependencies

2. Load all of your files via loader

Page 28: Moving to modules

RequireJS shimrequirejs.config({! baseUrl: '/src/js',! paths: {! 'foo': 'legacy/foo'! },! shim: {! 'foo': {! deps: ['bar'],! exports: 'Foo',! init: function (bar) {! return this.Foo.noConflict();! }! }! }!});

Page 29: Moving to modules

migrate!1. Map your dependencies

2. Load all of your files via loader

3. Walk your dependencies, wrapping or converting as you go

Page 30: Moving to modules

[ interlude ]possible sticking points

Page 31: Moving to modules

code sequence/* Old - app.js */!Foo.init();!Bar.init(); // Bar depends on globals created during Foo.init()

Page 32: Moving to modules

code sequence/* Old - app.js */!Foo.init();!Bar.init(); // Bar depends on globals created during Foo.init()!!!!/* Transitional - app.js */!define(['foo', 'bar'], function (Foo, Bar) {! Foo.init();! Bar.init();!});

Page 33: Moving to modules

code sequence/* Old - app.js */!Foo.init();!Bar.init(); // Bar depends on globals created during Foo.init()!!!!/* Transitional - app.js */!define(['foo', 'bar'], function (Foo, Bar) {! Foo.init();! Bar.init();!});!!!!/* Final form - bar.js */!define(['foo']), function (Foo) {! // Former Foo.init logic is now part of Foo's module definition! // so just do Bar stuff!}

Page 34: Moving to modules

globalsYou're using AMD, but others depending on your lib don't (yet).

Page 35: Moving to modules

globalsYou're using AMD, but others depending on your lib don't (yet). !!(function (root, factory) {! if (typeof define === 'function' && define.amd) {! // AMD. Register as an anonymous module.! define(['b'], factory);! } else {! // Browser globals! root.amdWeb = factory(root.b);! }!}(this, function (b) {! // use b in some fashion.! // ...! return amdWeb;!}));

Page 36: Moving to modules

migrate!1. Map your dependencies

2. Load all of your files via loader

3. Walk your dependencies, wrapping or converting as you go

4. Profit!

Page 37: Moving to modules

clean up

Page 38: Moving to modules

clean up• Package management

• Optimize

• Great time to incorporate grunt (or gulp!) w/ linting/validation into your workflow

• Add tests!

Page 39: Moving to modules

don’t wait for harmony.

!

write better code now.

Page 40: Moving to modules

thank you!@mize