loading...

Webpack 4 : Quick Start Guide

saileshsubramanian profile image Sailesh Subramanian Updated on ・5 min read

Webpack is one of most commonly used module bundlers available now. It eases the developer's job and provides blazing fast performance coupled with amazing features. From the days of task runners like Grunt and Gulp to Module Bundlers , front-end application development has never been so easier and engaging as today.

"Webpack is a static module bundler for modern JavaScript applications. When webpack processes your application, it internally builds a dependency graph which maps every module your project needs and generates one or more bundles"
Read the core concepts from here

Please note that the sole purpose of this article is to help to quickly build a neat webpack build configuration for a webapps. If you are more interested in learning the basics/core concepts of webpack please refer the above mentioned link to get to know about core concepts of webpack.

Let's Dive in

  1. Create a directory
    mkdir webpack101 && cd webpack101
  2. Use NPM or Yarn for package management
    npm init
    OR
    yarn init
    It will generate the package.json file. Yarn is my favorite , so throughout in this guide yarn will be used.
  3. Install webpack locally(recommended)
    yarn add --dev webpack webpack-cli 
    You can see the webpack being added as dev dependencies in package.
  4. Now lets create a sample project with our usual stuffs.You can find the source files here

Now the project structure is ready let's bring in the main player
webpack.config.js. Create the webpack.config.js in the root.

  1. Now that the initial configuration is ready,lets modify our package.json to add the build command.
  2. Now let's run the build command
    yarn build
  3. We now have a bundle.js inside the dist folder.For the sake of cache busting , include [chunkhash] in the output js file configuration of webpack. So each time the generated js file will be in the format bundle.[chunkhash].js.

Naturally our dist folder will be cluttered with many files. So we need to add
clean-webpack-plugin.

     const { CleanWebpackPlugin } = require('clean-webpack-plugin');
      ......

      plugins: [
         new CleanWebpackPlugin(),
         ....
      ]

But that does not the serve the whole purpose. So let's add more to the webpack.config.js.

Working with ES6
Let's modify our index.js and add some behaviour using ES6. Since the code is in ES6 we need to transpile it so that the browser can understand. Here loaders come for the rescue, and do the code transformation for us.

  1. Adding Babel to the project. We specify the rules in the module section to add the each loaders in webpack.config.js. The test property identifies which file or files should be transformed. The use property indicates which loader should be used to do the transforming.
    yarn add --dev babel-loader @babel/core @babel/preset-env
    Modify the our webpack.config.js as below.
    module:{
        rules: [
            {
              test: /\.(js|jsx)$/,
              exclude: /(node_modules)/,
              use: {
                loader: 'babel-loader',
                options: {
                  presets: ["@babel/preset-env"]
                }
              }
            }
        ]
    }
  1. Add a .babelrc file with contents as below.
     {
        "presets": [
           "@babel/preset-env"
         ]
      }

But how do we see the magic happening? So let's add the webpack-dev-server to run the project locally.

yarn add --dev webpack-dev-server

Also modify the package.json the script to run the dev server and then run yarn serve.
    "serve": "webpack-dev-server --open --config webpack.config.js"
  1. With the css preprocessors taking the significant role in the web development these days , lets create sass files and add loaders to transform and bundle it.
    yarn add --dev style-loader css-loader node-sass sass-loader
    The mini-css-extract-plugin helps us to extract all styles and bundle it in our dist directory. Use MiniCssExtractPlugin.loader instead of style-loader if you need a separate bundle.css file as the style-loader injects all the styles in the head element of your html.
    yarn add --dev mini-css-extract-plugin
    Add the loaders to our webpack.config.js as below.
        const MiniCssExtractPlugin = require('mini-css-extract-plugin');
        ......
         plugins: [
                new MiniCssExtractPlugin({
                    filename:"bundle.[chunkhash].css"
                }),
                ....
          ]

         .....

        {
                test: /\.(sa|sc|c)ss$/,
                use: [

                    {
                        loader: MiniCssExtractPlugin.loader
                    },
                    {
                        loader: "css-loader"
                    },
                    {
                        loader: "sass-loader"
                    }
                ]
            }         

Now comes the role of plugins. We need to modify our HTML files, copy some of the assets to build folder and so on and to do that we need to add certain webpack plugins.

  1. Adding HtmlWebpackPlugin , it generates an HTML file with generated bundle files,both js & css, integrated in the script and link tags. We can even specify the template as well.
     yarn add --dev html-webpack-plugin
    Now modify our webpack.config.jsto add the plugin.
    var HtmlWebpackPlugin = require('html-webpack-plugin');
     .............

     plugins: [new HtmlWebpackPlugin(
        {
          title: 'My App',
          template:'./src/index.html',
          'meta': {
              'viewport': 'width=device-width, initial-scale=1, user-scalable=no'
           }   
       }
     )]

What about assets like fonts, images..Let's add copy-webpack-plugin. The
reason why file-loader was not used because it loads on those assets
referenced in our modules.

yarn add --dev copy-webpack-plugin

Add the configurations for the plugin as well inside webpack.config.js.
   const CopyPlugin = require('copy-webpack-plugin');

   new CopyPlugin([
           { from:'./src/assets', to:'assets'   }
        ])

And finally all our assets are copied to build directory.

Preparing for Different environments

We could actually maintain separate webpack comfiguration files for
development and production deployment, with production files having
production configurations included.

Let's create webpack.common.config.js. Remove all the contents from the
current webpack.config.js and paste it in the new file.Change the output path
options as path:path.resolve(__dirname, '../dist'),

Add the below script in the webpack.config.js to configure different
environments.

    const webpackMerge = require('webpack-merge');
    const commonConfig = require('./webpack.common.config.js');
    module.exports = ({ env }) => {
      const envConfig = require(`./webpack.${env}.config.js`);
      return webpackMerge(commonConfig, envConfig);
      };

Make sure you have the webpack-merge yarn added as dev-dependency.
Now we can to create webpack.dev.config.js and webpack.prod.config.js.
Include the development specific feature config in the webpack.dev.config.js
as below.If they existed in your webpack.common.config remove it to avoid
unexpected results.

      module.exports={
        mode:"development",
        devServer:{
          port:3000,
          hot: true,
          contentBase:'./dist'
       },
       devtool:"inline-source-map"
      }

Same for the webpack.prod.config.js. I leave up to you if you require source-
map in prod mode.

     module.exports={
       mode:"production",
       devtool:"source-map"
     }

Modify the scripts to run for different environment in package.json to look
more meaningful.

     "scripts": {
     "serve": "webpack-dev-server --open --config build-config/webpack.config.js 
              --env.env=dev",
     "build:dev": "webpack --config build-config/webpack.config.js 
                  --env.env=dev",
     "build:prod": "webpack --config build-config/webpack.config.js 
                  --env.env=prod"
      }

You can again go for optimization techniques available with other webpack
plugins in the production mode. Since v4 webpack does the optimization for
you based on the mode. But you can override those with your own
configurations. uglify-js , optimise-css-assets are most popular.

Thanks for reading.I hope that was informative .If you have any corrections or
suggestion, please let me know in the comments section. Happy Coding !!

Posted on by:

saileshsubramanian profile

Sailesh Subramanian

@saileshsubramanian

Senior Web/ Hybrid App Engineer, Small-time writer, Cricket enthusiast.

Discussion

pic
Editor guide