Skip to content

Webpack Tutorial: The Basics

“The mechanic that wishes to perfect his work must first sharpen his tools.” – Confucius

A few weeks back, I was chatting with some of my coworkers about how quickly a developer’s toolset changes. It wasn’t that long ago, when we were building web applications where the pages were rendered completely on the server. The rendered HTML was then sent to the client with a nice helping of view state to increase the page size. Times have changed, and more developers adopted client-side scripting. Our jobs got progressively easier with the emergence of JavaScript frameworks like AngularJS and React for client-side development and the evolution from ASMX services, to WCF services, to RESTful APIs on the server-side.

This progress, however, does come at a cost as it requires some knowledge of the tools that make dealing with these frameworks possible. The conversation I was involved in a couple of weeks ago was centered on webpack and how it’s used and configured in our current projects. Webpack comes pre-configured out of the box on a lot of the newer default Visual Studio project templates. You don’t need to know anything about webpack to use it, Visual Studio conveniently hides most of that from you. That is, of course, until you need to update a package which requires a newer version of webpack. Which breaks webpack. Which has happened to all of us at least once or twice.

I put together a lunch time training session for my coworkers (and really, for myself) to figure out what webpack is and how to use it. What follows is a short introduction and a set of demos I did with my coworkers that ran us through the very basics of webpack to a somewhat more complex example that mirrors a good part of the functionality you get out of the box in a Visual Studio project template.

What is webpack?

“Webpack is an open-source JavaScript module bundler.” – Wikipedia

Webpack can be used for the following:

  • Automation (task runner)
  • Minimize CSS (bundling)
  • Minimize JS (includes transpilation and bundling)
  • Bundle images (and other assets)
  • Watch a project for changes and re-bundle

Similar Tools (there are many, many more)

I won’t bother going into too much detail, but there are many other tools that do similar things. A few of the more well-known ones are listed below:

Grunt – the JavaScript Task Runner

Gulp

Parcel JS

What do I need?

  • js
  • yarn
  • Text editor (I recommend Visual Studio Code)
  • js (we’ll take care of this in the demo code)
  • Patience (you’re on your own for this one)

node.js

What is node.js?

  • js is an open source server environment
  • js is free
  • js runs on various platforms (Windows, Linux, Unix, Mac OS X, etc.)
  • js uses JavaScript on the server

Yarn

What is Yarn?

  • Yarn is a package manager for the JavaScript programming language
  • created by Facebook
  • new kid on the block (relatively speaking, of course)
  • Yarn caches every package it downloads so it never needs to download it again
  • more secure (verifying packages)
  • originally the only package manager that included a lock file

Demo 1 – Use Yarn to install and setup basic webpack bundling

In this demo, we’re going to build a simple webpage that references a bundled JavaScript file built from two different JavaScript files. This will give you an extremely basic idea of what webpack offers.

Open up a PowerShell window, create a new folder for the demo, and navigate to that folder:

  • mkdir webpack-demo
  • cd webpack-demo
  mkdir webpack-demo
  cd webpack-demo

You’ll notice that it created a new file called “package.json”. This file keeps information about your project. It should look something like this:

Webpack demo package - package.json

Now we have to add webpack to our project. Type in the following command:

  • yarn add webpack webpack-cli -D
yarn add webpack webpack-cli -D

Yarn is now adding two packages to our project: webpack and webpack-cli. We need webpack-cli so that we can run webpack from the command line.

Now let’s open this folder in windows explorer:

You’ll notice that there is now a “node_modules” folder and a yarn.lock file added to our project.

Let’s head back over to Visual Studio code. If you look at the package.json file, you’ll notice that we have a new section called “devDependencies” added to our file. It lists both webpack and webpack-cli. The “-D” in our previous Yarn command told Yarn to install these dependencies as development only.

Webpack Demo 1 - devDependencies

Now, let’s have some fun! Inside Visual Studio code, create a new file called “main.js”

You can put whatever JavaScript you want in here, but I like to keep it simple. This was the content in my main.js file:

  1. console.log("Hello from main.js!");
console.log("Hello from main.js!");

We’ll create another file called “main2.js”. Here is the content in my main2.js file:

  1. console.log("Hello from main2.js The second file!");
console.log("Hello from main2.js The second file!");

And finally, we’ll create a third file called “index.html”. I like to use the Emmet abbreviation feature in Visual Studio code, so as I type “html” I’m able to click on “html:5” and have an HTML5 compliant template auto generated for me.

Webpack Demo 1 - HTML5 compliant

You can keep all of the defaults, or you can change the title, it is totally up to you.

Add a script tag to the head of the HTML document and set the source as “bundle.js”.  (don’t worry that it doesn’t exist yet)

  1. <script src="bundle.js"></script>
<script src="bundle.js"></script>

Here is my complete index.html file:

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6. <meta http-equiv="X-UA-Compatible" content="ie=edge">
  7. <title>Webpack demo!</title>
  8. <script src="bundle.js"></script>
  9. </head>
  10. <body>
  11. </body>
  12. </html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Webpack demo!</title>
<script src="bundle.js"></script>
</head>
<body>
</body>
</html>

Save all three files and head back to the command line.

Now we’re going to use webpack to generate that file “bundle.js” for us. Type in the following command:

  • node .\node_modules\webpack\bin\webpack.js main.js main2.js --output bundle.js
node .\node_modules\webpack\bin\webpack.js main.js main2.js --output bundle.js

Here is the output:

Webpack Demo 1 - output

We are essentially telling webpack (which we are running via node.js) to take “main.js” and “main2.js” and bundle them together and output them into one file called “bundle.js”. You can ignore the “Warning in configuration” for now; in a later demo I will show you how to get rid of that message.

If you look at the directory now, you should see a file called “bundle.js”.

Webpack Demo 1 - Directory bundle.js

Open the index.html file in Chrome and have a look at the developer tools. You should see your console.log messages!

Webpack Demo 1 - index.html file

Demo 2 – Use webpack config for more automated bundling

In this second demo, we’re going to build a simple webpage that (again) references a bundled JavaScript file, but this time we’ll be using a configuration file to tell webpack what to do.

Open up a PowerShell window, create a new folder for the demo, and navigate to that folder:

  • mkdir webpack-demo
  • cd webpack-demo
mkdir webpack-demo
cd webpack-demo

As we did in the last demo, use Yarn to create a basic project in this directory and then add the webpack and webpack CLI packages:

  • yarn -y init
  • yarn add webpack webpack-cli -D
yarn -y init
yarn add webpack webpack-cli -D

Let’s open the current folder in Visual Studio code (or whatever editor you prefer) by typing:

  • code .
code .

Create a new folder called “js” and add three new files called “file1.js”, “file2.js”, and “index.js” inside the newly created “js” folder:

Webpack Demo 2: JavaScript Folder

Type in the following text for file1.js:

  1. console.log("initializing file1.js");
  2. export default {
  3. hello: function() {
  4. console.log("Hello from file1.js");
  5. }
  6. }
console.log("initializing file1.js");
export default {
  hello: function() {
    console.log("Hello from file1.js");
  }
}

Type in the following text for file2.js:

  1. console.log("initializing file2.js");
  2. export default {
  3. hello: function() {
  4. console.log("Hello from file2.js");
  5. }
  6. }
console.log("initializing file2.js");
export default {
  hello: function() {
    console.log("Hello from file2.js");
  }
} 

Type in the following text for index.js:

  1. console.log("Hello from index.js!");
  2. import file1 from './file1';
  3. import file2 from './file2';
  4. file1.hello();
  5. file2.hello();
console.log("Hello from index.js!");
import file1 from './file1';
import file2 from './file2';
file1.hello();
file2.hello();

At this point, we have 3 JavaScript files -> index.js is simply importing file1.js and file2.js and calling their respective “hello()” methods.
We still need to create our index.html file and we’ll do that in the same fashion as we did in the previous demo. If you’re using Visual Studio code, simply start typing “html” and let the Emmet abbreviation feature finish the HTML5 compliant template.

Webpack Demo 2 Emmet Abbreviation

Add a script tag to the section (don’t worry that the source “dist/bundle.js” doesn’t exist yet, we’ll fix that with the magic of webpack!):

  1. <script src="dist/bundle.js"></script>
<script src="dist/bundle.js"></script>

Here is my complete index.html file:

  1. <script src="dist/bundle.js"></script>
    <script src="dist/bundle.js"></script>

Now add a file called “webpack.config.js” to the root of our project. Save it with the following text:

  1. const path = require('path');
  2.  
  3. module.exports = {
  4. entry: './js/index.js',
  5. output: {
  6. path: path.resolve(__dirname, 'dist'),
  7. filename: 'bundle.js'
  8. }
  9. };
const path = require('path');
 
module.exports = {
  entry: './js/index.js',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'bundle.js'
  }
}; 

Just to explain what we’ve typed into the webpack.config.js file:
“entry”: This is the initial file that webpack will start processing. Any references (imports) to other files will automatically be parsed and included in bundling.
“output”: This tells webpack what filename to use for the bundle (in this case we actually called it “bundle.js”) and it also tells webpack which path to use to put the output (we are going to store our bundled file in a “dist” folder).

At this point, we can go back to our PowerShell window and type in the following command:

  • node .\node_modules\webpack\bin\webpack.js --config .\webpack.config.js
node .\node_modules\webpack\bin\webpack.js --config .\webpack.config.js

This command is similar to the command we used in Demo 1, except we’ve simplified things considerably by specifying a configuration file for webpack to use.

Here is the output:

Webpack Demo 2 - PowerShell Output Bundle

There is one additional shortcut we can add at this time – instead of having to type out the whole “node .\node_modules…” command, we can add a section to our package.json that defines a shortcut for us. Open the package.json file in Visual Studio code and add the following “scripts” section after the “devDependencies” section:

  1. "scripts": {
  2. "webpack-it": "node ./node_modules/webpack/bin/webpack.js --config ./webpack.config.js"
  3. }
  "scripts": {
    "webpack-it": "node ./node_modules/webpack/bin/webpack.js --config ./webpack.config.js"
  }

Your package.json file should look something like this:

Webpack Demo 2 - Json package

Once you have saved the package.json file, go back to PowerShell and type in:

  • yarn webpack-it
yarn webpack-it

You’ll see that the output is almost identical to the output we saw when we typed in the full “node .\node_modules…” command. I gave my command a fun name of “webpack-it”, but you can use whatever name you want. The “scripts” area is a great place to store your custom commands for running unit tests, packaging of vendor files, etc.
Now let’s test and make sure our bundled JavaScript file works! Open index.html in a browser and you should see the following in the developer tools console:

Webpack demo 2 - index.html file

Demo 3 – Configure webpack to watch for changes (and get rid of that “mode” warning in the output)!

(This demo builds on the files created in the previous demo) 

You may have noticed that when you make changes to either of the JavaScript files (“file1.js” or “file2.js”) you have to retype the command “yarn webpack-it” in order to re-bundle the files.

Add the following line to the “module.exports” section of your webpack.config.js file:

  1. watch: true,
watch: true,

Your webpack.config.js file should look like this:

Webpack Demo 3 - Webpack Config

Now when you type in “yarn webpack-it” in your PowerShell window, you’ll notice the line “webpack is watching the files…”. This means that any change to “index.js”, “file1.js”, or “file2.js” will result in a re-bundling of the output file “bundle.js”.

Webpack Demo 3 - PowerShell Output bundle

Try it out for yourself! Refresh your browser window to make sure everything is still working as expected (you should see the same output in the debugger window as we saw in the previous demo). Now make a change to “file1.js”, I chose to change the “console.log” in my hello() method to say:

  1. console.log("Hello from file1 * Updated * .js");
console.log("Hello from file1 * Updated * .js");

You can verify that webpack re-bundled your JavaScript by refreshing your browser window and checking the output in the Developer Console:

Webpack Demo 3 - index.html file

The final part of this demo involves removing the “WARNING in configuration” message you’ve been seeing during the webpack bundling operations. Add the following text to the webpack.config.js file:

  1. mode: “production”,
mode: “production”,

Your final webpack.config.js file should now look like this:

Webpack Demo 3 - Final Webpack Config

Go back to the PowerShell command prompt one last time and type in “yarn webpack-it” and look at the output. You should notice that the “WARNING in configuration” message is now gone.

The value “production” simply tells webpack that you want to bundle the JavaScript together and minimize the bundled file. In a development environment, you can specify “development” instead of “production” and webpack will still bundle your files together, but it will bundle them un-minimized. I’ll leave it up to you to try that out and look at the output “bundle.js” file.
I hope this article was useful in seeing how powerful webpack can be by breaking it down into some small simple demos. From here, I would suggest trying to add some CSS (or SASS) files and adding a css-loader to your project and configuring webpack to process those files too. I found that by doing it in this manner, I was able to start troubleshooting problems that both I and other developers were having with our Visual Studio “out of the box” template build solutions. Something that seemed quite complicated at first, is now less confusing and significantly less daunting.