DEV Community

Cover image for Mastering Webpack
Kinanee Samson
Kinanee Samson

Posted on • Updated on

Mastering Webpack

Webpack for Beginners Series

Learn how to use Webpack to bundle your code, manage your assets, automate easy processes and optimize your code.

What is webpack?

Webpack is a module bundler and asset management tool that helps us to bundle our code which is split across different files and directories into one single file that is optimized for production environment. Webpack also helps us to mange assets in our code like stylesheets, fonts, icon, images e.t.c and provides some out of the box features like transpilation of typescript, sass, scss, makrdown, jade into plain vanilla JavaScript, CSS and HTML, webpack also provides cool features like css scoping, a cool development server and many more exciting features.
The importance of webpack as a tool cannot be understated because

  • Webpack can help us to reduce load time by bundling all our code which is split across different files and spit them out into a single file, this way our browser only ever loads a single JavaScript file that it needs to run and this significantly decreases load time.
  • Webpack can help us to convert our code which might be written in a language that is not too familiar with the browser to something that most browsers can understand, this also helps reduce time spent developing because most tasks are already automated.
  • It comes with a cool development sever where we can get a live reload of our work, this server also allows for source mapping so we can see the exact line in the particular file that is causing the error.

First thing first make sure you have nodejs installed on your pc first before we proceed and you can do that tying node -v in your terminal and that will throw of the version of node you have installed on your pc if there is one, else you can head to node js to download and install the latest version of node on your device and once you've done that, let's move to installing webpack. Still inside the command line type mkdir bundle-app && cd bundle-app and hit enter. This creates a folder for us with the name bundle-app and navigates to that directory from the command line. Next thing is to create a package.json file that will keep track of all our dependencies. Enter npm init --y and press enter, this creates a package.json file for us with the default configuration, don't really worry about that for now, just know that it keeps an eye on all the modules that our application depends on to run. Next thing we do now is to install webpack, type npm i webpack webpack-cli --save and hit enter, this installs webpack and webpack-cli and saves them to our dependency. Now we let's get our hands dirty, from the command line inside the bundle-app folder type code . and this opens up visual studio code for you with that directory loaded in or else just open up the folder in any editor of your choice. Your directory structure should look like this.

you can find the complete code base for this lesson on this repository


bundle-app ---------------------package.json
                        |-----package.lock.json

Enter fullscreen mode Exit fullscreen mode

Next thing add an index.html file and add the basic markup for a normal web page, your directory structure should now look like this


bundle-app-----------------------package.json
                |-------------package.lock.json
                |-------------index.html

Enter fullscreen mode Exit fullscreen mode

Open up your index.html file up and link to main.js, your typical index.html file should look like this;

webpack will create main.js for us


<!DOCTYPE html>
<html>
  <head>
    <title>Webpack Tutorial</title>
  </head>
  <body>
  <script src="main.js"></script>      
  </body>
</html>

Enter fullscreen mode Exit fullscreen mode

Great, now create a JavaScript file, let's call that file index.js. Okay create another JavaScript file again and let's call this one hero.js, your new directory structure should look like this;


bundle-app-----------------------package.json
                |-------------package.lock.json
                |-------------index.html
                |-------------index.js
                |-------------hero.js

Enter fullscreen mode Exit fullscreen mode

Open up your hero.js and define a very simple Hero Object using object literal notation, our person object should look like this


var hero = {
    alias: "Incredible Hulk",
    personality: "Bruce Banner",
    suit: "short Jeans",
    strength: "super human strength"
}

module.exports = hero

Enter fullscreen mode Exit fullscreen mode

Next thing open up your index.js and import the hero object we declared in our hero.js, your index.js file should look like this;


const Hero = require('./hero.js')

// create an html list object
var ul = document.createElement('ul')
// create a div tag
var div = document.createElement('div')
// we will loop through hero object and append a new li tag to the div for each property
for (var key in Hero){
    let li = document.createElement('li')
    li.textContent = key + ' - ' + Hero[key]
    ul.appendChild(li)
}
//appendn the list to the div and then the div to the body of the document
div.appendChild(ul)
document.querySelector('body').appendChild(div)

Enter fullscreen mode Exit fullscreen mode

whew! Now let's feel the raw power of webpack by using it from the command line, so if your terminal is still up and you are inside the bundle-app directory, cool, otherwise please open your command line and navigate to the directory bundle-app. Once you've done that, in the command line, type npx webpack ./index.js -o ./ and press enter, it will compile your code down and once that is done you can open up your index.html in your browser and you should see the document in the browser with the the properties of the hero on it.
In this instance we used wepack via the command line this is one of the methods of using webpack, however i will advice you to only use this approach for very simple projects, more complex projects require a different approach which we will be using from now on. If you look at that example, webpack took our code we wrote in two separate files and spit them out into one file which is then loaded by the browser, webpack is able to this efficiently and gracefully because before it spits out the code, it checks the files for their dependencies and builds a dependency graph which it uses to keep track of the dependencies in our application and then it spits out our code and the dependencies into one single file. Webpack can watch your will watch our file and recompile it again once there is a change in our file and it will update the dependency graph to accommodate new dependencies if there are any, use this command to that npx webpack ./index.js -o ./ --watch. In our example above we just did simple plain common is module export and import style, however we can use ES6 style module import system in our code and webpack will bundle down that to a version of JavaScript that most browser will understand, and for this we will now update our directory structure and files, and we will use a webpack.config.js file for our webpack set up hence forth, so create that file and it should sit at the root folder, our directory structure should now look like this;


bundle-app----------------------package.json
                |-------------package.lock.json
                |
                |-------------dist/---------index.html
                |           
                |
                |-------------src/---------index.js
                |                   |------hero.js
                |
                |-------------webpack.config.js

Enter fullscreen mode Exit fullscreen mode

One of the cool features of webpack is that we can write versions of JavaScript that we want in our code like ES6 JavaScript and webpack will be so nice that it will transpile that our code with ES6 syntax to a version of JavaScript that both modern and old browsers alike will be able to understand, open up the hero.js folder and make the following adjustment to it.


//hero.js
let Hero = {
    alias: "Incredible Hulk",
    personality: "Bruce Banner",
    suit: "Short Raggerd Jeans",
    strength: "super human strength"
}
export default Hero

Enter fullscreen mode Exit fullscreen mode

We now use ES6 style for declaring our hero object, next thing you head over to the index.js file and then we also use ES6 import statement to import our Hero object

//index.js
import Hero from './hero.js' //only change this line

// create an html list object
const ul = document.createElement('ul')
// create a div tag
const div = document.createElement('div')
// we will loop through hero object and append a new li tag to the div for each property
for(let key in Hero){
    let li = document.createElement('li')
    li.textContent = Hero[key]
    ul.appendChild(li)
}
//appendn the list to the div and then the div to the body of the document
div.appendChild(ul)
document.querySelector('body').appendChild(div)
Enter fullscreen mode Exit fullscreen mode

We need to edit our html code to link up to the bundle.js file that will be generated for us by webpack, so your html file should look like this;


<!DOCTYPE html>
<html>
  <head>
    <title>Webpack Tutorial</title>
  </head>
  <body>
  <script src="bundle.js"></script>      
  </body>
</html>


Enter fullscreen mode Exit fullscreen mode

Fine, we've got everything set and inplace, next thing we will do is to open up our webpack.config.js and here we define some configurations to webpack about how we want webpack to bundle our code.

//webpack.config.js
const path = require('path') //we require the path core module to help us resolve a directory

//this will hold our configuration object
module.exports = {
    //we first specify an entry script to webpack
    entry: './src/index.js',
    //next is our output file and directory
    output: {
        path: path.resolve(__dirname, 'dist'),
        filename: 'bundle.js'
    }
}
Enter fullscreen mode Exit fullscreen mode

That simple configuration object requires two things;

  • The file that we want to process which is specified in the entry variable, it contains the starting point to our code, normally this entry script should import all other scripts that our app depends on.
  • Where our processed file should be put and for that we import the path module which is a core node.js module and this will help us resolve the directory we want to place our file inside. Our output is specified via an output object that holds two keys, the path we want the file to sit in, and then the filename, which is what we want to name the file.
  • Webpack created that bundle.js for us even if it did not exist, much like it did when we first used it via the command line, the benefit of this command line is that we can easily pass information to webpack about how it should handle the things we import into our code and that helps with assets and style management

We use the resolve method on the path core module to get the directory with a name of dist, which we created earlier, remeber? next thing is the what we want the file to be named, and in this instance i'm just calling it bundle.js, ring any bells? To process our file simply open up your terminal inside the root folder that is bunde-app and then from the terminal simply type npx webpack --config webpack.config.js and tada! If everything goes according to plan which it should do except there's a typo somewhere you should see information concerning your file and information and the processed file and then a compiled successfully message in your console.

This is this for this article in this series, we will be looking at how we can convert typescript code into plain vanilla JavaScript with webpack in our next article so do stay tuned, don't forget to drop your comments in the comment section and do have a nice day.

Top comments (12)

Collapse
 
joshcheek profile image
Josh Cheek

For displaying directory structures, check out tree:

$ tree bundle-app
bundle-app/
├── dist
│   └── index.html
├── package.json
├── package.lock.json
├── src
│   ├── hero.js
│   └── index.js
└── webpack.config.js

2 directories, 6 files
Enter fullscreen mode Exit fullscreen mode

If you're on a mac, brew install tree

Collapse
 
kalashin1 profile image
Kinanee Samson

Okay, where can I get tree from??

Collapse
 
joshcheek profile image
Josh Cheek

If you're on a mac: brew install tree

Collapse
 
tiiunder profile image
Felix G

Hopefully this is the last packaging tool and we all start using this one. Who remembers bower? :D

Collapse
 
abirana profile image
Abi Rana

I was just checking your process and one of your initial command doesn't seems to be working
npx webpack ./index.js -o ./

it's throwing unknown command error

Collapse
 
agredalex profile image
Alex Ágreda

npx webpack --entry ./index.js -o ./ should work

Collapse
 
kalashin1 profile image
Kinanee Samson • Edited

Makes sure you install webpack first.. It could be as a result of webpack not being installed on your machine. Otherwise use the confirmation file.

Collapse
 
abirana profile image
Abi Rana • Edited

I've installed the webpack, my issue seems to be different. Webpack-cli is not detecting webpack as a command. Can you help me with this?

Check this screenshot here dev-to-uploads.s3.amazonaws.com/i/...

Thread Thread
 
kalashin1 profile image
Kinanee Samson

okay, try installing webpack and the webpack-cli globally, that should do the trick

Collapse
 
fagnerbrack profile image
Fagner Brack • Edited

this way our browser only ever loads a single JavaScript file that it needs to run and this significantly decreases load time

How does loading a single javascript file decreases load time? I assume a single javascript file would increase load time as the file will be bigger?

I'm confused...

Collapse
 
shwetabh1 profile image
Shwetabh Shekhar

I was just about to dive into webpack. This helped. Thanks for sharing!

Collapse
 
kalashin1 profile image
Kinanee Samson

I'm glad that you found it useful, you're welcome