|

Einfache Webpack Config in Symfony Apps (z.B. TYPO3 oder Drupal) mit Webpack Encore erstellen

Die Konfiguration von Webpack kann bekanntlich relativ schnell... relativ unübersichtlich werden. Webpack ist super flexibel, weshalb es sich als etwas mühsam erweisen kann, es von Grund auf einzurichten.

Warum nochmal Webpack? Webpack erfüllt für uns zwei wichtige Aufgaben:

  • Es bündelt unseren Frontend Code und Assets zusammen
  • Es verwaltet unsere Abhängigkeiten

Was ist die Beziehung zwischen Symfony's Webpack Encore und Webpack?

Symfony wurde ab Version 4 mit Webpack Encore ausgeliefert: eine einfachere Möglichkeit, Webpack in eine Symfony Anwendung zu integrieren.

Webpack Encore wird mit einer einfach zu bedienenden Wrapper API umhüllt, die es uns erlaubt, Webpack mitzuteilen, wie es sich verhalten soll.

Dies geschieht über die Anweisung module.exports = Encore.getWebpackconfig(), die sich am Ende unserer Datei webpack.config.js befindet (schauen wir uns gleich an).

Übrigens: Es gibt ähnliche Webpack-Wrapper-Tools für andere Sprachen und Frameworks wie den Webpacker von Ruby on Rails oder den Mix von Laravel.

Encore kann mit jeder PHP-Anwendung oder anderen serverseitigen Programmiersprachen verwendet werden, aber es funktioniert am besten mit Symfony.

Los gehts!

Geh in Dein Terminal und führe in Deinem Symfony basierten Projekt composer require symfony/webpack-encore-bundle aus, dies wird ein kleines Bundle namens webpackEncoreBundle herunterladen.

Dieses Package bringt einige wichtige Dateien mit ins Projekt, die von unserem NodeJS Setup benötigt werden, unter anderem auch eine package.json.

Als nächstes führst Du yarn oder (npm install) aus, um unsere wichtigste Datei zu erstellen: webpack.config.js, die im Stammverzeichnis Deines Projekts landet.

Nach der Installation finden wir eine Konfiguration die wie folgt aussieht:

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

// Zum Start des Files findest Du die Env Config
if (!Encore.isRuntimeEnvironmentConfigured()) {
    Encore.configureRuntimeEnvironment(process.env.NODE_ENV || 'dev');
}

Encore
    // Verzeichnis, in dem das ganze Kompilat landet    
    .setOutputPath('public/build/')
    // öffentlicher Pfad, der vom Webserver für den Zugriff auf den Ausgabepfad verwendet wird
    .setPublicPath('/build')
    // folgendes wird nur für CDNs oder den Einsatz von Unterverzeichnissen benötigt
    //.setManifestKeyPrefix('build/')

    /*
     * ENTRY CONFIG
     *
     * Entry Points anlegen - kennen wir schon!
     */
    .addEntry('app', './assets/js/app.js')
    //.addEntry('bird', './assets/js/bird.js')
    //.addEntry('dog', './assets/js/dog.js')

    // Wenn aktiviert, werden files in kleinere Chunks gesplittet
    .splitEntryChunks()

    // benötigt einen extra script tag für runtime.js
    // willst Du aber haben, wenn Du keine SPA baust
    .enableSingleRuntimeChunk()

    /*
     * FEATURE CONFIG
     *
     * Hier werden weitere Features aktiviert, mehr dazu hier (sehr cool!)
     * https://symfony.com/doc/current/frontend.html#adding-more-features
     */
    .cleanupOutputBeforeBuild()
    .enableBuildNotifications()
    .enableSourceMaps(!Encore.isProduction())
    // falls Du hashes in den Filenames willst (z.B. app.abc123.css)
    .enableVersioning(Encore.isProduction())

    // enables @babel/preset-env polyfills
    .configureBabelPresetEnv((config) => {
        config.useBuiltIns = 'usage';
        // Einstellung, je nachdem welche Version von core-js Du nutzt
        config.corejs = 3;
    })

    // aktiviert Sass/SCSS Support
    .enableSassLoader()

    // TypeScript Loader aktivieren (es ist so einfach!)
    .enableTypeScriptLoader()

    // falls Du das jQuery plugin nutzt
    //.autoProvidejQuery()

    // gibt auch weitere Presets, z.B. für React
    //.enableReactPreset()
;

module.exports = Encore.getWebpackConfig();

Um Deine Assets nun in Deinen Symfony Twig Templates nutzen zu können, kannst Du folgende Twig-Helper nutzen:

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

        {% block stylesheets %}
            {# 'app' muss zum argument von addEntry() in webpack.config.js passen #}
            {{ encore_entry_link_tags('app') }}
            <!-- Das Resultat sieht so aus:
                 <link rel="stylesheet" href="/build/app.css"> -->
        {% endblock %}

        {% block javascripts %}
            {{ encore_entry_script_tags('app') }}
            <!-- Das Resultat davon sieht so aus
                <script src="/build/runtime.js" defer></script>
                <script src="/build/app.js" defer></script>
                See note below about the "defer" attribute -->
        {% endblock %}
    </head>

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

Für andere Symfony Projekte wie TYPO3 oder Drupal, gibt es bereits Community Packages:

Fazit:

Wer Webpack in einem Symfony Projekt nutzt, sollte sich auf jeden Fall mal Webpack Encore anschauen. Es gibt sehr viele Community Packages die einem extrem viel Arbeit abnehmen können.

Webpack Encore wird aktiv gepflegt und erhält (Stand 03/2021) regelmäßig Updates. Viel Spaß beim ausprobieren!

Weiterführende Links: