Learn About Webpack and Why Should use it

Learn About Webpack and Why Should use it

If you’re wondering how did our tooling became more and more complicated that we have to use build tools like webpack, let us go back in the days where web development was so simple that including a simple script is already enough.

Why Webpack?


The field of Front-End development is changing so rapidly on how we do things these days. Back when life was so simple and before front-end libraries and frameworks started appearing, there used to be just a simple javascript file that you have to include in your html file and you’re good to go.

In CSS we have a couple of libraries and frameworks to use these days. This makes front-end development more and more challenging. The same can be said with JavaScript ecosystem. Not only that we have changing libraries and frameworks to use, but we also have changed the standards these days like ES6 and beyond. Big three frameworks like Angular, React, Vue came into play the past few years.

Then came these so-called “module bundlers” or build tools, namely webpack, browserify, and gulp.

If you’re wondering how did our tooling became more and more complicated that we have to use build tools like webpack, let us go back in the days where web development was so simple that including a simple script is already enough.

Tip

Use Bit to encapsulate components with all their dependencies and setup. Share them on Bit’s cloud, collaborate with your team and use them anywhere.

What is Webpack?

First, let us define what is Webpack. According to the official site, Webpack is a static module bundler for modern JavaScript applications. It builds a dependency graph that is responsible for bundling all your javascript modules into one regardless where they are located when one javascript file depends on each other.

In short, Webpack is a bundler that is responsible for bundling all your javascript files to make it work.

The time before libraries, frameworks, and build tools like Webpack

Back then life was so much simpler that we just need to include a single script in our HTML such as this then solve problems right away:

<head>
   <script src="main.js" type="text/javascript"></script>
</head>

But then, libraries came so we have to include them one by one and in the proper order to make them work interdependently:

<head>
   <script src="library1.js" type="text/javascript"></script>
   <script src="library2.js" type="text/javascript"></script>
   <script src="script.js" type="text/javascript"></script>
</head>

Then the ecosystem added frameworks such as Ember, Backbone, Meteor, React, Vue, Angular and things got complicated from there. Add in some more changing standards of javascript like ES6, ES7 and beyond.

Then lastly came build tools such as browserifygruntwebpack and we totally got lost in the sea of uncharted waters of Front-End ecosystem:

var webpack = require("webpack");
    var path = require("path");
    var HtmlWebpackPlugin = require("html-webpack-plugin");
    const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;


module.exports = {
    entry: {
        bundle: './src/index.js'
    },
    output: {
        path: path.join(__dirname, "../dist"),
        //note: we changed `bundle` name into a variable `[name]` to get the key values in `entry` property instead of declaring the name statically.
        //[chunkhash] - this is a large string of characters that uses hash. If vendor or javascript files were updated, webpack will automatically bundle the contents of the file then generate a different hash.
        filename: "[name].[chunkhash].js"
    },
    mode: "development",
    devtool: "inline-source-map",
    devServer: {
        proxy: {
            '/api': {
                target: "http://localhost:3000",
                secure: false,
                changeOrigin: true
            }
        }
    },
    module: {
        rules: [
            {
                use: {
                    loader: "babel-loader"
                },
                test: /\.js$/,
                exclude: /node_modules/ //excludes node_modules folder from being transpiled by babel. We do this because it's a waste of resources to do so.
            },
            {
                use: ['style-loader', 'css-loader'],
                test: /\.css$/
            }
        ]
    },
    plugins: [
        //`manifest` - Gives the browser a better understanding that tells whether the vendor file has actually got changed.
        // new webpack.optimize.CommonsChunkPlugin({
        //     names: ['vendor', 'manifest']
        // }), //We need to include this plugin so that it never duplicates the libraries that were included in `vendor.js` within `bundle.js` as well
        new HtmlWebpackPlugin({
            template: 'src/index.html'
        }), //this plugin is responsible for injecting the entry scripts of webpack (such as `bundle.js` and `vendor.js`) inside the html file without specifying them manually.        
        new webpack.DefinePlugin({
            'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV) //we will set the correct variable for `process.env.NODE_ENV` variable inside the `scripts` property in `package.json`
        }), //This adds windows-scoped variables that will be defined in bundle.js
        // new BundleAnalyzerPlugin()
    ],
    optimization: {
        splitChunks: {
            chunks: 'async',
            minSize: 30000,
            maxSize: 0,
            minChunks: 1,
            maxAsyncRequests: 5,
            maxInitialRequests: 3,
            automaticNameDelimiter: '~',
            name: true,
            cacheGroups: {
                commons: {
                    test: /[\\/]node_modules[\\/]/,
                    name: 'vendors',
                    chunks: 'all'
                },
                default: {
                    minChunks: 2,
                    priority: -20,
                    reuseExistingChunk: true
                }
            }
        }
    }
};


var webpack = require("webpack");
    var path = require("path");
    var HtmlWebpackPlugin = require("html-webpack-plugin");
    const CompressionPlugin = require("compression-webpack-plugin");

module.exports = {
    entry: {
        bundle: './src/index.js'
    },
    output: {
        path: path.join(__dirname, "../dist"),
        //note: we changed `bundle` name into a variable `[name]` to get the key values in `entry` property instead of declaring the name statically.
        //[chunkhash] - this is a large string of characters that uses hash. If vendor or javascript files were updated, webpack will automatically bundle the contents of the file then generate a different hash.
        filename: "[name].[chunkhash].js"
    },
    mode: "development",
    devServer: {
        proxy: {
            '/api': {
                target: "http://localhost:3000",
                secure: false,
                changeOrigin: true
            }
        }
    },
    module: {
        rules: [
            {
                use: {
                    loader: "babel-loader"
                },
                test: /\.js$/,
                exclude: /node_modules/ //excludes node_modules folder from being transpiled by babel. We do this because it's a waste of resources to do so.
            },
            {
                use: ['style-loader', 'css-loader'],
                test: /\.css$/
            }
        ]
    },
    plugins: [
        new HtmlWebpackPlugin({
            template: 'src/index.html'
        }), //this plugin is responsible for injecting the entry scripts of webpack (such as `bundle.js` and `vendor.js`) inside the html file without specifying them manually.
        new webpack.DefinePlugin({
            'process.env.NODE_ENV': JSON.stringify('production') //we will set the correct variable for `process.env.NODE_ENV` variable inside the `scripts` property in `package.json`
        }) //This adds windows-scoped variables that will be defined in bundle.js
    ],
    optimization: {
        minimize: true,
        splitChunks: {
            chunks: 'async',
            minSize: 30000,
            maxSize: 0,
            minChunks: 1,
            maxAsyncRequests: 5,
            maxInitialRequests: 3,
            automaticNameDelimiter: '~',
            name: true,
            cacheGroups: {
                commons: {
                    test: /[\\/]node_modules[\\/]/,
                    name: 'vendors',
                    chunks: 'all'
                },
                default: {
                    minChunks: 2,
                    priority: -20,
                    reuseExistingChunk: true
                }
            }
        }
    }
};

I have to admit that when I heard and read these stacks to learn in the developer community, I was one of the developers that got intimidated in climbing the Front-End ecosystem until I gave it a break then started giving it a shot again.

How did we get into this mess?

First, let us ask how did we actually get into this mess and what problems do build tools like webpack solve.

These are the problems webpack was trying to solve:

Automation

You might not be a big fan of including every javascript libraries in your HTML headers but prefer to use npm for including such libraries you want to use in your functionality.

Webpack does that for you. You just simply need to install any library of choice you want from npm then webpack can automatically include that library in the bundle for you if you’re making use of them in your modules.

Load Speed

Loading individual scripts within a webpage is very costly if we were to create a modern web app.

Webpack helps us improve the loading speed by bundling every javascript modules we have into one since we only ask once in fetching our script from the webserver. It makes sense since when we just fetch our javascript files one by one, we’re putting stress on webserver by fetching those files a couple of times in contrast to one big file being requested from webserver.

This might be true prior to the advent of HTTP/2, but things might have changed since then.

Only load necessary scripts when needed

Under normal circumstances, your app will load every javascript modules and libraries you had regardless if you need these functionalities or not. But what if at some point you don’t need some of the libraries in that particular functionality or module the user is using as of the moment?

Take a look at this graph in our developer console:

The red on the graph indicates the percentage of scripts unused in your app, while the green ones indicate it is being used. When you think about it, we have more unused scripts that are unnecessarily loaded during loading time.

With this, webpack provides a feature called “code splitting” to solve this problem. What this does is that you have a choice to load individual scripts “on-demand” or “asynchronously” only when the app needed it. This gives us the performance edge we need to load the app at blazing speeds.

Because of this feature, we don’t need to load any unnecessary scripts that only hampers the performance when the user is not using some particular modules or functions.

For more information about code splitting, visit webpack’s official documentation for it:

Dependency Issues

Another reason why webpack is so popular because it solves the common problem in building javascript apps: Dependency issues.

As mentioned earlier, before the dawn of webpack, we used to arrange our scripts and libraries in the proper order to connect the dependencies correctly:

<script src="moment.min.js"></script>
<script src="typeahead.min.js"></script>
<script src="jquery.min.js"></script>
<script src="otherplugins.min.js"></script> <script src="main.js"></script>

This is fine. But as your list of libraries you depend on gets broader, you will encounter some dependency issues because you haven’t imported the script in proper order. I encounter this issue a lot when my list of libraries I depend to gets broader and broader.

But as I used webpack, this solves all the dependency issues I previously had because you will know ahead of time which dependencies were missing during the build time through the use of ECMAScript Modules (ESM) like so:

//helper.js
export const sqrt = Math.sqrt;
export function square(x) {
    return x * x;
}
export function diag(x, y) {
    return sqrt(square(x) + square(y));
}

//main.js import { square, diag } from 'helper'; console.log(square(11)); // 121 console.log(diag(4, 3)); // 5

These import/export modules will automatically be detected by webpack and will serve as an indicator which javascript modules will it include during the bundle. This effectively takes away the pain of arranging your libraries in proper order just to make everything work.

Despite the problems that it resolves no matter how many, why do we still need to bother ourselves in learning webpack?

Why learn webpack?

To shed some light on this tool, I’ve enumerated the reasons why learning webpack is such a big advantage for you as Front-End Developer. Here are some of the reasons why:

You will understand the modern front-end ecosystem better

As you might have noticed recently, Angular, React, and Vue were already depending on webpack to build boilerplates or ready-made app for developers to start coding their prototype using these major frameworks.

The reason why boilerplates rely on webpack is that it has lots of modules/libraries involved in it like in the case of Angular. Webpack automates the process of downloading/including modules as I mentioned above, so it’s being used often in the frameworks/libraries.

Not only that learning webpack will allow you to gain the benefits mentioned earlier, but you will also understand how front-end boilerplates work under the hood, therefore, understanding the modern front-end ecosystem.

You can speed up development

Development time has also been improved thanks to webpack’s feature called “Hot Module Replacement”. This has been proven to boost productivity because your page doesn’t need to trigger full reload just to reflect your changes on your javascript code.

This not only applies to javascript, but your CSS code can also benefit from this feature by adding css loaders in your webpack config. This makes your development time insanely fast and cutting back the time it takes for the page to fully load while debugging.

You can setup Single-Page Applications better

You can actually see the benefits in using webpack especially if you’re developing Single Page Applications.

When you learn webpack, you will easily be able to setup Single Page Applications. This is especially true when you’re using React since webpack can use transpilers such as Babel alongside it to transpile JSX syntax into readable javascript code.

Total control over build system

You can choose various build systems you’ll need with webpack if there are any such as using babel or traceur via webpack loaders if you need to transpile your ES6+ code in previous versions to make your javascript code compatible with older browsers.

Either way, you always have control over it.

Conclusion

I hope I shed some light on the reasons why webpack is such an awesome tool to add in your day to day Front-End Development work. Although not all the time you’re gonna need this tool in every Front-End Development project you have.

In my personal experience, you will more likely to rely on webpack if you’re using React. But otherwise, you’re fine if the solutions offered by webpack don’t benefit you or doesn’t fit in your use-case.

If you’re struggling in learning webpack, I suggest making use of existing boilerplates first to set up your web app quickly then slowly learn webpack along the way:

Thanks For Visiting, Keep Visiting

☞ Webpack 4 in 2019: The Complete Tutorial For Beginners

☞ Webpack 4: Beyond the Basics

☞ JavaScript Infrastructure: CLI, NPM, Babel 7 and Webpack 4

☞ Getting started with Webpack

☞ Learn ReactJS with Webpack 4, Babel 7, and Material Design

☞ Getting Started With React.js, Babel 7, Webpack 4, and MobX 5

☞ React + Webpack + TypeScript Project Setup


Originally published on blog.bitsrc.io

webpack javascript web-development

Bootstrap 5 Complete Course with Examples

Bootstrap 5 Tutorial - Bootstrap 5 Crash Course for Beginners

Nest.JS Tutorial for Beginners

Hello Vue 3: A First Look at Vue 3 and the Composition API

Building a simple Applications with Vue 3

Deno Crash Course: Explore Deno and Create a full REST API with Deno

How to Build a Real-time Chat App with Deno and WebSockets

Convert HTML to Markdown Online

HTML entity encoder decoder Online

Hire Web Developer

Looking for an attractive & user-friendly web developer? HourlyDeveloper.io, a leading web, and mobile app development company, offers web developers for hire through flexible engagement models. You can **[Hire Web...

Why Web Development is Important for your Business

With the rapid development in technology, the old ways to do business have changed completely. A lot more advanced and developed ways are ...

Important Reasons to Hire a Professional Web Development Company

    You name the business and I will tell you how web development can help you promote your business. If it is a startup or you seeking some...

Hire Dedicated eCommerce Web Developers | Top eCommerce Web Designers

Build your eCommerce project by hiring our expert eCommerce Website developers. Our Dedicated Web Designers develop powerful & robust website in a short span of time.

How long does it take to develop/build an app?

This article covers A-Z about the mobile and web app development process and answers your question on how long does it take to develop/build an app.