Contao Agenturtag 2021

Peter Adelmann, trilobit GmbH

Webpack in Contao Projekten

Contao Agenturtag 2021

ACHTUNG!

Was ist Webpack?

Webpack I

de.wikipedia.org/wiki/Webpack

Webpack II

Mit Loadern ...

Wann / Warum soll ich das gebrauchen können?

Webpack III

Webpack IV

Assets werden automatisch ...

Webpack V

Tools können implementiert werden für ...

Installation

Yarn vs npm

OS


curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg
    | sudo apt-key add -

echo "deb https://dl.yarnpkg.com/debian/ stable main"
    | sudo tee /etc/apt/sources.list.d/yarn.list

sudo apt update
sudo apt install yarn


        

Beispielhaft auf einem Linux System

Contao


yarn install

composer require symfony/webpack-encore-bundle


        

Installation innerhalb des Contao Projekts

Struktur

Verzeichnis-Struktur


|- ...
|- config
|  |- config.yml       ⇐ Ergänzungen
|
|- layout              ⇐ neu
|  |- backend
|  |  |- backend.ts
|  |  |- backend.scss
|  |  |- backend.js
|  |
|  |- frontend
|  |  |- scripts
|  |  |- styles
|  |  |- frontend.ts
|  |
|  |- resources
|     |- fonts
|     |- icons
|
|- templates           ⇐ Ergänzungen
|  |- encore           ⇐ neu
|
|- webpack.config.js   ⇐ neu ff
|- tsconfig.json
|- tslint.json
|- package.json
|- postcss.config.js
|- .stylelintrc
|- .stylelintignore
|
|- web
|  |- layout           ⇐ neu
|
|- ...
        

Ablage innerhalb des Contao Projekts; Verzeichnisse & Dateien

Konfiguration

Dateien

config.yml

docs.contao.org/dev/reference/config

config.yml

webpack_encore:
  output_path: '%kernel.project_dir%/web/layout/'
 
twig:
  default_path: '%kernel.project_dir%/templates'
  paths:
    '%kernel.project_dir%/templates': app
 
        

Ergänzungen zu einer bestehenden Contao Konfigurationsdatei

webpack.config.js

webpack.js.org/configuration

webpack.config.js

let Encore = require('@symfony/webpack-encore');
 
Encore
    .setOutputPath('web/layout/')
    .setPublicPath('/layout')
 
    .addEntry('backend', './layout/backend/backend.ts')
    .addEntry('frontend', './layout/frontend/frontend.ts')
 
    .addLoader(
        {
            test: /\.scss|\.ts$/,
            enforce: 'pre',
            loader: 'import-glob-loader'
        }
    )
 
    .splitEntryChunks()
 
    .autoProvidejQuery()
 
    .cleanupOutputBeforeBuild()
 
    .enableSourceMaps(!Encore.isProduction())
    .enableVersioning(Encore.isProduction())
 
    .enableSingleRuntimeChunk()
    .enableBuildNotifications()
    .enableTypeScriptLoader()
    .enableSassLoader()
    .enablePostCssLoader()
;
 
if (Encore.isDevServer()) {
    Encore.disableCssExtraction()
}
 
const webpackConfig = Encore.getWebpackConfig();
 
webpackConfig.devServer = {
    host: '0.0.0.0',
    publicPath: '/layout/',
    port: 8080,
    headers: {'Access-Control-Allow-Origin': '*'},
    https: false,
    disableHostCheck: true
};
 
module.exports = webpackConfig;
 
        

Bspl. mit zwei Entrypoints, verschiedenen Loadern & Dev-Server

package.json

docs.npmjs.com/cli/v7/configuring-npm/package-json

package.json

{
  "license": "UNLICENSED",
  "dependencies": {
    "@fortawesome/fontawesome-free": "^5.11.2",
    "bootstrap": "^4.3.1",
    "ekko-lightbox": "^5.3.0",
    "jquery": "^3.4.1",
    "leaflet": "^1.6.0",
    "popper.js": "^1.16.1"
  },
  "devDependencies": {
    "@symfony/webpack-encore": "^0.31.0",
    "core-js": "^3.0.0",
    "import-glob-loader": "^1.1.0",
    "node-sass": "^4.14.1",
    "postcss-import": "^12.0.1",
    "postcss-loader": "^3.0.0",
    "postcss-preset-env": "^6.7.0",
    "sass-loader": "^9.0.1",
    "stylelint": "^13.7.1",
    "stylelint-config-standard-scss": "^1.1.0",
    "stylelint-scss": "^3.18.0",
    "ts-loader": "^5.3.0",
    "typescript": "^4.0.3",
    "webpack-notifier": "^1.6.0"
  },
  "scripts": {
    "build": "yarn encore prod --progress",
    "dev": "yarn encore dev",
    "dev-server": "yarn encore dev-server",
    "watch": "yarn encore dev --https --watch"
  },
  "browserslist": [
    "> 0.5%",
    "last 2 versions",
    "Firefox ESR",
    "not dead"
  ]
}
 
        

Bspl. Modulen für Layout & Inhalt; Linting, Skripten, Browser-Kompatibilität

tsconfig.json

typescriptlang.org/docs/handbook/tsconfig-json.html

tsconfig.json

{
  "compilerOptions": {
    "target": "es5",
    "lib": ["es6", "dom"]
  },
  "exclude": [
    "node_modules",
    "vendor",
    "assets"
  ]
}
 
        

Bspl. einfach-Konfiguration

tslint.json

palantir.github.io/tslint/usage/cli

tslint.json

{
  "defaultSeverity": "error",
  "extends": [
    "tslint:recommended",
    "tslint-config-airbnb",
    "tslint-config-prettier"
  ],
  "rules": {
    "no-var-requires": false,
    "member-ordering": [true, {"order": "fields-first"}]
  },
  "jsRules": {},
  "rulesDirectory": []
}
 
        

Bspl. einfach-Konfiguration

.stylelintrc

stylelint.io

.stylelintrc

{
  "extends": [
    "stylelint-config-standard-scss"
  ],
  "rules": {
    "number-leading-zero": "never",
    "at-rule-empty-line-before": null,
    "selector-id-pattern": "^(wrapper|container|left|right|main|header|footer)$",
    "at-rule-no-unknown": null,
    "scss/at-rule-no-unknown": true,
    "block-no-empty": true,
    "comment-no-empty": true,
    "no-duplicate-at-import-rules": true,
    "no-empty-source": true,
    "no-invalid-double-slash-comments": true,
    "max-nesting-depth": 4,
    "indentation": 2,
    "no-descending-specificity": null
  },
  "ignore": [
    "blockless-at-rules",
    "pseudo-classes",
    "selectors-within-list"
  ]
}
 
        

Bspl. einfache Linter-Konfiguration

.stylelintignore

stylelint.io

.stylelintignore

layout/resources
 
        

Bspl. einfache Konfiguration; extrene Ressourcen nicht berücksichtigen

postcss.config.js

github.com/postcss/postcss

postcss.config.js

module.exports = {
    plugins: {
        'postcss-import': {},
        'postcss-preset-env': {},
        'cssnano': {}
    }
};
 
        

Bspl. einfache Konfiguration

be_main.html5
fe_page.html5

docs.contao.org/dev/framework/templates

be_main.html5

<?php $this->extend('be_main'); ?>
 
<?php $this->block('head'); ?>
    <?php $this->parent(); ?>
    <?= \Contao\System::getContainer()
            ->get('twig')
            ->render('@app/encore/be_encore_link_tags.html.twig'); ?>
<?php $this->endblock(); ?>
 
<?php $this->block('container'); ?>
    <?php $this->parent(); ?>
    <?= \Contao\System::getContainer()
            ->get('twig')
            ->render('@app/encore/be_encore_script_tags.html.twig'); ?>
 
<?php $this->endblock(); ?>
 
        

Bspl. Einbindung in BE Template

*_encore_entry_link_tags.html.twig
*_encore_entry_scripts_tags.html.twig

twig.symfony.com

be_encore_entry_link_tags.html.twig

{{ encore_entry_link_tags('backend') }}
 
        

Bspl. Style Backend Entry Point

be_encore_entry_script_tags.html.twig

{{ encore_entry_script_tags('backend') }}
 
        

Bspl. Script Backend Entry Point
Name innerhalb der einfachen Hochkommata entspricht dem Namen in der webpack.config.js

Arbeiten

;-)

ck21-webpack-demo.trilobit.home

Live Beispiel

Commands


yarn encore dev

yarn encore dev-server --watch

yarn encore dev-server --hot --https --disable-host-check --host ck21-webpack-demo.trilobit.home

yarn encore production


        

Beispielhaft auf einem Linux System

Vereinfachungen

Ganz schön viel Overhead?!

Ja! & Nein!

Erfahrungen

Lohnt sich der Overhead?

Ja!

Unser Alltag

Weitere Schritte

Weitere Schritte

Vielen DANK!




Wir lieben Kunden, für die der Livegang einer Webseite nicht das Ende sondern der Anfang des Abenteuers ist.

trilobit GmbH

KnowHow

trilobit GmbH / Peter Adelmann