Symfony 4 Workshop

Managing assets with Webpack Encore

Theory

Webpack as assset manager

Webpack Encore is a wrapper around Webpack written by the Symfony team that simplifies its usage.

It allows us to bundle assets using modern features of the frontend works like imports, babel, use of preprocessors for things like Sass, and minifying assets in production.

Let's install it with Flex:

composer req encore

And download the dependencies:

npm install

Now, let's write a sass file. Copy the contents of this file in assets/css/app.scss.

And uncomment the lines of webpack.config.js that allow us to use Sass and manage CSS assets.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
var Encore = require('@symfony/webpack-encore');

Encore
    // the project directory where compiled assets will be stored
    .setOutputPath('public/build/')
    // the public path used by the web server to access the previous directory
    .setPublicPath('/build')
    .cleanupOutputBeforeBuild()
    .enableSourceMaps(!Encore.isProduction())
    // uncomment to create hashed filenames (e.g. app.abc123.css)
    // .enableVersioning(Encore.isProduction())

    // uncomment to define the assets of the project
    // .addEntry('js/app', './assets/js/app.js')
    .addStyleEntry('css/app', './assets/css/app.scss')

    // uncomment if you use Sass/SCSS files
    .enableSassLoader()

    // uncomment for legacy applications that require $/jQuery as a global variable
    // .autoProvidejQuery()
;

module.exports = Encore.getWebpackConfig();

Since we want to use SCSS, install node-sass:

npm install --save-dev sass-loader node-sass

Now, let's update our views. We have rewritten for you the templates so they apply the classes that we define in our styles:

Copy this file to templates/base.html.twig.

In this file, we are using the asset function of Twig to link to assets. Loading assets this way allows us to use in the future CDNs or other resources to serve our assets by changing only the configuration.

To install support for asset, run this command:

composer req asset

Copy this file to templates/logo.html.twig.

Copy this file to templates/movies/index.html.twig.

Copy this file to templates/movies/movie.html.twig.

Random fixtures are ok, but since we have took the time to write real fixtures about movies, why not use them?

Copy this file to Resources/fixtures/movies.yaml.

Reload the fixtures:

php bin/console hautelook:fixtures:load

And unzip this file into public/images.

Now run webpack:

npm run watch

It looks better, doesn't it?

Exercise

An interesting feature is asset versioning. When we link our CSS as app.css and we cache that file in the browser, if we make a change to the file, our users won't see the changes until the cache is invalidated.

It is possible to solve this with asset versioning, so we automatically append an alphanumeric hash to the file name that is different in every version.

Can you find something in the Symfony documentation about asset versioning and enable it?

Reveal the solution