Standing on the Shoulders of Giants or How to Read the Internals of React.js

Standing on the Shoulders of Giants or How to Read the Internals of React.js

Standing on the Shoulders of Giants
or
How to Read the Internals of React.js:

A talk about how to read code and libraries

4c57e6248d5f8fda1982aa0443e0adce?s=128

Üstün Özgür

May 27, 2015
Tweet

Transcript

  1. Standing on the Shoulders of Giants or How to Read

    the Internals of React.js Üstün Özgür @ustunozgur
  2. If I have seen further than others, it is by

    standing on the shoulders of giants.
  3. Libraries

  4. Library Users From https://flic.kr/p/e8XRdD

  5. user (noun) /ˈjuːzə/ A person who uses or operates something

    A person who takes illegal drugs; an addict
  6. Library users in real life read Library users in compute

    write, but rarely read.
  7. A computer language is not just a way of getting

    a computer to perform operations but rather that it is a novel formal medium for expressing ideas about methodology. Thus, programs must be written for people to read, and only incidentally for machines to execute.
  8. We should read libraries

  9. Why not?

  10. The acts of the mind [...] are chiefly these three:

    1. Combining several simple ideas into one compound one, and thus all complex ideas are made. 2. The second is bringing two ideas together [...] to take a view of them at once, without uniting them into one, by which it gets all its ideas of relations. 3. The third is separating them from all other ideas that accompany them in their real existence: this is called abstraction, and thus all its general ideas are made. John Locke, An Essay Concerning Human Understanding (1690)
  11. Libraries are abstractions. Good libraries are good abstractions.

  12. You probably will not read the code: - If you

    encounter no problems using the library - If the documentation is clear and abundant - If library has no bugs Does this mean you do not need to read the code?
  13. Why?

  14. • Intellectual curiosity • Understanding how software we write really

    works • Understanding how large applications are written • Benefiting from the experience of other programmers • Learning the language better • Leaky Abstractions • Coding is mostly reading and maintenance • We already read our coworkers and previous self's codes all the time
  15. We need rigor and technique

  16. How to Read Libraries Code

  17. None
  18. "Great Books". Licensed under CC BY-SA 2.0 via Wikimedia Commons

    - http://commons.wikimedia.org/wiki/File:Great_Books.jpg#/media/File:Great_Books.jpg
  19. "I. The first reading can be called structural or analytic.

    Here the reader proceeds from the whole to its parts. II. The second reading can be called interpretative or synthetic. Here the reader proceeds from the parts to the whole. III. The third reading can be called critical or evaluative. Here the reader judges the author, and decides whether he agrees or disagrees. " From How to Read a Book by Adler
  20. - the structure and purpose of the book - note

    any divisions in the book - what problems the author is trying to solve. Structural
  21. Interpretive • constructing the author's arguments • special phrases and

    terms • understanding deeply
  22. Critical Stage • critique the book • judge the book's

    merit and accuracy • agree or disagree with the arguments
  23. Reading Libraries

  24. • Code is not linear, where do we start? •

    There is no argument, it either works or not • There is no single author • Some parts are legacy or for backwards compatibility Differences from Reading a Book
  25. Structural Stage • Understand the main purpose of the library

    • Understand how the public API (interface) is used • Read through the usage docs
  26. Structural Stage • Understand the hierarchy and skeleton of files

    • Directory level • Dependency level • Try to understand the main purpose of the library and key points • Try to go through the build process and see how pieces fit
  27. Tools for This Stage • Documentation and experimentation • Look

    at the directory structure • Look at the dependencies • Find the super nodes: most depended files • Try to find largest and most complex files
  28. Example React library

  29. None
  30. None
  31. Number of Files 0 75 150 225 300 Number of

    Lines 0 7,500 15,000 22,500 30,000 Versions 0.3 to 0.13
  32. Main Goals • It is a view layer • Rerender

    the views all the time • Componentize the application • Explicit state changes and flow of props
  33. var  HelloWorld  =  React.createClass({      render:  function  ()  {

             return  <div>Hello  World</div>;      }   }) React.createElement("div",  null,  "Hello  World") JSX React.render(<HelloWorld/>,  document.body)
  34. var Counter = React.createClass({ getInitialState: function () { return {counter:

    0}; }, increment: function () { var currentCount = this.state.counter; this.setState({counter: currentCount + 1}); }, render: function () { return <div> You clicked {this.state.counter} times. <button onClick={this.increment}>Increment</button> </div>)})
  35. Virtual DOM

  36. Directory Structure & Finding the Starting Point and Super Nodes

  37. Finding Biggest Files Crudely all_files = "find . -type f

    -name '*.js' -exec ls -l {} \;" files = os.popen(all_files).read().strip() sizes = Counter() for row in files.split('\n'): row = row.strip() file = row.split(' ')[-1] size = int(row.split(' ')[7]) sizes[file] = size pprint.pprint(sizes.most_common(100))
  38. browser/ui/ReactMount.js', 29383 classic/class/ReactClass.js', 28048 core/ReactCompositeComponent.js', 27862 browser/ui/ReactDOMComponent.js', 16391 browser/eventPlugins/BeforeInputEventPlugin.js', 15126

    classic/element/ReactElementValidator.js', 13748 browser/eventPlugins/SimpleEventPlugin.js', 12328 browser/ReactBrowserEventEmitter.js', 12271 core/ReactMultiChild.js', 12011 browser/eventPlugins/ChangeEventPlugin.js', 11475 browser/eventPlugins/ResponderEventPlugin.js', 11108 classic/types/ReactPropTypes.js', 10895 core/ReactInstanceHandles.js', 10019 browser/ui/dom/DOMProperty.js', 9600 core/ReactUpdateQueue.js', 9421 core/ReactUpdates.js', 8530 browser/eventPlugins/AnalyticsEventPluginFactory.js', 8301
  39. Finding Most Depended Files Crudely all_files = "find . -type

    f -name '*.js'" require_count = "ag --ignore=__tests__ %s | grep require | wc -l" files = os.popen(all_files).read().strip() n_occurrences = Counter() for file in files.split('\n'): if file.split('/')[1] in ['vendor', 'stubs', 'test', 'utils']: continue n_occurrences[file] = int(os.popen(require_count % file.split('/') [-1].replace('.js', '')).read().strip()) pprint.pprint(n_occurrences.most_common(100))
  40. classic/element/ReactElement.js', 33 addons/update.js', 22 browser/ReactDOM.js', 17 modern/class/ReactComponent.js', 16 event/EventConstants.js', 16

    browser/ui/dom/DOMProperty.js', 15 core/ReactUpdates.js', 13 classic/class/ReactClass.js', 12 browser/ui/ReactMount.js', 11 browser/ui/ReactBrowserComponentMixin.js', 9 browser/syntheticEvents/SyntheticEvent.js', 9 core/ReactCurrentOwner.js', 9 event/EventPropagators.js', 8 core/ReactInstanceMap.js', 8 browser/ReactBrowserEventEmitter.js', 7 addons/ReactFragment.js', 7 core/ReactInstanceHandles.js', 7
  41. Demo: Overview of Directory Structure

  42. Level 2: Diving Down • Getting into source code •

    Static reading • Lots and lots of searching , grepping and ack'ing and even better ag'ing! • Which file uses which? • Which file is used by which? • Tooling support
  43. Static Reading

  44. Tooling Use all the tools, all the editors, IDEs! Hint:

    Emacs can do anything, even open Vim
  45. Level 2: Diving Down • Dynamic reading from the browser

    • Experimentation with variables in the browser • Running and reading the tests • Reading advanced documentation
  46. Important Files • React.js • ReactMount->render • ReactClass: calls ReactComponent

    • ReactMultiChild for rendering
  47. * - constructor: Initialization of state. The instance is now

    retained. * - componentWillMount * - render * - [children's constructors] * - [children's componentWillMount and render] * - [children's componentDidMount] * - componentDidMount * * Update Phases: * - componentWillReceiveProps (only called if parent updated) * - shouldComponentUpdate * - componentWillUpdate * - render * - [children's constructors or receive props phases] * - componentDidUpdate * * - componentWillUnmount
  48. Demo: Deep Dive

  49. Level 3: Critique • What feels right about React? •

    What feels wrong? • Are there any leaky abstractions? • What could have been done differently?
  50. • Some Critique From Community • Modularity? • Virtual-Dom and

    Mercury projects • https://github.com/Matt-Esch/virtual-dom
  51. None
  52. None
  53. • Some Critique From Community • Cycle.js: Honestly Reactive •

    Rx decouples data production from data consumption. Apps in Cycle have nothing comparable to imperative calls such as setState(), forceUpdate(), replaceProps(), handleClick()
  54. • Some Critique From ClojureScript Community • No setState •

    Easy shouldComponentUpdate • Just pass props from the top
  55. Thanks Ustun Ozgur @ustunozgur ustun@ustunozgur.com