Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Moving to Modules

Avatar for Sean Mize Sean Mize
February 19, 2014

Moving to Modules

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/

Avatar for Sean Mize

Sean Mize

February 19, 2014
Tweet

Other Decks in Programming

Transcript

  1. 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
  2. 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
  3. 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
  4. node.js /* makeItAwesome.js */! var multiplier = require('multiplier').awesome;! ! function

    makeItAwesome(value) {! return value * multiplier;! }! ! exports = module.exports = makeItAwesome;
  5. 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);
  6. 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);
  7. 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);! });
  8. 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.
  9. 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?
  10. RequireJS shim requirejs.config({! baseUrl: '/src/js',! paths: {! 'foo': 'legacy/foo'! },!

    shim: {! 'foo': {! deps: ['bar'],! exports: 'Foo',! init: function (bar) {! return this.Foo.noConflict();! }! }! }! });
  11. migrate! 1. Map your dependencies 2. Load all of your

    files via loader 3. Walk your dependencies, wrapping or converting as you go
  12. code sequence /* Old - app.js */! Foo.init();! Bar.init(); //

    Bar depends on globals created during Foo.init()
  13. 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();! });
  14. 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! }
  15. globals You'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;! }));
  16. 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!
  17. clean up • Package management • Optimize • Great time

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