Webpack 4 | Quick start guide

Sailesh Subramanian
5 min readMar 31, 2020
Photo by Clément H on Unsplash

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

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.

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, let’s 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(),
....
]

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"]
}
}
}
]
}

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"

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.

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 !!

--

--

Sailesh Subramanian

Front End Engineer @ Tata Consultancy Services Ltd. Cricket enthusiast. Small time writer.