Nette Framework + Webpack 4 17/03/2018

V rámci tréninku jsem vytvořil ukázkový projekt s Nette a Webpack 4.

Na Nette fóru se řešilo, zda-li použít Webpack, Gulp nebo Grunt. Dost často se také řeší, jestli použít nette.ajax.js nebo něco jiného. Ale co jiného? No třeba knihovnu Naja. Ja osobně používám Webpack, a snadno můžete i vy.

Webpack nedávno vyšel ve verzi 4, která značně zjednodušuje použití a přináší velkou optimalizaci. Nerad bych popisoval, co všechno Webpack 4 umí, na to je kupa jiných článků.


Webpack

Pojďme se podívat na Webpack 4 v Nette Frameworku.

Všechny zdrojové kódy jsou na Githubu (https://github.com/trainit/2018-03-nette-webpack/). Základem pro nás bude nette/sandbox. Pro konfiguraci webpack používá soubor webpack.config.js. Ten může vypadat třeba takto:

const webpack = require('webpack');
const path = require('path');

module.exports = {
    entry: {
        app: './www/assets/app.js'
    },
    output: {
        path: path.join(__dirname, 'www/dist'),
        filename: '[name].bundle.js'
    },
    module: {
        rules: [
            {
                test: /\.js?$/,
                exclude: /node_modules/,
                loader: 'babel-loader',
                query: {
                    cacheDirectory: true,
                    "presets": [
                        ["env", {
                            "targets": {
                                "browsers": ["last 2 versions", "safari >= 7"]
                            }
                        }]
                    ]
                },
            },
            {
                test: /\.css$/, loader: 'style-loader!css-loader'
            },
            {
                test: /\.woff2?(\?v=[0-9]\.[0-9]\.[0-9])?$/,
                use: 'url-loader?limit=10000',
            },
            {
                test: /\.(ttf|eot|svg)(\?[\s\S]+)?$/,
                use: 'file-loader',
            },
            {
                test: /\.(jpe?g|png|gif|svg)$/i,
                use: [
                    'file-loader?name=images/[name].[ext]',
                ]
            }
        ]
    },
    plugins: [
        new webpack.ProvidePlugin({
            $: 'jquery',
            jQuery: 'jquery',
            'window.jQuery': 'jquery',
        })
    ]
};

Zdá se komplikovaný? Není, copy & paste to jistí. Blíže si rozebereme jednotlivé části.

Entrypoint

entry: {
    app: './www/assets/app.js'
}

Tím říkáme, z jakých hlavních častí se naše aplikace skládá. Pro ukázku je použit jenom jeden vstup, ale jednoduše oddělíme třeba frontend a backend části. Nebo více modulů.

entry: {
    frontend: './www/assets/frontend.js',
    backend: './www/assets/backend.js'
}

Endpoint

output: {
    path: path.join(__dirname, 'www/dist'),
    filename: '[name].bundle.js'
}

Output.path definuje místo, kam se uloží sestavený bundle. V output.filename máme magickou proměnnou [name], což pro výše definované 2 entrypointy bude frontend.bundle.js a backend.bundle.js.

Rules

{
    test: /\.(jpe?g|png|gif|svg)$/i,
    use: [
        'file-loader?name=images/[name].[ext]',
    ]
}

Sekce rules je nejkomplikovanější, ale také nejduležitější. Definuje pravidla, podle kterých webpack nakládá s jednotlivými soubory.

Nebudeme si popisovat všechny, ale dobrým příkladem může být generování obrázků.

Rule.test je regulární výraz, nejčastěji definujicí koncovky, pro které se pravidlo uplatňuje. Rule.use je definici loaderů. Každý loader musíte mít nainstalovaný přes NPM/YARN, tzn. npm i --save-dev file-loader. Loader lze dokonfigurovat, např. přidáním hodnot za otazník. name=images/[name].[ext] říká, že webpack dumpne soubory do www/dist/images/[name].[ext].

Plugins

plugins: [
        new webpack.ProvidePlugin({
            $: 'jquery',
            jQuery: 'jquery',
            'window.jQuery': 'jquery',
        })
    ]

Existuje celá řada pluginů: https://webpack.js.org/plugins/

jQuery vyžaduje definování speciálních proměnných pro běh scriptů a dalších jQuery pluginů. Je to zlo(!), které ale funguje už řadu let.

NPM

Základní vhled do Webpacku bychom měli za sebou. Pro čistě frontendové (SPA) aplikace by konfigurace vypadala daleko složitěji. Na druhou stranu, bez jQuery a dalších věcí by byla zase o poznání menší.

Pro sestavení bundlů využijeme NPM scripty.

"scripts": {
    "dev": "webpack --mode development --watch --progress",
    "build": "webpack --mode production"
}

Development

Pro vývoj je vhodné, abychom mohli dělat změny v souborech a Webpack nám na pozadí aktualizoval bundle. Pokud nepoužijeme Webpack Dev Server, tak nám zbýva monitorovat soubory přes watch.

npm run dev

# webpack --mode development --watch --progress

Production

Na produkci nám jde o velikost, nepotřebujeme komentáře, kusy mrtvého kódu apod. Všechny tyto optimalizace provede Webpack při sestavení produkčního bundlu.

npm run build

# webpack --mode production

Vidíte, jak Webpack nadává na velikost? Díky tomu poznáte, jestli máte vše v pořádku a správně optimalizované. Pro naše účely nám to takto stačí.

PHP

Pro jednoduchost si zapneme PHP Development Server. Je to skvělý nástroj pro lokální vývoj, dokonce zvládá COOL url adresy.

php -S 0.0.0.0:8000 -t www

Browser

V prohlížeci už se na závěr pokocháme fungujícími assety a funkčními snippety.

Závěr

  1. Webpack není složitý.
  2. Použijte Webpack 4. Je fakt rychlý!
  3. Dejte šanci moderní AJAX knihovně Naja od Jirky Pudila.
  4. PHP Development Server na lokální vývoj stačí.
  5. Nebojte se dávát hvězdičky na Githubu. Nebolí to.

Máte-li nápady na vylepšení ukázkového repozitáře, sem s nimi. Nefunguje vám ukázkový projekt? Nechte mi komentář.