github.com/jgarto/itcv@v0.0.0-20180826224514-4eea09c1aa0d/_talks/2017/golang_uk.slide (about)

     1  Creating interactive frontend apps with GopherJS and React
     2  
     3  Paul Jolly
     4  Co-founder, modelogiq
     5  paul@myitcv.io
     6  https://myitcv.io
     7  @_myitcv
     8  
     9  
    10  * Today we will
    11  
    12  - Write a browser-based, interactive frontend app in Go
    13  - Using myitcv.io/react, a wrapper around Facebook's React
    14  - Learn to love `go`generate`
    15  - Enjoy the benefits of writing frontend apps in Go, thereby solving many of the problems associated with using Javascript
    16  - End up with teams of happy frontend Gophers
    17  
    18  .image golang_uk/frontend_gopher.png 250 _
    19  
    20  
    21  * What do we mean by "frontend"?
    22  
    23  For the purposes of this talk:
    24  
    25  - A browser/equivalent (e.g. Electron) on a client device
    26  - Rendering of HTML and CSS
    27  - Backend could be local/remote/non-existent
    28  
    29  
    30  * What do we mean by "interactive"?
    31  
    32  For the purposes of this talk:
    33  
    34  - Intra-page-load responsiveness
    35  - Visual changes, i.e. re-rendering in response to user interactions
    36  - May or may not involve backend calls; could be entirely frontend logic
    37  
    38  
    39  * What do we mean by "app"?
    40  
    41  For the purposes of this talk:
    42  
    43  - HTML page/pages that are interactive
    44  - Page `=>` a single page application - everything retrieved in a single page load
    45  - Pages `=>` logic split across multiple pages (and hence page loads)
    46  
    47  
    48  * Why is any of this important?
    49  
    50  - Browser is an extremely good cross platform way of building frontend apps
    51  - Billions of devices
    52  - Zero cost to adoption
    53  - Low cost from a development perspective (or should be at least!)
    54  
    55  * Examples of interactive frontend apps
    56  
    57  
    58  * 
    59  
    60  .iframe http://blog.myitcv.io/gopherjs_examples_sites/globalstate/?hideGithubRibbon=true 600 975
    61  
    62  
    63  * 
    64  
    65  .iframe http://blog.myitcv.io/gopherjs_examples_sites/markdowneditor/?hideGithubRibbon=true 600 975
    66  
    67  
    68  * 
    69  
    70  .iframe http://blog.myitcv.io/gopherjs_examples_sites/immtodoapp/?hideGithubRibbon=true 600 975
    71  
    72  
    73  * 
    74  
    75  .iframe http://blog.myitcv.io/gopherize.me_site/?hideGithubRibbon=true 600 975
    76  
    77  
    78  * 
    79  
    80  .iframe http://blog.myitcv.io/gopherjs_examples_sites/latency/?hideGithubRibbon=true 600 975
    81  
    82  
    83  * How do we make HTML and CSS dynamic in this way?
    84  
    85  DOM model represents a document with a logical tree.
    86  
    87  Using Javascript we can then manipulate the DOM:
    88  
    89  - add, change, and remove HTML elements and attributes
    90  - change CSS styles
    91  - react to existing events (e.g. mouse clicks, key press)
    92  - create new events (e.g. timer events)
    93  
    94  
    95  * Javascript? Really?
    96  
    97  _“JavaScript_is_ubiquitous_on_the_web,_and_that’s_not_going_to_change_anytime_soon,_so_there’s_no_point_in_carrying_the_baggage_necessary_for_multiple_scripting_engines_that_never_materialized.”_
    98  
    99  A Mozilla maintainer, 2012.
   100  
   101  
   102  * Javascript: the reality
   103  
   104  - Javascript "won" the browser battle
   105  - Easily picked up and learnt
   106  - Standardised via ECMAScript
   107  - `asm.js`, WebAssembly (possibly) represent tomorrow's world
   108  
   109  
   110  * What's the option space for writing interactive frontend apps?
   111  
   112  A very incomplete list:
   113  
   114  - Javascript
   115  - CoffeeScript (compiles to Javascript)
   116  - Typescript (compiles to Javascript)
   117  - ClojureScript (compiles to Javascript)
   118  - Other languages that compile to Javascript/`asm.js`/WebAssembly
   119  - ...
   120  
   121  
   122  * A brief (incomplete) analysis of Typescript
   123  
   124  - Typed superset of Javascript that compiles to Javascript
   125  - Large language; extensive specification, more edge cases, harder to write tools that work with language
   126  - Painful hangovers from Javascript
   127  - Myriad compiler options to satisfy myriad backgrounds of newcomers
   128  - Low development velocity
   129  - No single-source-of-truth `gofmt` equivalent
   130  
   131  
   132  * Is there another way?
   133  
   134  - We want to write interactive frontend apps
   135  - We *ultimately* have to use Javascript to do so
   136  
   137  
   138  * 
   139  
   140  .image golang_uk/gophercolor.png 500 _
   141  
   142  .caption _Gopher_ by [[http://www.reneefrench.com][Renée French]]
   143  
   144  
   145  * GopherJS
   146  
   147  * What is GopherJS?
   148  
   149  - A compiler from Go to JavaScript
   150  - Developed by Richard Musiol et al
   151  - Principally targets the browser
   152  
   153  
   154  
   155  * What does GopherJS support?
   156  
   157  - Full language coverage, including goroutines
   158  - Almost the entire standard library
   159  - Performance is good in most cases
   160  - Source map support (debugging)
   161  - DOM package
   162  - Javascript interoperability package
   163  
   164  
   165  * React
   166  
   167  
   168  * Why React?
   169  
   170  _"A_Javascript_library_for_building_user_interfaces"_
   171  
   172  - Presents a nice abstraction of the DOM
   173  - Makes you think in terms of components (reuse primitive)
   174  - Pragmatic: doesn't mandate data or state patterns
   175  - Widely used; existing Javascript components can be reused
   176  
   177  
   178  * React Fundamentals
   179  
   180  - Components - a description of what HTML/components we want to render via a `Render()` method
   181  - Props - parameters to a component (optional)
   182  - State - private to a component (optional)
   183  - Virtual DOM
   184  
   185  
   186  * Render()
   187  
   188  - `Render()` is a function of a component's props and state
   189  - Results in a hierarchy of component instances/HTML
   190  
   191  .image golang_uk/react_component_tree.png 450 _
   192  
   193  
   194  * myitcv.io/react
   195  
   196  * What is myitcv.io/react?
   197  
   198  _Package_myitcv.io/react_is_a_set_of_GopherJS_bindings_for_Facebook's_React_
   199  
   200  - Wraps the Facebook-distributed React Javascript library
   201  - Presents a Go-esque "interface" to declare components, props and state
   202  - `reactGen`: a tool to initialise a new frontend app, but also a code generator as we declare our components, props and state
   203  
   204  
   205  * Let's create a simple app
   206  
   207    # The ubiquitous hello world
   208    #
   209    mkdir -p $GOPATH/src/example.com/helloworld && cd $_
   210  
   211    # Use the Boostrap template
   212    #
   213    reactGen -init bootstrap
   214  
   215  
   216  * 
   217  
   218  .iframe http://blog.myitcv.io/gopherjs_examples_sites/helloworldbootstrap/ 600 975
   219  
   220  * What did reactGen generate?
   221  
   222    helloworld
   223    ├── app.go
   224    ├── gen_App_reactGen.go
   225    ├── index.html
   226    └── main.go
   227  
   228  * index.html
   229  
   230  Effectively the entry point for our app:
   231  
   232  .code golang_uk/bootstrap_init/index.html
   233  
   234  `helloworld.js` is the GopherJS compiled result of `example.com/helloworld`
   235  
   236  
   237  * main.go
   238  
   239  .code golang_uk/bootstrap_init/main.go
   240  
   241  
   242  * app.go
   243  
   244  .code golang_uk/bootstrap_init/app.go
   245  
   246  
   247  * gen_App_reactGen.go
   248  
   249  `gen_App_reactGen.go` is the result of `go`generate` seeing the directive:
   250  
   251    //go:generate reactGen
   252  
   253  `reactGen`:
   254  
   255  - generates glue code between component, props and state declarations and the wrapped React library
   256  - runs at the package level
   257  - creates type-safe methods for accessing props and state in a component
   258  - saves you writing lots of boilerplate code!
   259  
   260  
   261  * go generate
   262  
   263  .image golang_uk/go_generate.png _ 975
   264  
   265  
   266  * Using a file watcher
   267  
   268  .image golang_uk/go_generate_watch.png _ 975
   269  
   270  e.g. `github.com/cespare/reflex`
   271  
   272  
   273  * Writing our own React component
   274  
   275  * A simple component: declaration
   276  
   277  Components are defined as struct types with a `*Def` name suffix that embed `react.ComponentDef`:
   278  
   279    import "myitcv.io/react"
   280  
   281    // FooBarDef is the definition of the FooBar component.
   282    //
   283    type FooBarDef struct {
   284        react.ComponentDef
   285    }
   286  
   287  
   288  * A simple component: props
   289  
   290  The props type for a component use a corresponding `*Props` suffix:
   291  
   292    // FooBarProps is the props type for the FooBar component.
   293    //
   294    type FooBarProps struct {
   295        Name string
   296    }
   297  
   298  
   299  * A simple component: state
   300  
   301  The state type for a component use a corresponding `*State` suffix:
   302  
   303    // FooBarState is the state type for the FooBar component.
   304    //
   305    type FooBarState struct {
   306        Age int
   307    }
   308  
   309  
   310  * What's reactGen done for us?
   311  
   312  Amongst other things we now have some type-safe methods:
   313  
   314    func (f FooBarDef) Props() FooBarProps
   315  
   316    func (f FooBarDef) State() FooBarState
   317    func (f FooBarDef) SetState(state FooBarState)
   318  
   319  
   320  * A simple component: Render()
   321  
   322  .code golang_uk/foo_bar/render.go
   323  
   324  
   325  * A simple component: click handler
   326  
   327    // ageClick implements the react.OnClick interface to handle when the "Bump age" button
   328    // is clicked
   329    //
   330    type ageClick struct{
   331            FooBarDef
   332    }
   333  
   334    func (a ageClick) OnClick(e *react.SyntheticMouseEvent) {
   335            s := a.State()
   336            s.Age++
   337            a.SetState(s)
   338    }
   339  
   340  
   341  * A simple component: constructor function
   342  
   343  This constructor function is our component's equivalent to, say, `react.Div(...)`:
   344  
   345    // FooBar is the constructor for a FooBar component.
   346    //
   347    func FooBar(p FooBarProps) *FooBarElem {
   348            return buildFooBarElem(p)
   349    }
   350  
   351  `buildFooBarElem()` is generated by `reactGen`
   352  
   353  
   354  * Using our simple component
   355  
   356  .code golang_uk/foo_bar/revised_app_render.go
   357  
   358  
   359  The result?
   360  
   361  * 
   362  
   363  .iframe http://blog.myitcv.io/gopherjs_examples_sites/blog/2017_04_16/ 600 975
   364  
   365  
   366  * React dev tools work
   367  
   368  .image golang_uk/foo_bar/react_tools.png _ 975
   369  
   370  
   371  * 
   372  
   373  .iframe http://blog.myitcv.io/gopherize.me_site/?hideGithubRibbon=true 600 975
   374  
   375  * gopherize.me React component hierarchy
   376  
   377  .image golang_uk/gopherize.me_comps.png _ 975
   378  
   379  
   380  * Backends for our frontend
   381  
   382  
   383  * Where do we stand?
   384  
   385  - Written an interactive frontend app in Go
   386  - Used `myitcv.io/react` and `reactGen` to declare components, props and state
   387  - A new found love for `go`generate`
   388  - But no "data" in our application...
   389  
   390  
   391  * Option space for backends
   392  
   393  - No backend
   394  - JSON/REST API
   395  - Base64 encoded Protobuf 3 over HTTP 1.1
   396  - gRPC over HTTP 2
   397  - ...
   398  
   399  You have (almost) the entire standard library at your disposal
   400  
   401  
   402  * 
   403  
   404  .iframe https://grpcweb.jbrandhorst.com/ 600 975
   405  
   406  
   407  * That's all Gophers
   408  
   409  .image golang_uk/wrap.png 500 _
   410  
   411  * Credits and thanks
   412  
   413  - [[https://github.com/neelance][Richard Musiol]], [[https://github.com/shurcooL][Dmitry Shuralyov]] and others in the GopherJS community
   414  - [[https://twitter.com/lejatorn][Mathieu Lonjaret]] and [[https://twitter.com/bradfitz][Brad Fitzpatrick]] - [[https://camlistore.org/][Camlistore]]
   415  - [[https://twitter.com/tjholowaychuk][TJ Holowaychuk]]
   416  - [[https://twitter.com/JohanBrandhorst][Johan Brandhorst]] for his excellent work on gRPC-backend example
   417  - [[https://twitter.com/ashleymcnamara][Ashley McNamara]] and [[https://twitter.com/matryer][Mat Ryer]] - [[https://gopherize.me/]]
   418  
   419  
   420  * More details/getting started/etc
   421  
   422  - [[https://github.com/myitcv/react/wiki][`myitcv.io/react` wiki]]
   423  - [[http://blog.myitcv.io/][My blog]]
   424  - [[https://gophers.slack.com/messages/gopherjs][GopherJS Slack Channel]]
   425