Know the role of module bundlers in web development and use the three popular options
BG Image — Unsplash
Module Bundlers — you have probably heard of them a thousand times, but have you ever thought about the need for them or what they do under the hood? Well, to understand what they do, we need to go back in time a little. So, let’s dive in.
Why Do We Need a Module Bundler?
Back in ancient times, all you needed to build a website were HTML, JS, and CSS, and things were much simpler. But when the internet grew exponentially, so did the need for building more complex web pages and apps. Imagine that we are writing a complex website the old school way using just those three. In an ideal case, we would break our JS into different files and include them in the HTML for simplicity. Here’s an example:
But in this case, each file will make separate HTTP requests, which results in five requests to load everything the application needs to work. To avoid this, we could combine them into one single file — which includes everything — as follows:
But this makes the file complex and big to manage manually. And it’s not an easy or straightforward process. For example, two files may have the same functions and variables, and it will be a headache before deployment to work on resolving issues.
Let’s also consider a more modern example of a project that is built with a JS framework like Angular and uses libraries from npm. This causes even more problems while deploying. We would have too many files to keep track of manually while building. If the project has a dependency on a library, that library may have a dependency on multiple other libraries for it to work. This will require the developer to create a complex and large dependency chart while building.
Another problem would be making sure that the JS code that you have written or used by libraries works the same way as intended on all browsers. You may have to write different sets of code for some features to work on legacy browsers.
Even if we overcome all the above problems to merge everything somehow — without any name collisions or scope issues — after spending too many dev hours it may create a huge JS file. This file will increase the load time of our website considerably because everything is bundled together in an unoptimized manner. Needless to say, all these hours spent on building the app could be actually used to develop more features or enhance our web app.
What Is a Module Bundler?
To explain it in simplest terms, a module bundler is a dev tool that fixes all the problems mentioned above to save time and optimize our application for the best performance. One of the most important tasks of a module bundler is to take multiple JS files and combine them to create a single file that contains code we wrote along with required libraries to load in the browser.
Libraries in the project may have multiple dependencies, each of which may have its own dependencies. A bundler creates a dependency graph to keep track of this, and all we have to do is specify the entry point of our project. For example, if App.js is our entry point, the bundler will scan the file for dependencies and then scan each of the resulting dependency files to create the graph. This is very important — without which the browser would not know where to look for any module that we are using in our project.
Example of how module bundler extracts project into static assets.
The bundler also creates a similar process for other files such as CSS by combining all CSS files into one minified file. Assets such as images, fonts, etc., are also mapped and bundled together for the best performance. A bundler also allows you to customize the whole process to suit the various needs of the project.
To summarize, module bundlers are required in modern web projects because:
- It helps developers to manage dependency relationships in the project which will take a lot of time if done manually. Also, it helps load modules in dependency order for you.
- Avoid issues when the browser doesn’t support the module system completely.
- It helps to convert, optimize, and minify our code so that it works
- It helps to optimize and load assets like CSS, images, etc., in their dependency order
Now let’s take a look at some of the most popular Module Bundlers
1. Webpack
Webpack is one of the most popular static module bundlers out there. It works how a module bundler is supposed to work — by building a dependency graph to map every module the project needs. Some of the pros and cons of Webpack includes:
- Generating output based on customizable configurations. We can customize split points to create separate bundles within the same project.
- More control over how to treat different assets encountered.
- Rich and flexible plugin infrastructure.
- Takes time to learn, which includes understanding the complex config file which has a somewhat hard to grasp syntax.
2. RollUp
Rollup is another popular module bundler that uses the new standardized format for code modules included in the ES6 revision of JavaScript, instead of previous idiosyncratic solutions such as CommonJS and AMD. Some of the key points to note while choosing Rollup is:
- Compared to Webpack, Rollup generates a much smaller bundle and there is no module map.
- Rollup has node polyfills for import/export.
- Rollup has support for relative paths in the config.
- All the modules are “flattened” into the bundle and there is no function wrapping of modules. This can be very useful in many cases, but it doesn't always work well when there are circular dependencies.
- It doesn’t support async/await out of the box.
3. Parcel
Parcel is similar to the other two, except it does many of the things more efficiently compared to the other two. For example, dead code elimination or more commonly known as tree shaking. Parcel supports tree shaking for both ES6 and CommonJS modules. Here’s what you get when you select Parcel for building:
- Out of the box support for JS, CSS, HTML, images, etc., without the need for plug-ins.
- It can split output bundles to enable us to load only what is needed initially.
- It pinpoints code frames when there are errors, so we can locate issues faster.
4. Snowpack
Snowpack is my personal favorite in this list and the most recent addition to the bundler world. It has a lot of advantages and some limitations due to the same reason. To add perspective, Webpack released in 2012 — before ES modules even existed. Whereas Snowpack came out in 2019 when modern browsers supported ES Modules and ESNext.
While other bundlers transform your code, Snowpack is more of an install-time tool that doesn’t. For example, Webpack, with its impressive bundling abilities takes time to generate builds each time we make changes to our project. On the other hand, Snowpack takes zero time to do this, because it is not building the project again for each change. Some of the main advantages of using Snowpack are:
- Writing ES Modules directly for the browser that allows an instant preview of code.
- Only rebuilds the specific file that changed instead of rebuilding through all dependencies.
- More efficient caching - if there is a change in code or an npm dependency, a user visiting the site will only need to download the exact files and dependencies that changed. Nothing more, nothing less!
Conclusion
Well, that’s it for now. You may want to try Snowpack if you haven't used it before to learn how easy and efficient it is.
Also, if you’re new to the whole Module Bundler concept, the best way to learn about them would be to try creating a very simple project and experiment building it using different bundlers and different configurations. Compare the results, and then try customizing them to your needs in bigger projects to master the art of bundling to create a faster and more efficient web app.