|

Creating simple Webpack configs in Symfony Apps (e.g. TYPO3 or Drupal) with Webpack Encore

It is well known that the configuration of Webpack can become... relatively confusing. Webpack is super flexible, so setting it up from scratch can prove a bit tedious.

Why Webpack again? Webpack fulfills two important tasks for us:

  • It bundles our frontend code and assets together
  • It manages our dependencies

What is the relationship between Symfony's Webpack Encore and Webpack?

Symfony shipped with Webpack Encore starting with version 4: an easier way to integrate Webpack into a Symfony application. Webpack Encore is wrapped with an easy-to-use wrapper API that allows us to tell Webpack how to behave.

This is done via the statement module.exports = Encore.getWebpackconfig(), which is located at the end of our webpack.config.js file (we'll look at it in a moment).

By the way, there are similar Webpack wrapper tools for other languages and frameworks like Ruby on Rails' Webpacker or Laravel's Mix. Encore can be used with any PHP application or other server-side programming languages, but it works best with Symfony.

Let's go!

Go into your terminal and run composer require symfony/webpack-encore-bundle in your Symfony based project, this will download a small bundle called webpackEncoreBundle.

This package brings some important files into the project that are needed by our NodeJS setup, including a package.json.

Next, run yarn or (npm install) to create our most important file: webpack.config.js, which will end up in the root of your project.

After the installation we find a configuration that looks like this:

var Encore = require('@symfony/webpack-encore');

// To start the file you find the Env Config
if (!Encore.isRuntimeEnvironmentConfigured()) {
    Encore.configureRuntimeEnvironment(process.env.NODE_ENV || 'dev');
}

Encore
    // directory where the whole compilation will end up    
    .setOutputPath('public/build/')
    // public path used by the web server to access the output path
    .setPublicPath('/build')
    // the following is only needed for CDNs or subdirectory use
    //.setManifestKeyPrefix('build/')

    /*
     * ENTRY CONFIG
     *
     * Create entry points - we already know this!
     */
    .addEntry('app', './assets/js/app.js')
    //.addEntry('bird', './assets/js/bird.js')
    //.addEntry('dog', './assets/js/dog.js')

    // If enabled, files will be split into smaller chunks
    .splitEntryChunks()

    // needs an extra script tag for runtime.js
    // but you want to have if you don't build SPA
    .enableSingleRuntimeChunk()

    /*
     * FEATURE CONFIG
     *
     * Here you enable more features, read more here (very cool!)
     * https://symfony.com/doc/current/frontend.html#adding-more-features
     */
    .cleanupOutputBeforeBuild()
    .enableBuildNotifications()
    .enableSourceMaps(!Encore.isProduction())
    // if you want hashes in the filenames (e.g. app.abc123.css)
    .enableVersioning(Encore.isProduction())

    // enables @babel/preset-env polyfills
    .configureBabelPresetEnv((config) => {
        config.useBuiltIns = 'usage';
        // set depending on which version of core-js you are using
        config.corejs = 3;
    })

    // enable Sass/SCSS support
    .enableSassLoader()

    // enable TypeScript Loader (it's so easy!)
    .enableTypeScriptLoader()

    // if you use the jQuery plugin
    // .autoProvidejQuery()

    // there are also other presets, e.g. for React
    //.enableReactPreset()
;

module.exports = Encore.getWebpackConfig();

Translated with www.DeepL.com/Translator (free version)

To be able to use your assets in your Symfony Twig templates now, you can use the following Twig helpers:

{# templates / base.html.twig #}
<! DOCTYPE html>
<html>
      <head>
          <! - ... ->

          {% Block stylesheets%}
              {# 'app' must pass to the argument of addEntry () in webpack.config.js #}
              {{encore_entry_link_tags ('app')}}
              <! - The result looks like this:
                   <link rel = "stylesheet" href = "/ build / app.css"> ->
          {% End block%}

          {% block Javascripts%}
              {{encore_entry_script_tags ('app')}}
              <! - The result of it looks like this
                  Postpone <script src = "/ build / runtime.js"> </script>
                  Postpone <script src = "/ build / app.js"> </script>
                  See note below on the "postpone" attribute ->
          {% End block%}
      </head>

      <! - ... ->
</html>

For other Symfony projects like TYPO3 or Drupal, there are already community packages available:

Conclusion


If you are using Webpack in a Symfony project, you should definitely have a look at Webpack Encore. There are many community packages that can save you a lot of work.


Webpack Encore is actively maintained and receives regular updates. Have fun trying it out!


Further links: