Setup di Bootstrap 4 con webpack per lo sviluppo locale

C’è stato un periodo in cui facevo lo sviluppatore frontend fulltime. C’erano i preprocessori, i task runner e i package manager. Usavo quotidianamente Bootstrap 2, Bower, Grunt, LESS. Dopo oltre 7 anni  ho scoperto che Bootstrap è arrivato alla versione 4, che si appoggia a webpack e come impostare il mio ambiente di sviluppo.

Ecco un po’ di appunti per non dimenticarmi come fare 😅

Per cominciare

Come al solito un punto di partenza fondamentale è l’ottima documentazione di webpack. Quindi suggerisco di seguire questo ottimo articolo che spiega passo passo come impostare il proprio ambiente, con tutti i comandi npm da lanciare nel vostro terminale per ottenere tutti i moduli di cui avrete bisogno (quasi tutto questo post è preso da quell’articolo 🙏)

Si tratta di inizializzare il progetto con npm per ottenere un file package.json e successivamente installare webpack.

$ mkdir bootstrap-webpack && cd bootstrap-webpack
$ npm init -y
$ npm install webpack --save-devCode language: Shell Session (shell)

P.S. Tutto il codice e le spiegazioni più dettagliate nell’articolo linkato qui sopra.

Successivamente vi servirà avere in locale bootstrap e le sue dipendenze (jQuery e popper.js).

$ npm install bootstrap jquery popper.js --saveCode language: Shell Session (shell)

Quindi un po’ di moduli per compilare poi i sorgenti a seconda dei vari casi

$ npm install exports-loader autoprefixer css-loader node-sass postcss-loader sass-loader style-loader --save-devCode language: Shell Session (shell)

Per gestire la vostra configurazione vi sarà utile infine creare il file webpack.config.js:

const path = require('path');

module.exports = {
  entry: './src/app.js',
  output: {
    filename: 'bundle.js',
    path: path.resolve(__dirname, 'dist')
  },
  module: {
    rules: [
      {
        test: /\.(scss)$/,
        use: [
          {
            // Adds CSS to the DOM by injecting a `<style>` tag
            loader: 'style-loader'
          },
          {
            // Interprets `@import` and `url()` like `import/require()` and will resolve them
            loader: 'css-loader'
          },
          {
            // Loader for webpack to process CSS with PostCSS
            loader: 'postcss-loader',
            options: {
              plugins: function () {
                return [
                  require('autoprefixer')
                ];
              }
            }
          },
          {
            // Loads a SASS/SCSS file and compiles it to CSS
            loader: 'sass-loader'
          }
        ]
      }
    ]
  }
};
Code language: JavaScript (javascript)

Per lavorare con i file scss creiamo un file  /src/scss/app.scss e importiamo l’intera libreria di componenti con

@import "~bootstrap/scss/bootstrap";Code language: SCSS (scss)

Quindi creiamo il file /src/app.js che conterrà le informazioni sui nostri componenti javascript. Per il mio scenario è sufficiente avere all’interno le due righe:

import 'bootstrap';
import './scss/custom.scss';
Code language: JavaScript (javascript)

Aggiungiamo al file package.json la direttiva "build": "webpack", per compilare il progetto usando il comando npm run build.

Al termine dell’articolo avremo così scoperto come compilare correttamente il progetto Bootstrap a partire dai sorgenti scss e js.

Automatismi

Per evitare di eseguire npm run build per ogni modifica ai vostri file, è utile seguire la guida di webpack per l’ambiente di sviluppo.

Per il mio scenario la scelta è usare webpack-dev-server. Questo mi permetterà di avere il progetto compilato all’indirizzo http://localhost:8080. Ogni volta che un file sorgente verrà modificato sarà webpack a preoccuparsi di ri-compilare tutti gli asset senza che io ci debba pensare.

Per installare il modulo eseguiamo il comando

$npm install --save-dev webpack-dev-serverCode language: Shell Session (shell)

quindi andiamo a modificare il file webpack.config.js aggiungendo

mode: 'development',Code language: JavaScript (javascript)

e la cartella di destinazione per i nostri file compilati con le seguenti tre righe:

devServer: {
  contentBase: './dist',
},Code language: JavaScript (javascript)

A questo punto potete aggiungere al file package.json le direttive per osservare e compilare i sorgenti:

"scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "watch": "webpack --watch",
    "start": "webpack-dev-server --open",
    "build": "webpack"
  },Code language: JSON / JSON with Comments (json)

In questo modo lanciando il comando npm run watch webpack ricompilerà il progetto ad ogni modifica dei file sorgenti. Il comando npm run start invece lancerà un piccolo servizio accessibile a http://localhost:8080 permettendovi di vedere il vostro sito sempre aggiornato, senza dover cliccare il pulsante “ricarica”.

Altri plugin e opzioni

Wepack infila tutto in un unico file javascript. Sì, anche il CSS, che viene iniettato nella pagina .html come stile inline. Per questo motivo avevo esplorato il MiniCssExtractPlugin che mi permette di avere invece un file .css esterno.

Tra le altre sezioni importanti per cominciare con webpack, consiglio Output Management e Production.

Per riassumere

Ecco qui sotto i miei due file webpack.config.js e package.json:

webpack.config.js

const path = require('path');

module.exports = {
  mode: 'development',
  entry: './src/app.js',
  output: {
    filename: 'bundle.js',
    path: path.resolve(__dirname, 'dist'),
  },
  devtool: 'inline-source-map',
  devServer: {
    contentBase: './dist',
  },
  module: {
    rules: [
      {
          test: /\.(scss)$/,
          use: [{
              loader: 'style-loader', // inject CSS to page
          }, {
              loader: 'css-loader', // translates CSS into CommonJS modules
          }, {
              loader: 'postcss-loader', // Run postcss actions
              options: {
                  plugins: function () { // postcss plugins, can be exported to postcss.config.js
                      return [
                          require('autoprefixer')
                      ];
                  }
              }
          }, {
              loader: 'sass-loader' // compiles Sass to CSS
          }]
      },
    ],
  },
};
Code language: JavaScript (javascript)

package.json

{
  "name": "bootstrap-webpack",
  "version": "1.0.0",
  "description": "Un progetto per fare esperimenti",
  "main": "bundle.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "watch": "webpack --watch",
    "start": "webpack-dev-server --open",
    "build": "webpack"
  },
  "keywords": [],
  "author": "Giulio",
  "license": "ISC",
  "devDependencies": {
    "autoprefixer": "^9.7.6",
    "clean-webpack-plugin": "^3.0.0",
    "css-loader": "^3.5.2",
    "html-webpack-plugin": "^4.2.0",
    "mini-css-extract-plugin": "^0.9.0",
    "node-sass": "^4.13.1",
    "postcss-loader": "^3.0.0",
    "sass": "^1.26.3",
    "sass-loader": "^8.0.2",
    "style-loader": "^1.1.4",
    "webpack": "^4.42.1",
    "webpack-cli": "^3.3.11",
    "webpack-dev-server": "^3.10.3"
  },
  "dependencies": {
    "bootstrap": "^4.4.1",
    "jquery": "^3.5.0",
    "popper.js": "^1.16.1",
    "postcss-cli": "^7.1.0"
  }
}
Code language: JSON / JSON with Comments (json)
Torna in alto