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

Modern Web Development Tools And Workflow

Modern Web Development Tools And Workflow

Amjad Masad

June 06, 2014
Tweet

More Decks by Amjad Masad

Other Decks in Programming

Transcript

  1. Invention of the web • STARTED AS A NOTEBOOK PROGRAM

    “ENQUIRE” WITH LINKS IN 1980S • INVENTED THE WEB AS WE KNOW IT TODAY WITH HTML AND HTTP IN 1990 • THE FIRST BROWSER WAS A PROTOTYPE THAT ONLY RAN ON NEXT OS • FIRST REAL CROSS PLATFORM ACCESSIBLE BROWSER WAS A LINE-MODE BROWSER
  2. 1993 • GUI BROWSERS CAME ABOUT LIKE MOSAIC AND LATER

    MICROSOFT IE • ON PC LAND IN 1993 WE STARTED TO SEE ADVANCED 3D GRAPHIC GAMES LIKE DOOM
  3. In Just Few Years • FAST DOM MANIPULATION TO HANDLE

    COMPLEX APPS LIKE FACEBOOK • NEAR NATIVE JAVASCRIPT PERF GETS US 3D GAME ENGINES LIKE UNREAL • RELIABLE VIDEO PLAYBACK FOR APPS LIKE NETFLIX • WEBSOCKET AND WEBRTC API FOR REALTIME APPS AND VIDEO CHAT • OFFLINE MODE FOR GOOGLE DRIVE AND OFFICE APPS • AND MANY MORE
  4. What’s Missing? • TO BUILD MAINTAINABLE SOFTWARE ON THE WEB

    WE NEED • POWERFUL UI FRAMEWORKS FOR BUILDING AND REUSING COMPONENTS • LANGUAGES WITH MORE ADVANCED PRIMITIVES • TOOLING
  5. “the best way to attack the essence of building software

    is not to build it at all” The Mythical Man-Month On Reuse
  6. Rule of Diversity • ‘DISTRUST ALL CLAIMS FOR “ONE TRUE

    WAY”’ • NOT CLAIMING A ONE TRUE WAY. BUT CERTAINLY A WAY THAT HAS PROVEN TO WORK
  7. Rule of Modularity • “WRITE SIMPLE PARTS CONNECTED BY CLEAN

    INTERFACES” • OUR BASIC PRIMITIVE FOR MODULARITY IN JAVASCRIPT IS A FUNCTION • EVERYTHING IS GLOBAL BY DEFAULT • CAN’T REQUIRE OR INCLUDE CODE • WHICH MAKES IT PRE-C LANGUAGE IN TERMS OF MODULARITY
  8. Rule of Clarity function sum() { var args = Array.prototype.slice.call(arguments);

    var ret = 0; for (var i = 0; i < args.length; i++) { ret += args[i]; } return ret; } • “CLARITY IS BETTER THAN CLEVERNESS” • JAVASCRIPT IS INCREDIBLY VERBOSE
  9. Rule of Composition • “DESIGN PROGRAMS TO BE CONNECTED TO

    OTHER PROGRAMS” • PROGRAMS ARE HARD TO CO-EXIST IN JAVASCRIPT (SEE RULE OF MODULARITY) • NO BUILT-IN VERSIONING • UI CODE IS INCREDIBLY HARD TO COMPOSE BECAUSE PARENT NEEDS TO KNOW ABOUT CHILDREN STATE
  10. Composing UIs in Backbone init: function() { this.model.on('change:field', this.changeContent) },

    ! changeContent: function(text) { this.$('.field').val(text); }, ! renderSubview: function() { this.subview.$el.remove(); this.subview = new Subview(); this.$el.append(this.subview.render().$el); }, ! render: function() { this.$el.$html(this.template()); this.renderSubview(); this.renderAnotherSubview(); return this; }
  11. Rule of Simplicity • “DESIGN FOR SIMPLICITY; ADD COMPLEXITY ONLY

    WHERE YOU MUST” • HAVING TO POLLY-FILL THE APIS ADDS COMPLEXITY AND CODE TO MAINTAIN • IT TAKES A LOT OF CODE TO KEEP YOUR APPLICATION STATE IN SYNC WITH YOUR DOM • TO UPDATE THE DOM WE USE CSS SELECTORS WHICH COUPLES THE MARKUP TO OUR UI LOGIC
  12. Building UI With Templates <ul id="todos"> {{#todos}} <li id="todo-{{id}}"> <input

    type="checkbox" checked="{{done}}"> <div>{{task}}</div> </li> {{/todos}} </ul> ! ! // First render looks nice template({ todos: todos }); // Later .. todos.on('change', function(model) { $('#todo-' + model.id).find('input').val( model.get('done'); ); });
  13. Rule of Separation • “SEPARATE INTERFACES FROM ENGINES” • WE

    DO COMPUTATION ON THE UI THREAD • WE STORE DATA IN THE DOM • INTERFACES AND ENGINES ARE COMMINGLING
  14. Rule of Economy • “PROGRAMMER TIME IS EXPENSIVE; CONSERVE IN

    PREFERENCE TO MACHINE TIME” • WE SLAVE OVER OPTIMIZING DOM MANIPULATIONS • WE WRITE SO MUCH BOILERPLATE • LACK OF GOOD DEBUGGING TOOLS
  15. Rule of Repair • “WHEN YOU FAIL, FAIL NOISILY AND

    AS SOON AS POSSIBLE” • JAVASCRIPT IS NOTORIOUS FOR FAILING SILENTLY • BROWSERS WON’T THROW ERRORS FOR HTML OR CSS EITHER
  16. Rule of Generation • MACHINES ARE BETTER THAN US IN

    WRITING CODE • JAVASCRIPT COMMUNITY BUILT GREAT AST AND COMPILER TOOLS FOR JS • WE CAN USE IT TO GENERATE BOILERPLATE AND DO USEFUL TRANSFORMATION ON THE CODE
  17. Enter ES6 • HELPS WITH MODULARITY • HELPS WITH CLARITY

    • HELPS WITH ECONOMY • HELPS WITH COMPOSITION
  18. Enter React • LIBRARY FOR BUILD UI • HELPS WITH

    MODULARITY • HELPS WITH CLARITY • HELPS WITH COMPOSITION • HELPS WITH SIMPLICITY • HELPS WITH ECONOMY • HELPS WITH REPAIR
  19. What is React var Hello = React.createClass({ render: function() {

    return <div>Hello {this.props.name}</div>; } }); ! React.renderComponent( <Hello name="Foo" />, document.body );
  20. What’s Special About It • DON’T NEED TO UPDATE THE

    DOM AND SYNC IT WITH YOUR APPLICATION STATE • JUST DESCRIBE THE UI DECLARATIVELY USING XML SYNTAX • DON’T NEED TO WORRY ABOUT OPTIMIZING DOM UPDATES • ALL JAVASCRIPT MEANS LESS GLUE CODE AND EASIER EVENT HANDLING
  21. var Counter = React.createClass({ getInitialState: function() { return { count:

    this.props.initialCount }; }, ! addToCount: function(delta) { this.setState({ count: this.state.count + delta }); }, ! render: function() { return <div> <h3>Count: {this.state.count}</h3> <button onClick={this.addToCount.bind(this, 1)}> +1 </button> <button onClick={this.addToCount.bind(this, -1)}> -1 </button> </div>; } });
  22. Revisiting Todo Example (Simplicity) <ul id="todos"> {{#todos}} <li id="todo-{{id}}"> <input

    type="checkbox" checked="{{done}}"> <div>{{task}}</div> </li> {{/todos}} </ul> ! ! // First render looks nice template({ todos: todos }); // Later .. todos.on('change', function(model) { template({ todos: todos }); });
  23. Economy and Repair • REACT IS STRICT ABOUT MARKUP ERRORS

    UNLIKE THE BROWSER • CAN ONLY CHANGE REACT COMPONENT STATE VIA SETSTATE CALL MAKES IT EASY TO SPOT BUGS
  24. React’s Transparency ONLY ONE TO DO ITEM BUT UI SAYS

    IT’S TWO. example credit @vjeux
  25. React Devtools • FIND THE OFFENDING COMPONENT • LOOK ONLY

    IN THE COMPONENT FOR LOCAL VARIABLES • OR LOOK IN THE PARENT COMPONENT PASSING IN THE PROPS SINCE THEY ARE IMMUTABLE
  26. Recast • TRANSFORM JAVASCRIPT AST • EXAMPLE: USED RECAST TO

    AUTOMATICALLY MODERNIZE OUR JAVASCRIPT CODE • SAVES ON HUMAN TIME AND LESS ERROR PRONE • https://github.com/benjamn/recast
  27. Recast Example [3, 1, 10, 28].sort((a, b) => a -

    b) [3, 1, 10, 28].sort(function(a, b) { return a - b; }.bind(this)) INPUT (ES6) OUTPUT (ES5) example credit @benjamn
  28. Recast Example var recast = require("recast"); var types = recast.types;

    var traverse = types.traverse; var n = types.namedTypes; var b = types.builders; ! var ast = recast.parse( "[3, 1, 10, 28].sort((a, b) => a - b)" );
  29. Recast Example traverse(ast, function(node) { if (n.ArrowFunctionExpression.check(node)) { var body

    = node.body; ! if (node.expression) { node.expression = false; body = b.blockStatement([b.returnStatement(body)]); } ! ! ! ! ! ! ! ! } });
  30. Recast Example traverse(ast, function(node) { if (n.ArrowFunctionExpression.check(node)) { var body

    = node.body; ! if (node.expression) { node.expression = false; body = b.blockStatement([b.returnStatement(body)]); } ! var funExp = b.functionExpression( node.id, node.params, body, node.generator, node.expression ); ! ! ! ! ! } });
  31. Recast Example traverse(ast, function(node) { if (n.ArrowFunctionExpression.check(node)) { var body

    = node.body; ! if (node.expression) { node.expression = false; body = b.blockStatement([b.returnStatement(body)]); } ! var funExp = b.functionExpression( node.id, node.params, body, node.generator, node.expression ); ! var bindExp = b.callExpression( b.memberExpression(funExp, b.identifier("bind"), false), [b.thisExpression()] ); ! this.replace(bindExp); } });
  32. debug_utils • ADVANCED JAVASCRIPT DEBUGGING UTILITY • CAN BREAK ON

    OBJECT ACCESS, EVENTS, CALLS, AND MORE • https://github.com/amasad/debug_utils
  33. Debugging Example • BUG WERE YOUR WINDOW SCROLLS ALL THE

    WAY TO TO TOP • YOU CAN GREP THE CODEBASE FOR WINDOW.SCROLLTO, WINDOW.SCROLLBY, BODY.SCROLLTOP = • IMPOSSIBLE AT THE SCALE OF FB OR EVEN MUCH SMALLER COMPANY • SOLUTION: SET UP TRAPS!
  34. fb-flo • MODIFY RUNNING APPS WITHOUT RELOADING • FLEXIBLE AND

    CAN BE EASILY INTEGRATED INTO YOUR SETUP • SHORTER DEVELOPMENT CYCLE • https://github.com/amasad/debug_utils
  35. Why fb-flo • RELOADING AND GETTING TO THE USER FLOW

    TAKES A LONG TIME • HOOKS INTO THE RUNNING VM AND PATCHES THE CODE • NON OF THE OTHER TOOLS WORKED WITH OUR SETUP AT FACEBOOK • NON OF THE OTHER TOOLS WORKED WITH FACEBOOK SCALE