Slide 1

Slide 1 text

Modern Web Development Tools And Workflow Amjad Masad @amasad ! facebook

Slide 2

Slide 2 text

What Do I Mean By Modern?

Slide 3

Slide 3 text

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

Slide 4

Slide 4 text

CLI is 70’s Tech

Slide 5

Slide 5 text

No content

Slide 6

Slide 6 text

Upon Inception The Web Was 20 Years Behind

Slide 7

Slide 7 text

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

Slide 8

Slide 8 text

Doom Eventually Made It’s Way To The Web in 2011

Slide 9

Slide 9 text

repl.it ran Python, Ruby, Lua and other programming languages on the Web in 2011

Slide 10

Slide 10 text

The Past Few Years Were Amazing For the Web

Slide 11

Slide 11 text

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

Slide 12

Slide 12 text

We’re Trying To Build The Applications Of Tomorrow By Using The Tools Of Yesterday

Slide 13

Slide 13 text

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

Slide 14

Slide 14 text

What Do We Know About Maintainable Software?

Slide 15

Slide 15 text

“the best way to attack the essence of building software is not to build it at all” The Mythical Man-Month On Reuse

Slide 16

Slide 16 text

Unix Philosophy

Slide 17

Slide 17 text

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

Slide 18

Slide 18 text

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

Slide 19

Slide 19 text

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

Slide 20

Slide 20 text

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

Slide 21

Slide 21 text

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

Slide 22

Slide 22 text

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

Slide 23

Slide 23 text

Building UI With Templates
    {{#todos}}
  • {{task}}
  • {{/todos}}
! ! // First render looks nice template({ todos: todos }); // Later .. todos.on('change', function(model) { $('#todo-' + model.id).find('input').val( model.get('done'); ); });

Slide 24

Slide 24 text

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

Slide 25

Slide 25 text

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

Slide 26

Slide 26 text

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

Slide 27

Slide 27 text

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

Slide 28

Slide 28 text

We Can Do Better

Slide 29

Slide 29 text

Enter ES6 • HELPS WITH MODULARITY • HELPS WITH CLARITY • HELPS WITH ECONOMY • HELPS WITH COMPOSITION

Slide 30

Slide 30 text

Writing Modular Code • ES6 HAS POWERFUL PRIMITIVES • BUILT-IN MODULES • CLASSES • LET KEYWORD

Slide 31

Slide 31 text

Clarity and Economy var sum = (...args) => args.reduce( (acc, n) => acc + n ); ES6 is concise

Slide 32

Slide 32 text

Enter React • LIBRARY FOR BUILD UI • HELPS WITH MODULARITY • HELPS WITH CLARITY • HELPS WITH COMPOSITION • HELPS WITH SIMPLICITY • HELPS WITH ECONOMY • HELPS WITH REPAIR

Slide 33

Slide 33 text

What is React var Hello = React.createClass({ render: function() { return
Hello {this.props.name}
; } }); ! React.renderComponent( , document.body );

Slide 34

Slide 34 text

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

Slide 35

Slide 35 text

var Counter = React.createClass({ getInitialState: function() { return { count: this.props.initialCount }; }, ! addToCount: function(delta) { this.setState({ count: this.state.count + delta }); }, ! render: function() { return

Count: {this.state.count}

+1 -1
; } });

Slide 36

Slide 36 text

Revisiting Todo Example (Simplicity)
    {{#todos}}
  • {{task}}
  • {{/todos}}
! ! // First render looks nice template({ todos: todos }); // Later .. todos.on('change', function(model) { template({ todos: todos }); });

Slide 37

Slide 37 text

Clarity and Modularity

Slide 38

Slide 38 text

Composition render: function() { return
; }

Slide 39

Slide 39 text

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

Slide 40

Slide 40 text

React’s Transparency ONLY ONE TO DO ITEM BUT UI SAYS IT’S TWO. example credit @vjeux

Slide 41

Slide 41 text

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

Slide 42

Slide 42 text

Tools • RECAST FOR GENERATION • FB-FLO FOR ECONOMY • DEBUG_UTILS FOR ECONOMY

Slide 43

Slide 43 text

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

Slide 44

Slide 44 text

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

Slide 45

Slide 45 text

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

Slide 46

Slide 46 text

Recast Example traverse(ast, function(node) { ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! });

Slide 47

Slide 47 text

Recast Example traverse(ast, function(node) { if (n.ArrowFunctionExpression.check(node)) { ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! } });

Slide 48

Slide 48 text

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

Slide 49

Slide 49 text

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

Slide 50

Slide 50 text

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

Slide 51

Slide 51 text

debug_utils • ADVANCED JAVASCRIPT DEBUGGING UTILITY • CAN BREAK ON OBJECT ACCESS, EVENTS, CALLS, AND MORE • https://github.com/amasad/debug_utils

Slide 52

Slide 52 text

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!

Slide 53

Slide 53 text

Trap Scroll With debug_utils $dum(window, 'scrollBy');! $dum(window, 'scrollTo');! $dus(window, 'scrollTop');

Slide 54

Slide 54 text

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

Slide 55

Slide 55 text

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

Slide 56

Slide 56 text

Thank You ! @amasad