1. Introduzione

    webpack è un cosiddetto "static module bundler", prende in input tutto un insieme di moduli "sorgenti", che possono essere file JS con tutte le loro dipendenze, immagini, file TS, CSS, SASS/LESS, font, etc. e crea in output dei cosiddetti "bundle" (anche più di uno, nel caso si può parlare di "chunks" che compongono il bundle o più semplicemente di bundle multipli) che sono dei file statici interpretabili dal browser.
    Ha parzialmente rimpiazzato i task runner quali Grunt e Gulp.
    I principali componenti sono:
    entry-point: per default è "src/index.js" il file sorgente da cui parte il processo di compilazione
    output: è la cartella "dist" che contiene il risultato della compilazione
    loaders: sono quei package che permettono a webpack di generare il risultato finale
    plugins: sono appunto dei plugin che aggiungono funzionalità alla fase di generazione del bundle

  2. Installazione

    Creo una nuova cartella di progetto e inizializzo il nuovo progetto:
    >npm init -y
    installo webpack e la sua CLI come dipendenze di sviluppo (devDependencies):
    >npm i webpack webpack-cli --save-dev

    La struttura delle cartelle del mio progetto inizialmente sarà più o meno questa:
    progetto
    |______ dist
    |______ src
    index.js
    |______ node_modules
    package.json
    package-lock.json
    webpack.config.js

    La cartella src conterrà i moduli sorgenti, incluso l'entry-point.
    La cartella dist è quella di output che contiene i bundle generati.
    "webpack.config.js" è un file di configurazione da creare a mano.

  3. File di Configurazione

    webpack.config.js è un file di configurazione da posizionare generalmente sotto la root di progetto.
    Nel package.json inserisco questo script:
    "build" : "webpack"
    poi dalla CLI dò il comando
    >npm run build
    in questo modo invoco webpack che compilerà i miei sorgenti e genererà un bundle nella cartella dist, utilizzando le opzioni specificate nel file di configurazione.
    Ad esempio se voglio utilizzare nel mio progetto dei files .css, dovrò installare i loader necessari (sono i package style-css e css-loader) e poi nel file di configurazione devo dire a webpack di utilizzarli (con la proprietà "use") e per quali tipi di file (con la proprità "test" , che accetta una RegExp).
    Per poter utilizzare i file .scss nel progetto sono necessari i loaders: sass-loader e sass.

  4. Bundle multipli

    Ogni file creato dalla build è chiamato "bundle" o "chunk". Se voglio generare più chunks devo specificarlo nel file di configurazione, in particolare nella proprietà "output". E' possibile generare i nomi dei file (dei chunks) in maniera "dinamica" utilizzando una variabile [name].

  5. Plugins

    I plugin forniscono delle funzionalità aggiuntive in fase di generazione della build.
    Esempi di plugin:
    html-webpack-plugin: gestisce automaticamente l'elenco dei "chunks" che includo nel mio file index.html, cioè in fase di generazione va ad inserire in automatico nel file index.html l'elenco dei chunks generati (inserisce i relativi tag " <script></script>" in fondo al file prima della chiusura del </body>. )
    clean-webpack-plugin: cancella tutti i file "vecchi" che non serveno a webpack dalla cartella dist.
    Esistono molti altri plugins (documentazione ufficiale )

  6. Debug e Source Map

    Inserendo questa proprietà nel file di configurazione:
    devtool : "inline-source-map"
    è possibile avere delle info aggiuntive utili quando ci sono degli errori o si deve debuggare. Vengono generate delle "mappe" del codice sorgente, che mi permetteno ad esempio di sapere esattamente quale porzione di codice ha dato errore. Nei devtools del browser (F12), sia sotto "Console" che sotto "Sources" ho delle info più specifiche. Sotto "Sources" trovo tutti i file del mio progetto, sia i sorgenti che quelli ottenuti dalla compilazione.

  7. Watch

    L'opzione "WATCH" permette di avere webpack in ascolto di eventuali modifiche sui file sorgente e nel caso eseguire automaticamente una nuova build.
    E' necessario inserire un nuovo script in package.json:
    "watch": "webpack --watch"
    dopodichè, dalla CLI, anzichè
    >npm run build
    darò
    >npm run watch
    NOTA: ad oggi 23/10/2020 sulla versione 4 di webpack-cli, c'è un baco per cui vengono generati dei warning (DeprecationWarning, info a questo link)
    In alternativa, se inserisco, nel file di configurazione, la proprietà:
    watch: true
    il comando >npm run build compila e poi và in watch.

  8. Web Server

    Per ottenere un server locale sul quale hostare il progetto, bisogna installare questo package:
    >npm i --save-dev webpack-dev-server
    poi nel file package.json aggiungo questo script:
    "start": "webpack serve"
    e infine, da CLI, dò il comando:
    >npm start
    Verrà creato un server locale accessibile sulla porta 8080 (default): http://localhost:8080
    Ad ogni modifica dei file sorgenti ci sarà un " live reload" e la pagina risulterà aggiornata praticamente in tempo reale con le modifiche appena inserite.
    NOTA BENE: webpack-dev-server non scrive nessun file di output dopo la compilazione. Invece, tiene i bundle files generati in memoria e li serve tramite il server locale, per cui nella cartella "dist" non avrò nessun bundle aggiornato. Per aggiornare i file in "dist" devo dare un comando di "build" o "watch".

  9. Esempio

    Questo bottone, al click, invoca una funzione che scrive in Console una stringa.
    Il codice che crea il bottone e gestisce il click è definito nell'entry point file (index.js), mentre la funzione che viene richiamata è definita in un altro modulo (module1.js) che viene "importato" dal modulo chiamante. Vedi codice nella repo.