Slide 1

Slide 1 text

Optimizing for Developer Delight Rebecca Murphey • JSConf 2013 Wednesday, May 29, 13

Slide 2

Slide 2 text

@rmurphey • rmurphey.com bazaarvoice.com Wednesday, May 29, 13

Slide 3

Slide 3 text

@rmurphey • rmurphey.com bazaarvoice.com Wednesday, May 29, 13

Slide 4

Slide 4 text

• large and growing codebase • mission-critical application • constantly expanding team • mix of junior and senior devs • mandate for rapid feature development the problem Wednesday, May 29, 13

Slide 5

Slide 5 text

• a clear path for getting up to speed • points of entry for junior & senior devs • as few surprises as possible: it just works • isolated complexity • easy development and debugging • nothing more difficult than it “should” be “developer delight” Wednesday, May 29, 13

Slide 6

Slide 6 text

assert all the things Wednesday, May 29, 13

Slide 7

Slide 7 text

Wednesday, May 29, 13

Slide 8

Slide 8 text

BVReporter.assert(    _(config).isObject(),      'config  is  object' ); BVReporter.assert(    !_(config.subjectId).isUndefined(),      'config.subjectId  is  defined' ); Wednesday, May 29, 13

Slide 9

Slide 9 text

assert  :  function  (assertion,  message)  {    if  (!assertion)  {        throw  new  Error('Assertion  failed:  '  +  message);    } } Wednesday, May 29, 13

Slide 10

Slide 10 text

lifecycle logging log the lifecycle Wednesday, May 29, 13

Slide 11

Slide 11 text

Wednesday, May 29, 13

Slide 12

Slide 12 text

BVReporter.group(BVReporter.INFO,  'Component  Initialization'); _(componentData).each(function  (cd,  componentName)  {    var  c  =  new  BComponent(cd);    this.components[componentName]  =  c; },  this); BVReporter.groupEnd(BVReporter.INFO,  'Component  Initialization'); Wednesday, May 29, 13

Slide 13

Slide 13 text

Wednesday, May 29, 13

Slide 14

Slide 14 text

eliminate temptation Wednesday, May 29, 13

Slide 15

Slide 15 text

define([    'ENV',    'underscore',    'bv/api/fetch' ],  function  (ENV,  _,  api)  { Wednesday, May 29, 13

Slide 16

Slide 16 text

ENV.trigger('showLoading'); Wednesday, May 29, 13

Slide 17

Slide 17 text

ENV.trigger(    'track:error',      new  Error('Missing  parent  in  Collection  :  '  +  this.name) ); Wednesday, May 29, 13

Slide 18

Slide 18 text

ENV.trigger('track:conversion',  data,  conversion); Wednesday, May 29, 13

Slide 19

Slide 19 text

if  (      !ENV.get('userTokenDfd')  ||      ENV.get('userTokenDfd').state()  ===  'resolved' )  {    ENV.set({  userTokenDfd  :  $.Deferred()  }); } Wednesday, May 29, 13

Slide 20

Slide 20 text

this.on('pageto',  this.fetchPage,  ENV); Wednesday, May 29, 13

Slide 21

Slide 21 text

ENV.trigger('showLoading'); LoadingOverlay.show(); Wednesday, May 29, 13

Slide 22

Slide 22 text

ENV.trigger(    'track:error',      new  Error('Missing  parent  in  Collection  :  '  +  this.name) ); BVTracker.error(  new  Error(        'Missing  parent  in  Collection  :  '  +  this.name )  ); ENV.trigger('track:conversion',  data,  conversion); BVTracker.conversion(data,  conversion); Wednesday, May 29, 13

Slide 23

Slide 23 text

this.on('pageto',  this.fetchPage,  ENV); this.subscribe('pageto',  this.fetchPage); Wednesday, May 29, 13

Slide 24

Slide 24 text

code for every concept Wednesday, May 29, 13

Slide 25

Slide 25 text

ENV.trigger(    'track:error',      new  Error('Missing  parent  in  Collection  :  '  +  this.name) ); BVTracker.error(  new  Error(        'Missing  parent  in  Collection  :  '  +  this.name )  ); Wednesday, May 29, 13

Slide 26

Slide 26 text

"reviewContentList"  :  {    "features"  :  {        "self"  :  ["headToHead",  "contentFilter",  "contentItemCo        "contentItem"  :  ["has:stars",  "has:secondaryRatings",  "        "pagination"  :  ["ugcCount"],        "secondaryContentList"  :  ["secondaryContentItemCollecti        "secondaryContentItem"  :  ["avatar",  "feedback"],        "contentFilter"  :  ["has:filterButton"]    },    //  ... }, Wednesday, May 29, 13

Slide 27

Slide 27 text

var  components  =  ENV.get('components'); components.each(function  (component,  index)  {    var  view  =  init.initView(component,  index);    //  ... }); Wednesday, May 29, 13

Slide 28

Slide 28 text

Wednesday, May 29, 13

Slide 29

Slide 29 text

_(componentData).each(function  (config,  componentName)  {    var  c  =  new  Component(config);    this.components[componentName]  =  c;    var  view  =  c.initView(index);    //  ... },  this); Wednesday, May 29, 13

Slide 30

Slide 30 text

automate everything Wednesday, May 29, 13

Slide 31

Slide 31 text

Wednesday, May 29, 13

Slide 32

Slide 32 text

Wednesday, May 29, 13

Slide 33

Slide 33 text

Wednesday, May 29, 13

Slide 34

Slide 34 text

document Wednesday, May 29, 13

Slide 35

Slide 35 text

Wednesday, May 29, 13

Slide 36

Slide 36 text

Wednesday, May 29, 13

Slide 37

Slide 37 text

Wednesday, May 29, 13

Slide 38

Slide 38 text

Wednesday, May 29, 13

Slide 39

Slide 39 text

Wednesday, May 29, 13

Slide 40

Slide 40 text

Wednesday, May 29, 13

Slide 41

Slide 41 text

Wednesday, May 29, 13

Slide 42

Slide 42 text

measure progress (and side effects) Wednesday, May 29, 13

Slide 43

Slide 43 text

Wednesday, May 29, 13

Slide 44

Slide 44 text

Wednesday, May 29, 13

Slide 45

Slide 45 text

“I wish I’d had this documentation when I was building that feature last week.” “So I can just add my own logging and they’ll show up in these groups automatically?” “e assertion stuff just caught an error in my code that I would have missed.” Wednesday, May 29, 13

Slide 46

Slide 46 text

are we there yet? Wednesday, May 29, 13

Slide 47

Slide 47 text

@rmurphey • rmurphey.com bazaarvoice.com Wednesday, May 29, 13