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

Gerenciando Assets com Symfony Encore

Gerenciando Assets com Symfony Encore

Os assets são elementos fundamentais de uma aplicação web. Nesta palestra mostrarei como utilizar o Symfony Encore para o gerenciamento de assets de sua aplicação de forma simples e sem as complexidades do Webpack. Nesta palestra veremos como lidar com CSS, JavaScript, Sass e outros pré-processadores, invalidação de cache entre outras coisas.

Marcel dos Santos

May 16, 2019
Tweet

More Decks by Marcel dos Santos

Other Decks in Programming

Transcript

  1. Marcel Gonçalves dos Santos
    @marcelgsantos
    Symfony Encore
    gerenciando assets com

    View Slide

  2. pensandonaweb.com.br
    desenvolvedor web full-stack
    Marcel Gonçalves dos Santos
    @marcelgsantos

    View Slide

  3. View Slide

  4. @femugsp
    sp.femug.com

    View Slide

  5. @phpsp
    phpsp.org.br
    bit.ly/vemproslackphpsp

    View Slide

  6. Interaja nas mídias sociais!


    - fale sobre o evento, palestrantes e conteúdo
    - tire fotos do evento e publique

    - interaja com outros participantes do evento
    - tire dúvidas ou dê feedbacks para os palestrantes

    View Slide

  7. 1. seguir @marcelgsantos no Twitter

    2. tuitar utilizando as hashtags
    #Symfony_Live, #Encore e #PHP

    3. não vale tuíte em branco e retuíte

    4. ler e preencher este simples formulário

    bit.ly/sorteio-sflive-2019
    Concorra a um livro da Casa do Código!

    View Slide

  8. O que são assets?

    View Slide

  9. os assets são elementos estáticos que
    compõem uma aplicação web

    View Slide

  10. os assets são scripts, folhas de estilos,
    imagens e fontes

    View Slide

  11. O que é genciamento
    de assets?

    View Slide

  12. o gerenciamento de assets é um
    conjunto de procedimentos realizados
    sobre os assets…

    View Slide

  13. …que os tornam "prontos" para serem
    utilizados pela sua aplicação

    View Slide

  14. assemelha-se a um processo de build

    View Slide

  15. JavaScript
    - module bundling
    - transpiling
    - geração de sourcemaps
    - tree-shaking ou dead code elimination
    - minificação

    - cache busting

    View Slide

  16. CSS
    - pré-processamento (Sass, Less ou Stylus)
    - geração de sourcemaps
    - pós-processamento (vendor-prefixes)
    - ajustar o caminho de imagens e fontes
    - minificação
    - cache busting

    View Slide

  17. imagens e fontes
    - otimização de imagens (redução da

    qualidade e remoção de metadados)
    - codificação em base64
    - cache busting

    View Slide

  18. gerais
    - copiar e remover arquivos
    - notificar processo de compilação
    - atualizar o navegador (após salvar)

    View Slide

  19. todos estes procedimentos fazem parte de
    um desenvolvimento front-end robusto e
    moderno

    View Slide

  20. Um pouco da história
    do front-end

    View Slide

  21. o desenvolvimento front-end evoluiu
    muito nos últimos anos

    View Slide

  22. Parte 1
    - código JavaScript em um “arquivão”
    - variáveis globais por todo lado
    - inclusão manual de bibliotecas
    - preocupação com a ordem de inclusão
    - vários pontos de entrada na aplicação
    - pouca preocupação com versionamento

    - minificação manual ou inexistente

    View Slide

  23. Problemas
    - tudo!

    View Slide

  24. Parte 2
    - organização em módulos (revealing 

    module pattern)
    - simulação de namespaces (com objetos)

    - gerenciamento de dependências

    - concatenação de módulos

    - melhor organização de códigos

    View Slide

  25. Problemas
    - concatenação de módulos de 

    forma manual e propensa a erros

    - gerenciamento de dependências imaturo

    View Slide

  26. Parte 3
    - organização em módulos (CommonJS e AMD)
    - gerenciamento de dependências ganhando

    maturidade (NPM)

    - resolução de dependências automatizada 

    (Browserify e Require.js)

    - automação de tarefas com Gulp

    View Slide

  27. Problemas
    - especificação de módulos oficial ainda

    pouco utilizada

    - muitas bibliotecas sem suporte 

    (necessidade de utilização de Shims)

    View Slide

  28. Parte 4
    - organização em módulos (ES2015)
    - gerenciamento de dependências maduro 

    e robusto (NPM e Yarn)

    - resolução de dependências automatizada

    (Webpack)

    - automação de tarefas com NPM Scripts

    View Slide

  29. Problemas
    - dificuldade na compreensão de inúmeros
    termos e ferramentas

    - configuração complicada do Webpack

    View Slide

  30. loader: "babel-loader",
    options: {
    presets: ['env']
    }
    }
    },
    "//html-loader
    { test: /\.html$/, use: ['html-loader'] }
    ]
    },
    plugins: [
    new CleanWebpackPlugin(['dist']),
    "//html-webpack-plugin instantiation
    new HtmlWebpackPlugin({
    template: 'index.html'
    })
    ],
    devServer: {
    contentBase: path.resolve("__dirname, "./dist/assets/media"),
    compress: true,
    port: 12000,
    stats: 'errors-only',
    open: true
    },
    devtool: 'inline-source-map'
    }
    module.exports = config;

    View Slide

  31. O que é Webpack?

    View Slide

  32. o Webpack é um module bundler, ou seja,
    uma ferramenta que empacota o seu código
    JavaScript e CSS

    View Slide

  33. View Slide

  34. a sua instalação é feita através do NPM

    View Slide

  35. O que é Node.js e NPM?

    View Slide

  36. o Node.js é uma plataforma que permite a
    execução de código JavaScript no back-end

    View Slide

  37. o Node.js é o V8 (engine JavaScript do
    Chrome) + biblioteca padrão + event loop

    View Slide

  38. o NPM é o gerenciador de dependências do
    mundo JavaScript

    View Slide

  39. ele é utilizado tanto para o back-end quanto
    para o front-end

    View Slide

  40. O que é o
    Symfony Encore?

    View Slide

  41. o Symfony Encore é um gerador de
    configuração para o Webpack

    View Slide

  42. ele envolve o Webpack e fornece uma API
    simples e poderosa para o gerenciamento
    de assets

    View Slide

  43. var Encore = require('@symfony/webpack-encore');
    Encore
    .setOutputPath('public/build')
    .setPublicPath('/build')
    .addEntry('app', './assets/js/app.js');
    module.exports = Encore.getWebpackConfig();

    View Slide

  44. ele é inspirado pelo Webpacker e Mix, porém
    preserva o espírito do Webpack usando suas
    funcionalidades, conceitos e convenções

    View Slide

  45. foi feito pela Symfony e funciona
    perfeitamente com o Symfony ❤

    View Slide

  46. ele é uma biblioteca JavaScript, porém, que
    pode ser instalado através do Composer

    View Slide

  47. composer require encore

    View Slide

  48. View Slide

  49. ao ser instalado pelo Composer, obtém-se
    os arquivos package.json e webpack.config.js
    e um diretório assets

    View Slide

  50. View Slide

  51. deve-se executar npm install para a
    instalação do Webpack Encore e suas
    dependências

    View Slide

  52. npm install

    View Slide

  53. as dependências são instaladas em um
    diretório node_modules e as dependências
    são registradas no package.json

    View Slide

  54. o arquivo package.json possui a dependência
    @symfony/webpack-encore e contém
    scripts como dev-server, dev, watch e build

    View Slide

  55. {
    "devDependencies": {
    "@symfony/webpack-encore": "^0.27.0",
    "core-js": "^3.0.0",
    "webpack-notifier": "^1.6.0"
    },
    "license": "UNLICENSED",
    "private": true,
    "scripts": {
    "dev-server": "encore dev-server",
    "dev": "encore dev",
    "watch": "encore dev "--watch",
    "build": "encore production "--progress"
    }
    }

    View Slide

  56. o arquivo webpack.config.js é o arquivo de
    configuração do Webpack

    View Slide

  57. var Encore = require('@symfony/webpack-encore');
    Encore
    .setOutputPath('public/build')
    .setPublicPath('/build')
    .addEntry('app', './assets/js/app.js');
    module.exports = Encore.getWebpackConfig();

    View Slide

  58. o arquivo webpack.config.js fornecido pelo
    Encore é muito bem documentado

    View Slide

  59. "// enables Sass/SCSS support
    "//.enableSassLoader()
    "// uncomment if you use TypeScript
    "//.enableTypeScriptLoader()
    "// uncomment to get integrity="""..." attributes on your script & link t
    "// requires WebpackEncoreBundle 1.4 or higher
    "//.enableIntegrityHashes()
    "// uncomment if you're having problems with a jQuery plugin
    "//.autoProvidejQuery()
    "// uncomment if you use API Platform Admin (composer req api-admin)
    "//.enableReactPreset()
    "//.addEntry('admin', './assets/js/admin.js')
    ;
    module.exports = Encore.getWebpackConfig();

    View Slide

  60. Utilização de
    módulos em JavaScript

    View Slide

  61. o JavaScript evoluiu e projetos passaram a
    ser organizados em módulos ao invés de
    apenas um arquivo

    View Slide

  62. módulos em JavaScript podem conter
    classes, funções, objetos e variáveis que
    existem apenas no escopo do módulo

    View Slide

  63. para torná-los utilizáveis fora do escopo do
    módulo deve-se exportar o que é desejado

    View Slide

  64. import $ from 'jquery';
    import Utils from './helpers/utils';
    class Subscription
    {
    constructor(container) {
    let $container = $(container);
    this.$form = $container.find('#subscription-form');
    }
    init() {
    this.$form.find('#cep').on('blur', this.findAddress.bind(this));
    this.$form.find('#query').on('click',this.findAddress.bind(this));
    }
    "// findAddress implementation""...
    }
    export default Subscription;

    View Slide

  65. pode-se instalar qualquer biblioteca
    utilizando o NPM para gerenciamento de
    dependências

    View Slide

  66. npm install jquery

    View Slide

  67. os módulos instalados via NPM são
    referenciado pelo nome e módulos da
    aplicação são iniciados com ./

    View Slide

  68. import $ from 'jquery';
    import Subscription from ‘./components/subscription';

    View Slide

  69. var Encore = require('@symfony/webpack-encore');
    Encore
    .setOutputPath('public/build')
    .setPublicPath('/build')
    .addEntry('app', './assets/js/app.js');
    module.exports = Encore.getWebpackConfig();

    View Slide

  70. ./node_modules/.bin/encore dev

    View Slide

  71. {
    "devDependencies": {
    "@symfony/webpack-encore": "^0.27.0",
    "core-js": "^3.0.0",
    "webpack-notifier": "^1.6.0"
    },
    "license": "UNLICENSED",
    "private": true,
    "scripts": {
    "dev-server": "encore dev-server",
    "dev": "encore dev",
    "watch": "encore dev "--watch",
    "build": "encore production "--progress"
    }
    }

    View Slide

  72. npm run dev

    View Slide

  73. Gerar um bundle com
    múltiplos arquivos

    View Slide

  74. ao gerar o bundle o Webpack pode gerar
    mais de um arquivo de bundle

    View Slide

  75. a funcionalidade do Encore que permite
    esse comportamento é splitEntryChunks()

    View Slide

  76. var Encore = require('@symfony/webpack-encore');
    Encore
    .setOutputPath('public/build')
    .setPublicPath('/build')

    .splitEntryChunks()
    .addEntry('app', './assets/js/app.js');
    module.exports = Encore.getWebpackConfig();

    View Slide

  77. os arquivos gerados podem ser, por
    exemplo, vendors-app.js e app.js

    View Slide

  78. o arquivo vendors-app.js contém o código de
    vendors importados como jQuery e
    Bootstrap

    View Slide

  79. para fazer parte do bundle de vendors deve
    satisfazer algumas condições como estar
    em node_modules e ser maior que 30kB

    View Slide

  80. e por que o Webpack faz a seperação de
    arquivos de bundle?

    View Slide

  81. para fazer o cache de arquivos de terceiros
    por um longo período de tempo

    View Slide

  82. porém, torna um pouco mais complicado
    para incluir tags de script e style no HTML

    View Slide

  83. para facilitar a inclusão de tags script e style
    no HTML, o Encore fornece funções helpers

    View Slide

  84. encore_entry_link_tags('app')
    encore_entry_script_tags('app')

    View Slide





  85. {% block title %}Welcome to SymfonyLive Brasil '19{% endblock %}
    "

    {% block stylesheets %}
    {{ encore_entry_link_tags('app') }}
    {% endblock %}
    "

    """

    {% block javascripts %}
    {{ encore_entry_script_tags('app') }}
    {% endblock %}
    "
    "

    View Slide

  86. o Encore sabe quais arquivos precisam ser
    incluídos através do arquivo entrypoints.json

    View Slide

  87. ele é apenas um mapeamento para cada
    entrypoint correspondente em JavaScript e
    CSS

    View Slide

  88. {
    "entrypoints": {
    "app": {
    "js": [
    "/build/vendors~app.js",
    "/build/app.js"
    ],
    "css": [
    "/build/app.css"
    ]
    }
    }
    }

    View Slide

  89. o Webpack possui um modo watch que
    permite ouvir alterações no sistema de
    arquivos e iniciar a execução

    View Slide

  90. npm run watch

    View Slide

  91. Utilização de
    pré-processadores em CSS

    View Slide

  92. a utilização de pré-processadores CSS como
    Sass, Less ou Stylus é importante para
    projeto front-end moderno

    View Slide

  93. essas ferramentas traz mais poder,
    flexibilidade e produtividade

    View Slide

  94. "// Sass utilities
    @import "helpers/variables";
    @import "helpers/functions";
    @import "helpers/mixins";
    @import "helpers/placeholders";
    "// Vendors and external stylesheets
    @import "vendors/slider";
    @import "vendors/tipsy";
    "// Base stuff
    @import "base/reset";
    @import "base/typography";
    "// Layout related stylesheets
    @import "layout/site/header";
    @import "layout/site/footer";
    @import "layout/site/navigation";
    @import "layout/site/content";
    @import "layout/site/forms";

    View Slide

  95. .cart {
    @extend %clearfix;
    &-list {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    }
    &-item {
    list-style-type: none;
    margin: 0 10px 15px;
    max-width: 90px;

    }

    }

    View Slide

  96. porém é necessário um processo de build
    para transformar o código em CSS

    View Slide

  97. para habilitar o suporte a Sass no Encore
    basta utilizar enableSassLoader()

    View Slide

  98. var Encore = require('@symfony/webpack-encore');
    Encore
    .setOutputPath('public/build')
    .setPublicPath('/build')

    .enableSassLoader()

    .splitEntryChunks()
    .addEntry('app', './assets/js/app.js');
    module.exports = Encore.getWebpackConfig();

    View Slide

  99. npm install sass-loader node-sass "--save-dev

    View Slide

  100. nem todos os módulos são instalados por
    padrão, isso torna o projeto mais enxuto e
    dependências são instaladas se necessárias

    View Slide

  101. Problemas com
    bibliotecas antigas

    View Slide

  102. as bibliotecas modernas podem ser
    retornadas de forma global e adicionada no
    objeto window ou retornada como objeto e
    atribuída a uma variável local

    View Slide

  103. não é uma boa prática utilizar objetos
    globais em códigos JavaScript

    View Slide

  104. porém existem inúmeras bibliotecas que ainda
    não utilizam a abordagem mais moderna e
    esperam um objeto global como $ ou jQuery

    View Slide

  105. os plugins de jQuery são a maioria destas
    bibliotecas que possuem práticas antiquadas

    View Slide

  106. os plugins de jQuery como o Bootstrap
    modificam o objeto jQuery e adiciona
    funcionalidades a ele

    View Slide

  107. utiliza-se a funcionalidade autoProvidejQuery()
    do Encore para corrigir este problema

    View Slide

  108. var Encore = require('@symfony/webpack-encore');
    Encore
    .setOutputPath('public/build')
    .setPublicPath('/build')

    .splitEntryChunks()
    .autoProvidejQuery()
    .addEntry('app', './assets/js/app.js');
    module.exports = Encore.getWebpackConfig();

    View Slide

  109. ele basicamente reescreve o código
    quebrado para que funcione corretamente

    View Slide

  110. Cópia de arquivos e
    ajuste de caminhos

    View Slide

  111. o Encore possui a funcionalidade de cópia
    de arquivos, ideal para copiar imagens de
    assets para public

    View Slide

  112. var Encore = require('@symfony/webpack-encore');
    Encore
    .setOutputPath('public/build')
    .setPublicPath('/build')

    .splitEntryChunks()
    .copyFiles({
    from: './assets/images',
    to: 'images/[path][name].[hash:8].[ext]'
    })
    .addEntry('app', './assets/js/app.js');
    module.exports = Encore.getWebpackConfig();

    View Slide

  113. o Encore faz a verificação e ajusta os
    caminhos de imagens e fontes em CSS para
    o caminho do diretório de saída

    View Slide

  114. Build para produção

    View Slide

  115. npm run build

    View Slide

  116. o build de produção costuma demorar mais
    que o build de desenvolvimento

    View Slide

  117. os arquivos são minificados e não possuem
    os sourcemaps

    View Slide

  118. var Encore = require('@symfony/webpack-encore');
    Encore
    .setOutputPath('public/build')
    .setPublicPath('/build')

    .splitEntryChunks()
    .enableSourceMaps(!Encore.isProduction())
    .addEntry('app', './assets/js/app.js');
    module.exports = Encore.getWebpackConfig();

    View Slide

  119. pode-se adicionar um hash no nome dos
    arquivos de assets para lidar com cache
    busting

    View Slide

  120. var Encore = require('@symfony/webpack-encore');
    Encore
    .setOutputPath('public/build')
    .setPublicPath('/build')

    .splitEntryChunks()
    .enableVersioning(true)
    .addEntry('app', './assets/js/app.js');
    module.exports = Encore.getWebpackConfig();

    View Slide

  121. var Encore = require('@symfony/webpack-encore');
    Encore
    .setOutputPath('public/build')
    .setPublicPath('/build')

    .splitEntryChunks()
    .enableVersioning(Encore.isProduction())
    .addEntry('app', './assets/js/app.js');
    module.exports = Encore.getWebpackConfig();

    View Slide

  122. Conclusão

    View Slide

  123. 1. utilize um workflow moderno de desenvolvimento
    front-end com módulos e processo de build
    2. deixe tarefas repetitivas para ferramentas como
    o Webpack
    3. utilize o Webpack Encore para facilitar a
    configuração do Webpack

    View Slide

  124. Referências

    View Slide

  125. bit.ly/referencias-palestra-encore

    View Slide

  126. Avalie!

    View Slide

  127. bit.ly/avalie-palestra-encore

    View Slide

  128. @marcelgsantos
    speakerdeck.com/marcelgsantos
    Obrigado.
    Perguntas?

    View Slide