Webpack - A Detailed Introduction - Smashing Magazine

  1. Basic setup:

    1. Go to directory

    2. npm init → Initialise npm

    3. create src folder and put script.js, index.html and style.css in it.

      in index.html

      <!DOCTYPE html>
      <html lang="en">
      <head>
          <meta charset="UTF-8">
          <meta http-equiv="X-UA-Compatible" content="IE=edge">
          <meta name="viewport" content="width=device-width, initial-scale=1.0">
          <title>Document Name</title>
      </head>
      <body>
          
      </body>
      </html>
      

      in script.js add:

      import ./style.css
      

      in style.css add:

      * {
          margin: 0;
          padding: 0;
      

      PS: We adding just the basic boiler plate.

  2. Webpack Setup

    1. yarn add webpack webpack-cli in CLI to add webpack dependencies: webpack and webpack-cli
    2. Create bundler folder at the same level as src
    3. Create webpack.common.js in it.
    4. Removie "main" from package.json → removing the entry point from package.json to avoid clashes.
  3. Webpack Configuration:

    1. Creating entry and output -> in webpack.common.js

      const path = require('path');
      
      module.exports = {
          entry: path.resolve(__dirname, '../src/script.js'),
          output:
          {
              filename: 'bundle.[contenthash].js',
              path: path.resolve(__dirname, '../dist')
          },
      		devtool: 'source-map',
      }
      
    2. For testing in package.json add the following scripts:

      "scripts": {
          "test": "webpack --config ./bundler/webpack.common.js",
      },
      

      here we are specifing that instead of having a webpack.config.js file in our e=root folder we have seperated it on to a bundler folder.

      You can run npm run test any time in between to see the output in the dist folder

  4. Installing loaders, plugins and writing corresponding rules for webpack configuration:

    Learn Webpack Pt. 8: Html-loader, File-loader, & Clean-webpack

  5. Adding file-loader other loaders for handeling fonts and images

  6. Adding copy-webpack-plugin:

    Copies individual files or entire directories, which already exist, to the build directory.

    The idea here is you will have a static folder in dev where you will store all your fonts, images, etc, and in prod build you want this to be all copied in the build folder.

    Without this plugin, in the final production folder that is created, only those images will be bundles that are imported in the javascript.

    Also make sure from now on you have atleast one image inside the static folder, else it will trown an error.

    The structure inside the static folder will be replicated in the dist (production build) folder.

    Make sure you create a static folder first.

  7. Creating Dev Configuration: to start a live server.

    We will use webpack.common.js a commn configuration that will be used by for the dev and prod configurations:

    In Dev server, files get build in memory and are destroyed as soon as the server id destroyed.

    1. Create a webpack.dev.js file in bundler folder

    2. Importing commonConfiguration from webpack.common.js

      1. To import we will need webpack-merge module

        • yarn add webpack-merge
      2. Adding basic things to webpack.dev.js

        const { merge } = require('webpack-merge')
        const commonConfiguration = require('./webpack.common.js')
        module.exports = merge(
            commonConfiguration,
            {
                mode: 'development'
            }
        )
        
    3. Adding dev script in package.json

      "scripts": {
        "test": "webpack --config ./bundler/webpack.common.js",
        "dev": "webpack serve --config ./bundler/webpack.dev.js",
      },
      

      here the serve flag will make it live reload, but before running it, there are still a few things we need to add to serve this app.

    4. Adding Server Dependencies.

      • yarn add portfinder-sync

        Find an open port synchronously.

      • yarn add D webpack-dev-server

        Dev Server for web applications, ideal for buildless es module workflows. Optionally supports simple code transformations.

        This is added so now the webpack 'serve' command is recognised

    5. Updating wepack dev:

      1. Importing required modules:

        const ip = require('internal-ip')
        const portFinderSync = require('portfinder-sync')
        
      2. Function that prints local domain (where server is running) names distinctly:

        const infoColor = (_message) => {
            return `\\u001b[1m\\u001b[34m${_message}\\u001b[39m\\u001b[22m`
        }
        
      3. Adding devServer key to module exports:

        devServer: {
          host: '0.0.0.0',
          port: portFinderSync.getPort(8080),
          contentBase: './dist',
          watchContentBase: true,
          open: true,
          https: false,
          useLocalIp: true,
          disableHostCheck: true,
          overlay: true,
          noInfo: true,
          after: function(app, server, compiler)
          {
              const port = server.options.port
              const https = server.options.https ? 's' : ''
              const localIp = ip.v4.sync()
              const domain1 = `http${https}://${localIp}:${port}`
              const domain2 = `http${https}://localhost:${port}`
              
              console.log(`Project running at:\\n  - ${infoColor(domain1)}\\n  - ${infoColor(domain2)}`)
          }
        }
        

      Try running npm run dev and you should see a live server being sprung up! and this is now live updating with all the changes you make!

  8. Creating build Configuration: to creat a production ready dist folder.

    1. Creating a production configuration file in bundlers folder:

      bundlers → webpack.prod.js

    2. Adding basic configurations to webpack.prod.js:

      const { merge } = require('webpack-merge')
      const commonConfiguration = require('./webpack.common.js')
      
      module.exports = merge(
          commonConfiguration,
          {
              mode: 'production',
          }
      )
      

      It will use the same merge and commonConfiguration as dev configuration. We will just change the mode.

    3. Adding Plugin:

      • yarn add clean-webpack-plugin

        A webpack plugin to remove/clean your build folder(s).

        It makes sure that there is no dist folder.

        If there is already existing one it deletes it.

      • Importing and Declating Plugin in the webpack production configuration:

        const { merge } = require('webpack-merge')
        const commonConfiguration = require('./webpack.common.js')
        const { CleanWebpackPlugin } = require('clean-webpack-plugin')
        
        module.exports = merge(
            commonConfiguration,
            {
                mode: 'production',
                plugins:
                [
                    new CleanWebpackPlugin()
                ]
            }
        )
        
    4. Add scripts to package.json for a build command.

      "scripts": {
        "test": "webpack --config ./bundler/webpack.common.js",
        "dev": "webpack serve --config ./bundler/webpack.dev.js",
        "build": "webpack --config ./bundler/webpack.prod.js"
      },
      

    And that should be it, try running npm run build and check the dist folder that would have been created.

  9. Adding raw-loader for loading shaders: