Introduction to Webpack – JavaScript Module Loading

What is Webpack

As JavaScript projects go, its increasingly more difficult to organize all your static assets (JavaScript, images, fonts, CSS, etc) in way that makes sense and performs well. You have to balance the number of files being downloaded verses that size of the files being downloaded.

On top of that, the development environment should be rich and productive as possible for developers. Developers should be able to debug code easily without going through a lot of hurdles.

Webpack is a module loading system that takes your assets and splits into manageable modules, and then loads them on demand. From their website, the goal of Webpack is the following:

  • Split the dependency tree into chunks loaded on demand.
  • Keep initial loading time low.
  • Every static module should be able to be a module.
  • Ability to integrate 3rd party libraries as modules.
  • Ability to customize nearly every part of the module bundler.
  • Suited for big projects.

How Webpack Works

Webpack works by taking the designated content and transforming it into a bundle.

webpack1

Webpack can be customize to do many transformations, such as, processing SASS or LESS to CSS, processing ES6/7 JavaScript code to ES5 code, etc.

Getting Started

So to get started, I’ve created an HTML page that will load our Webpack bundle.

I have also create a simple JavaScript file that adds content to the div element. Webpack requires a main entry point to load the modules and then Webpack will load all the other module based on the dependency tree created by the entry module. So in this case, I have created a JavaScript file called entry.js.

So if I load this page on a browser obviously it will be empty, because no files have been transformed. Plus, the file name I created is entry.js and there is no bundle.js so I get a 404 exception as well.

Okay, so let’s install Webpack. If you have node.js install then from the command line install Webpack globally:

Now from the command line, I can run “webpack”:

From the above command, I told Webpack that the entry module is “entry.js” and  to transform it to “bundle.js”.

And now my little application works!

You can take it a step further and add the “-w” parameter to the above Webpack command, and then Webpack will watch for any file changes, and execute the transformation again when any file changes are saved.

webpack2

Okay, what if I want to add a second JavaScript file and load the file dynamically.

If you are familiar with Node.js, you can create modules using the module.exports / require syntax.

So I have adjusted my entry file to read a content.js file.

And in the content.js file a simply export a string.

Now the index page looks like this:

webpack3

One thing you might notice is the bundle has my custom code as well as Webpack specific code. As a matter of fact, at this point the Webpack code is the majority of the code and I have to sift though a lot of it to get to my code.

Webpack offers a setting that will make it easier to debug. So to the above Webpack command, I am going to add the “devtools” and “sourcemap” parameters. So from the command line if I enter the following:

In the development window, Webpack separated the files and now my code is much easier to navigate to.

webpack4

 

Create a Configuration File

Now that I have a working development environment, I don’t want to keep typing everything from the command line every time I want to run Webpack. So instead, I am going to create a Webpack configuration file that will handle these settings.

So the convention for Webpack is, I need to create a file called “webpack.config.js” and place it the root of my project.

So if I take the bare minimum of what I had included in the command line above, my configuration file looks like this.

Now I can simply type “webpack” and I get the same result as before.

Using Webpack Loaders to load CSS

I mentioned above that you can not only dynamically load JavaScript, but you can also load CSS, HTML, images, etc. So with that in mind I want to now add some styles to my program. I can do that by using Webpack Loaders.

I am going to create a stylesheet called main.css and place it at the root of my project.

I am then going to take this CSS file and load it into my entry.js file.

Out of the box, Webpack does not know how to load this file, and I am getting an error trying to load the CSS.

I need to tell Webpack to use the Webpack loaders to get this work, but first I need to load the specific loaders from NPM.

I used the “–save-dev” flag because I need to save these files locally to the project.

I can then add these loaders to the Webpack configuration.

In the above configuration, I added a module section that has an array of loaders. In the loader section, I am loading my first loader. Each loader expects a “test” property that takes a regular expression of the file extension it is expecting. In this case, I am telling Webpack to load all “css” files through this loader.

The second property “loader” is telling Webpack which loader to use. In this case, I am using two loaders. Moving from right to left I am calling the css-loader to process the css and then I am calling the style-loader to render the styles in the HTML. Note: when I specified “css” and “style” on the loader line, Webpack assumes the name css-loader, style-loader respectively as the package name; however, be careful using abbreviations here because if there is a NPM package called “css” installed, it will use that one instead.

Running Webpack now creates the following output with the CSS rendered in the <head> tag.

webpack5

Adding Images and Fonts

Adding images and fonts is pretty straight forward however, there are a couple of parameters that you can play around with to get it working correctly.

Just like adding CSS, we will need to use a loader to get images and fonts loaded on a web page.

Once the package is install, I then need to go to the “webpack.config.js” configuration file and add the loader configuration to the file.

In the loader section, I added the url-loader configuration. I told Webpack that whenever it sees the “png” or “jpg” file then use this loader pipe the file to the webpage. I have also added the limit parameter which tells Webpack to look at the image size and if it is less than roughly 16kb, it will inline the image using base 64 encoded data, and any image that is large than that size Webpack will be created as a separate image, and will be treated as a separate request.

In my code I can now include the image.

Now on the page, notice the image is inline. If it were larger than 16kb then it would be loaded as a separate, external image file.

webpack5

Fonts work pretty much the same way. To load a font file I will use the same url-loader that was used for images. Just need to go into the configuration file and add the font extensions to the test node.

The limit size will work exactly the same for fonts. If the size of the font file is less than the limit specified then it will be rendered inline. If the file is greater than the limit specified than the file will external and referenced via a link.

I added a fonts folder to my project.

fonts

And in the CSS file, I added a fontface to get these fonts on the page.

Finally in my entry.js file I reference the stylesheet and added some content on the page.

Now my web page is using the nice new font.

webpack-fonts

Running a Web Server for Debugging

Webpack also has a development server package that will run your code and “hot swap” modules real-time without reloading the browser. This provides a really fast development experience. Basically, it uses Socket.IO to push the changes to the web server without reloading the browser.

To get this working you need to install this NPM middleware component that provide the functionality.

Once installed, you can get the server running on localhost port 8080 by running “webpack-dev-server” from the command line.

Summary

These are some of the features that Webpack has but there still more I didn’t cover like integrating TypeScript or React’s JSX syntax, compiling Sass or Less to CSS, as well as optimizing the code for production.

Where Webpack is weak at the moment is it does not yet support the ES6 module standard, although it looks like they are addressing this in the next beta version. So for now Webpack seems to be a better fit when using ReactJs verses Angular 2 for module loading.

In future, posts I will look at another module loading framework JSPM and compare it to Webpack.

 

Leave a Reply

Skip to toolbar