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

Hands on with the modern front end stack

Hands on with the modern front end stack

Slides for a workshop I gave at Dutch PHP Conference in June 2015. The accompanying code can be found at https://github.com/bensmithett/dpcon-primer

Ben Smithett

June 23, 2015
Tweet

More Decks by Ben Smithett

Other Decks in Programming

Transcript

  1. hands on with
    the modern
    front end stack

    View full-size slide

  2. who am I?
    Ben Smithett
    Front End Dev @
    @bensmithett / bensmithett.com

    View full-size slide

  3. tomorrow @15:45
    The UI is an
    Application

    View full-size slide

  4. today:
    meet the stack
    build an app
    explore the bleeding edge
    hack!

    View full-size slide

  5. it’s not a lecture!
    there are no stupid questions!

    View full-size slide

  6. no, really… ask questions!

    View full-size slide

  7. the plan
    • Meet the stack!
    • npm
    • Managing dependencies
    • Running tasks
    • JS Modules
    • Webpack for JS
    • Babel
    • ES6 & ES7
    • React
    • Webpack for CSS & images

    View full-size slide

  8. the bonus plan (if we have time!)
    • Hot module reloading
    • Isomorphic React
    • Styling with JS

    View full-size slide

  9. laptops armed & ready?
    github.com/bensmithett/dpcon-primer
    npm install
    npm start

    View full-size slide

  10. meet
    the modern front end stack

    View full-size slide

  11. this stack has
    united
    the front end community

    View full-size slide

  12. It is a recursive bacronymic abbreviation
    for "npm is not an acronym”
    https:/
    /docs.npmjs.com/misc/faq

    View full-size slide

  13. managing dependencies
    with npm

    View full-size slide

  14. yay! now I can use window.$

    View full-size slide

  15. views/
    css/
    js/
    jquery.js
    jquery.fancy-slider.js
    backbone.min.js
    underscore.js
    video-player.min.js
    ...

    View full-size slide

  16. enter
    dependency management

    View full-size slide

  17. nested folder structure
    by convention, JS packages are
    expected to export a module
    flat folder structure
    no expected module format
    depends on npm

    View full-size slide

  18. workshop tasks
    •Create a new package.json with npm init
    •Search npm for React using npm search
    •Install & save React to your package.json
    with npm install

    View full-size slide

  19. running tasks
    with npm

    View full-size slide

  20. Grunt & Gulp require wrapper plugins

    View full-size slide

  21. Just use the original command line tools
    directly!

    View full-size slide

  22. without npm scripts
    node-sass --watch app.scss app.css
    karma start ./config/karma.conf.js
    http-server ./build -p 3000 --cors
    with npm scripts
    npm run sass
    npm test
    npm start

    View full-size slide

  23. workshop tasks
    •Run the existing npm test script
    •Install http-server from npm & add a new
    npm script to start a local server on port
    1337

    View full-size slide

  24. JavaScript
    modules

    View full-size slide

  25. the old way: expose global variables
    // jquery.js
    window.$ = function () { /* ... */ }
    // fancy_modal.js
    window.fancyModal = function () { /* ... */ }
    // my_app.js
    window.MyApp = {
    init: function () {
    $('.content').slideDown()
    fancyModal('Hello!')
    }
    }

    View full-size slide

  26. a better way: modules
    // my_app.js
    var $ = require('jquery')
    var fancyModal = require('fancy_modal')
    var init = function () {
    $(".content").slideDown()
    fancyModal('Hello!')
    }
    module.exports = {init: init}

    View full-size slide

  27. module formats
    AMD
    CommonJS
    ES6

    View full-size slide

  28. workshop tasks
    •Using CommonJS format, use the add()
    function from the supplied add.js module
    to add two numbers together.
    console.log the result
    •Run it with node my_app.js

    View full-size slide

  29. webpack is a module bundler
    // my_app.js
    var add = require("./add")
    console.log(add(4, 6))

    View full-size slide

  30. webpack is a module bundler
    // my_app.js
    var add = require("./add")
    console.log(add(4, 6))
    •Browsers don’t have access to your local
    filesystem
    •Even if you can require individual files from
    the server (i.e. AMD modules) the request is
    asynchronous

    View full-size slide

  31. a module bundler lets you
    author as if you have access to
    multiple files on a filesystem
    but outputs a single JS file for
    end users

    View full-size slide

  32. workshop tasks
    •Build a simple bundle with webpack
    npm run 03
    •Open up the generated file & look at it!
    03_webpack/build/bundle.js

    View full-size slide

  33. webpack config

    View full-size slide

  34. workshop tasks
    •Check out the webpack configuration in
    03_webpack/webpack.config.js

    View full-size slide

  35. webpack code splitting

    View full-size slide

  36. webpack code splitting
    my_app.js
    myapp.com/home myapp.com/timeline

    View full-size slide

  37. webpack code splitting
    myapp.com/home
    timeline.js
    myapp.com/timeline
    router.js
    home.js

    View full-size slide

  38. webpack common chunk extraction
    myapp.com/home
    timeline.js
    myapp.com/timeline
    router.js
    home.js common.js

    View full-size slide

  39. webpack gives you
    powerful optimisation tools
    what you do with them is
    up to you

    View full-size slide

  40. (previously known as 6to5)

    View full-size slide

  41. javascript is evolving
    not all browsers are keeping up

    View full-size slide

  42. http:/
    /kangax.github.io/compat-table/es5/

    View full-size slide

  43. http:/
    /kangax.github.io/compat-table/es6/

    View full-size slide

  44. treat ES5 as a compile target
    author in bleeding edge syntax

    View full-size slide

  45. babel: transforms ES6 to equivalent ES5
    `Hi ${name}. Welcome to ${city}!`
    "Hi " + name + ". Welcome to " + city + "!";

    View full-size slide

  46. babel: polyfills missing features
    class Australian {
    sayHello () { return “G'day" }
    }
    var _createClass = (function () { /* Babel polyfill... */ })();
    function _classCallCheck(instance, Constructor) { /* Babel polyfill... */ }
    var Australian = (function () {
    function Australian() {
    _classCallCheck(this, Australian);
    }
    _createClass(Australian, [{
    key: "sayHello",
    value: function sayHello() {
    return "G'day";
    }
    }]);
    return Australian;
    })();

    View full-size slide

  47. babel: checks your code at compile time
    const speedOfLight = 299792458
    speedOfLight = 17
    COMPILE ERROR
    Line 2: "speedOfLight" is read-only

    View full-size slide

  48. workshop tasks
    •Open babeljs.io/repl & play around with
    some new ES6 features!
    •class
    •const
    •destructuring
    •default function arguments
    •arrow functions

    View full-size slide

  49. webpack loaders
    Loaders allow you to preprocess files
    as you require() or “load” them.

    View full-size slide

  50. webpack loaders
    module.exports = {
    module: {
    loaders: [
    {
    test: /\.js$/,
    loaders: ["babel"]
    }
    ]
    }
    };

    View full-size slide

  51. workshop tasks
    Let’s build a real app!
    •From the root folder, run npm run app
    • If you haven’t installed Webpack, start a static web server instead
    •Try changing the language in entry.js
    congratulations!
    you now have a modular JS app written in ES6 syntax,
    compiled by Babel & bundled by Webpack!

    View full-size slide

  52. react fast facts

    View full-size slide

  53. built (& battle tested in prod) by
    the Facebook & Instagram team

    View full-size slide

  54. a JavaScript library for
    building user interfaces

    View full-size slide

  55. uses virtual DOM diffing
    to make the minimum possible set
    of DOM operations

    View full-size slide

  56. react important facts

    View full-size slide

  57. re-render the entire app
    whenever data changes

    View full-size slide

  58. describe what your UI looks like
    at a given point in time

    View full-size slide

  59. workshop tasks
    •Demo the simple PhotoApp React
    component
    •Add a click event handler to PhotoApp

    View full-size slide

  60. react components can be
    composed

    View full-size slide

  61. const Child = React.createClass({
    render () {
    return
    }
    })
    const Parent = React.createClass({
    render () {
    return (





    )
    }
    })

    View full-size slide

  62. every React component has
    props & state

    View full-size slide

  63. props
    • Passed down from parent to child
    • Cannot be directly changed

    View full-size slide

  64. const Child = React.createClass({
    render () {
    return
    }
    })
    const Parent = React.createClass({
    render () {
    return (





    )
    }
    })

    View full-size slide

  65. const Child = React.createClass({
    render () {
    return Name: {this.props.name}
    }
    })
    const Parent = React.createClass({
    render () {
    return (





    )
    }
    })

    View full-size slide

  66. state
    • Local data for each component
    • Can be changed via this.setState
    • Every state change causes a new
    render()

    View full-size slide

  67. const Counter = React.createClass({
    getInitialState () {
    return {count: 0}
    },
    increment () {
    this.setState({
    count: this.state.count + 1
    })
    },
    render () {
    return (

    Count: {this.state.count}

    )
    }
    })

    View full-size slide

  68. workshop tasks
    •Build the PhotoThumb component
    •Render a PhotoThumb for each photo in
    the supplied data
    •When a PhotoThumb is clicked, store that
    photo in PhotoApp’s state
    •Build a PhotoDetail component
    •Pass the currently selected photo into
    PhotoDetail as a prop

    View full-size slide

  69. building a CSS bundle with
    webpack

    View full-size slide

  70. import React from 'react'
    const FancyButton = React.createClass({
    render () {
    return Hi
    }
    })

    View full-size slide

  71. import React from 'react'
    import 'css/components/fancy-btn'
    const FancyButton = React.createClass({
    render () {
    return Hi
    }
    })

    View full-size slide

  72. workshop tasks
    •Configure webpack so that it can require
    CSS
    •Style the app, requiring each component’s
    CSS dependencies

    View full-size slide

  73. hot module replacement

    View full-size slide

  74. Hot Module Replacement exchanges,
    adds, or removes modules while an
    application is running without a page
    reload.

    View full-size slide

  75. Reminder
    Webpack bundles all of your individual
    modules into a giant array
    and looks a module up in that array
    whenever another module requires it

    View full-size slide

  76. Hot Module Replacement
    Small client runtime polls dev server
    When a file changes, client runtime loads
    new version
    Module stored in array is updated

    View full-size slide

  77. Advantages
    Real time updates as you edit JS views &
    CSS
    Client state is maintained (even if you had
    to click 5 things to get it in that state)

    View full-size slide

  78. demo
    •CSS
    •JS
    •JS with state (i.e. an input)

    View full-size slide

  79. workshop tasks
    •Configure your app to use hot module
    reloading
    •Experiment!

    View full-size slide

  80. isomorphic javascript

    View full-size slide

  81. Reusing the same JavaScript on the
    server & client.

    View full-size slide

  82. http:/
    /bensmithett.github.io/going-
    isomorphic-with-react

    View full-size slide

  83. universal
    isomorphic javascript

    View full-size slide

  84. progressive
    universal
    isomorphic javascript

    View full-size slide

  85. React.renderToString()

    This is my photo app

    View full-size slide

  86. Generate real HTML on the server
    When client JS loads, mount onto server-
    rendered HTML, adding event listeners
    Reuse the same React components on the
    client & server!

    View full-size slide

  87. demo
    •http:/
    /sample-react-rails-app.herokuapp.com/

    View full-size slide

  88. workshop tasks
    •npm run isomorphic

    View full-size slide

  89. styling with
    javascript

    View full-size slide

  90. Who uses a CSS Preprocessor?

    View full-size slide

  91. variables
    functions
    loops
    conditionals
    … real programming language things!

    View full-size slide

  92. javascript already has all those things!

    View full-size slide

  93. var myStyles = {
    color: colors.red,
    backgroundColor: signedInUser ? colors.green : colors.grey,
    backgroundImage: CDNPathFor('forest_bg.png'),
    width: Math.round(viewportSize / 2) + 'px'
    }

    View full-size slide

  94. var totalCols = 12
    var gridColClasses = {}
    for (var i = 1; i <= totalCols; i++) {
    gridColClasses['col-' + i] = {
    width: ((100 / totalCols) * i) + '%'
    }
    }

    View full-size slide

  95. var styles = {
    border: '2px solid #0f0',
    height: '100px',
    width: '100px',
    float: left
    }
    var PhotoThumb = React.createClass({
    render () {
    return (



    )
    }
    })

    View full-size slide

  96. https:/
    /github.com/js-next/react-style
    https:/
    /github.com/jsstyles/jss

    View full-size slide

  97. workshop tasks
    •Convert your app’s styles to JavaScript!

    View full-size slide

  98. extras!
    •React component lifecycle
    •CSS Modules

    View full-size slide