Introduction

As the size and ambition of a project grows, it will typically require more resources of a wider variety. A bundler is a workflow tool designed to collect and consolidate all of a project’s dependencies including styles, scripts, fonts, images and markup.

For example, a simple project may only require a single CSS file and a single JS file. In this case the need for a bundler is not apparent as we can manage these dependencies quite easily. Compare this to a complex application with many features, package dependencies and many individual scripts or stylesheets. A bundler’s job is to minimise the overhead spent managing reference by moving, transpiling, minifying and building code.

Bundler Concepts

Although there are many competing bundlers, there are commonalities that can be helpful to know when approaching one of these for the first time.

Key Directories

As the primary task of a bundler is to build code from a source it is common to have these represented in a project as folders:

1. /my-project/build
2. /my-project/src

Example 1 is called the output directory or outDir. This is the final destination of our built code and the location of the contents that a user will consume via a web application. This is commonly known as dist, build or public depending on the framework or bundler at hand.

Example 2 is called the input directory or inDir. This is the “raw” code and the only place where code changes should occur in a project. Every time an important code change is made here it must be rebuilt by the bundler before it can be consumed.

Compilation and Transpilation

Every bundler must have the ability to facilitate code compilation or transpilation, particularly for JavaScript. A bundler should allow for a specific input or output version for code assets.

Compilation

Compilation refers to a process of transforming code from a “higher order” to a “lower order” syntax.

For example, SCSS code is compiled into CSS. Likewise, TypeScript is compiled into JavaScript. In both cases a higher order (more complex) syntax is converted into a lower order (less complicated) syntax.

This process continues from the Browser, to your Operating System all the way to your CPU where it is executed in it’s simplest possible form - binary.

Transpilation

Transpilation is a similar concept, however, the goal is to convert from one version of a language to another version. With every major version of each language new syntax and/or features are introduced and/or deprecated. These changes are referred to as breaking changes. Consider this example:

ES5.js

require("example.js");

ES15.js

import "example.js";

Both files use the extension .js and both are ostensibly valid JavaScript - however we cannot run ES15.js in a NodeJS environment. This is because the NodeJS runtime engine is only designed to interpret a particular version of JS.

NPM Scripts

Another feature common to bundlers is how they expose their functionality to their users (us in this case). All major bundlers expose a Command Line Interface (CLI) that can be used to trigger various build related tasks.

Like any other CLI command we can use these in our package.json file to create helpful shortcuts. Consider this fictional example:

{
  "name": "Example",
  "scripts": {
    "build": "bundler build index.html",
    "watch": "bundler build --watch index.html",
    "start": "bundler index.html --open"
  }
}

These three scripts (or tasks) provide similar but subtly different outcomes:

  • build processes the contents of the project once.
  • watch processes the contents of the project every time something changes.
  • start runs the package without processing for faster reloading.

Exactly how these commands behave is different in different tools, however this is a key concept to be aware of as you investigate options and begin using a bundler for the first time.

The Ideal Bundler

When approaching a crucial tool it is useful to understand what qualities would make The Ideal Tool before investigating the options. A good bundler:

  • Uses time and computer resources well
  • Produces a reliable output or a clear error
  • Handles a wide range of file types or pipelines
  • Uses a well tested default configuration
  • Allows for deeper configuration for specialist needs

The Bundler Marketplace

Due to the common design principles mentioned earlier it is unusually straightforward to migrate from one bundler tool to another, in comparison with something like migrating a JS framework. Furthermore, due to the ideals listed above, the benefits of switching to a more effective tool can be considerable. Making this switch could mean less time spent in development, deploying work, finding errors, testing or experimenting. This has lead to a highly competitive marketplace for category of tooling.

At the time of writing rollup is the most popular tool for this purpose, having recently replaced WebPack in this position. esbuild is in third place. Other bundlers that deserve worthy mention include parcel, bower, grunt, gulp, requirejs and browserify.

Vite

For the purposes of this lesson and future lessons, we will be using Vite as our bundler. Vite makes use of both rollup and esbuild for different tasks to produce a highly efficient, stable and well configured tool.

Installing Vite

In your terminal, change directory to the location where you want to create your new Vite project, then run the following command:

npm create vite@3.1.0

You will be prompted to enter a project name and select a template. For this lesson, we will be using the Vanilla JavaScript template. This will create a new directory with the name you entered and install all the dependencies for you.

✔ Project name: … vite-project
✔ Select a framework: › Vanilla
✔ Select a variant: › JavaScript

Scaffolding project in /Users/User/Repos/Noroff/Workflow/vite-project...

Done. Now run:

  cd vite-project
  npm install
  npm run dev

Follow the commands as suggested, replacing project-name with the name that you chose in the first step of the process:

cd vite-project
npm install
npm run dev

This will install and start Vite’s live server, allowing you to view all of your code changes live in the browser.

Additional resources

Tags: