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

Pragmatic frontend for Symfony developers

Pragmatic frontend for Symfony developers

Titouan Galopin

February 28, 2020
Tweet

More Decks by Titouan Galopin

Other Decks in Programming

Transcript

  1. Pragmatic
    frontend for
    Symfony
    developers
    Titouan GALOPIN

    View full-size slide

  2. 2
    Titouan Galopin
    Product Manager
    SymfonyInsight
    insight.symfony.com

    View full-size slide

  3. 4
    Why is frontend
    development
    so complex?

    View full-size slide

  4. 5
    Thinking about modern
    software architectures
    requires frontend choices

    View full-size slide

  5. 6
    Let’s discuss!

    View full-size slide

  6. Agenda
    1. A bit of history
    2. Modern frontend
    3. The least complex
    technology possible
    4. Approaches to
    frontend with
    Symfony
    7

    View full-size slide

  7. 8
    1.
    A bit of history

    View full-size slide

  8. 9
    1990–1995
    HTML, CSS and JavaScript
    are invented

    View full-size slide

  9. 10
    1996–1999
    Standardization efforts begin
    Browser compliance is terrible

    View full-size slide

  10. 2000–2004
    CSS frameworks begin to emerge
    jQuery is born
    11

    View full-size slide

  11. 2005–2009
    W3C specification is met
    Responsive designs and frameworks
    introduced
    12

    View full-size slide

  12. 13
    2010–2015
    JS frameworks are born (Backbone,
    Ember, Angular, React, Vue, ...)
    HTML5 is announced

    View full-size slide

  13. 14
    2016–2020
    New technologies and platforms built
    around modern frontend emerge:
    GraphQL, Service Workers, Cordova,
    Electron, React Native, …

    View full-size slide

  14. 15
    Modern frontend
    development is a direct
    consequence of this
    history

    View full-size slide

  15. 16
    What is Modern Frontend?

    View full-size slide

  16. 17
    2.
    Modern frontend

    View full-size slide

  17. 18
    Modern frontend is
    supposed to be about
    user experience

    View full-size slide

  18. 19
    “Nowadays, users expect
    more from websites
    (performance, help,
    productivity, …)”

    View full-size slide

  19. 20
    Ever wondered whether a
    loader was actually loading
    or was broken?

    View full-size slide

  20. 21
    Ever been frustrated about a
    Back button click returning
    to the wrong page?

    View full-size slide

  21. 22
    Ever been disappointed by
    a link you couldn’t
    open in a new tab?

    View full-size slide

  22. 23
    Ever been angered by a
    website you couldn’t open in
    multiple tabs without
    messing with the data?

    View full-size slide

  23. 24
    Ever had to disable your
    adblocker to make a website
    work?

    View full-size slide

  24. 25
    Ever had to use a screen
    reader on a full Javascript
    interface?

    View full-size slide

  25. 26
    Full-page apps
    (for instance create-react-app)
    is not an answer to
    the UX problem

    View full-size slide

  26. 27
    It’s easy to do it
    really wrong
    and hurts UX a lot

    View full-size slide

  27. 28
    Modern frontend
    !=
    Full-page app

    View full-size slide

  28. 29
    Full-page app
    is a solution to a
    different problem

    View full-size slide

  29. 30
    How to build a website and
    a mobile application with
    the same backend?

    View full-size slide

  30. 31
    3.
    The least
    complex
    technology
    possible

    View full-size slide

  31. How many times did you
    experience PHP failing
    between a function call and
    the first line of the function?
    32

    View full-size slide

  32. How many times did you
    experience an AJAX call
    failing between the request
    and the response?
    33

    View full-size slide

  33. 34
    The network is a huge
    source of complexity

    View full-size slide

  34. How many times did you
    develop your own session
    system in PHP?
    35

    View full-size slide

  35. How many times did you
    develop your own session
    history stack in PHP?
    36

    View full-size slide

  36. 37
    Not using the features of
    the browser is a source of
    complexity

    View full-size slide

  37. How many developers in
    your team know perfectly
    well both React and
    Symfony?
    38

    View full-size slide

  38. 39
    Dealing with
    backend vs with interfaces
    are two different jobs:
    human complexity

    View full-size slide

  39. KISS
    Keep It Super Simple
    40

    View full-size slide

  40. By default, use the simplest
    option available
    Migrate to something more
    complex only if necessary
    41

    View full-size slide

  41. The simplest option
    =
    HTML + CSS built with PHP
    42

    View full-size slide

  42. But it’s sometimes not
    enough...
    43

    View full-size slide

  43. 44
    4.
    Approaches to
    frontend with
    Symfony

    View full-size slide

  44. 45
    No JS
    Misses the real UX gain of
    Javascript, but still possible

    View full-size slide

  45. 46
    Full-page app + API
    Has a lot of drawbacks but is
    the only option for multiple
    clients (web + mobile)

    View full-size slide

  46. 47
    Progressive enhancement
    A pragmatic in-between

    View full-size slide

  47. 48
    Most recent JS
    frameworks
    (React, Vue, …)
    can be used in limited
    parts of the page

    View full-size slide

  48. 49
    What about using React
    only where it brings actual
    improvements?

    View full-size slide

  49. 50
    Using React to enhance
    your Symfony application

    View full-size slide

  50. 51
    1. Develop your
    application
    as usual

    View full-size slide

  51. 52
    {# index.html.twig #}
    {% extends 'base.html.twig' %}
    {% block body %}

    Hello world

    placeholder="Color in hexadecimal" />


    {% endblock %}

    View full-size slide

  52. 53
    {# index.html.twig #}
    {% extends 'base.html.twig' %}
    {% block body %}

    Hello world

    placeholder="Color in hexadecimal" />


    {% endblock %}
    This could be a Symfony
    Form field

    View full-size slide

  53. 54
    2. Add React only
    where it’s useful

    View full-size slide

  54. 55
    composer req --dev webpack
    yarn install
    https://symfony.com/doc/current/frontend.html

    View full-size slide

  55. 56
    Webpack is a build tool
    It lets you manipulate your Javascript
    and CSS before using it in production
    (JSX, minification, …)

    View full-size slide

  56. 57
    Webpack Encore wraps
    Webpack around a nice API
    to improve its Developer
    Experience

    View full-size slide

  57. 58
    Webpack Encore is
    awesome to compile React
    apps to normal Javascript

    View full-size slide

  58. 59
    yarn add
    @babel/preset-react
    react
    react-dom
    prop-types

    View full-size slide

  59. 60
    // webpack.config.js
    Encore.enableReactPreset()

    View full-size slide

  60. 61
    {# index.html.twig #}
    {% extends 'base.html.twig' %}
    {% block body %}

    Hello world

    placeholder="Color in hexadecimal" />


    {% endblock %}
    Marker to find where to
    inject a React component

    View full-size slide

  61. 62
    // app.js
    import ReactDOM from 'react-dom';
    import {ColorChooser} from './ColorChooser/ColorChooser';
    $('div[data-color-chooser]').each((key, node) => {
    const input = $(node).find('input');
    ReactDOM.render(
    color={input.val()}
    onColorChange={(color) => input.attr('value', color)}
    />,
    node
    );
    });

    View full-size slide

  62. 64
    ✓ Allow to use great React components
    where it’s useful
    ✓ Do not add unnecessary complexity
    ✓ 100% compatible with Symfony, HTTP
    and default browser behaviors

    View full-size slide

  63. 65
    3. How to transfer data?

    View full-size slide

  64. 66
    namespace App\DataExposer;
    class DataExposer
    {
    private $data = [];
    public function expose(string $name, $value) {
    $this->data[$name] = $value;
    }
    public function getExposedData(): array {
    return $this->data;
    }
    }

    View full-size slide

  65. 67
    namespace App\Twig;
    class DataExposerExtension extends AbstractExtension {
    private $exposer;
    public function __construct(DataExposer $exposer) {
    $this->exposer = $exposer;
    }
    public function getFunctions(): array {
    return [
    new TwigFunction('expose', [$this, 'exposeData']),
    new TwigFunction('get_exposed_data', [$this, 'getExposedData']),
    ];
    }
    // ...
    }

    View full-size slide

  66. 68
    {# base.html.twig #}




    Welcome!


    {% block body %}{% endblock %}
    <br/>{{- get_exposed_data()|json_encode|raw -}}<br/>
    {{ encore_entry_script_tags('app') }}


    View full-size slide

  67. 69
    const data = JSON.stringify(
    document.getElementById('exposed-data')
    );

    View full-size slide

  68. 70
    ✓ Easy to parse (JSON.stringify)
    ✓ Compatible with Content Security Policy
    ✓ Easy to use in automated testing

    View full-size slide

  69. 71
    Conclusion

    View full-size slide

  70. Thanks!
    72
    For any question:
    ▪ @titouangalopin
    on Twitter
    ▪ titouan.galopin
    @symfony.com

    View full-size slide