Getting Started With Webpack

Introduction

Webpack

Webpack is module bundler that takes your modules with dependencies and generates static assets representing those modules. If we are working with a website, then it is possible that it contains the large numbers of JS and CSS files. For a general scenario, if our application contains 10 JavaScript files and 3 CSS files, then 13 requests will be sent to the server for all these files, which makes the process slow.

The best practice is to make the bundle of all these files and provide a single package for JS and a single package for CSS; that means now only 2 requests will be sent to the Server to load all the required resources. This, definitely, reduces the time and increases the performance of our application.

Webpack

Webpack not only bundles our resources like JS and CSS but it also transforms them and allows us to write our code in ES6 (ECMA Script 6). In current time, all the technologies like Angular2, React etc. use ES6 for the development. But every browser doesn’t necessarily understand the ES6, so Webpack compiles the code into ES5 such that the browser can understand the code.
 
Webpack is a build tool but it does more than that. It manages our code and handles the dependencies. Let’s start with a simple example and understand how Webpack can be helpful to increase the performance and manage the application.

I have created a sample project, in which, I have one HTML, two CSS, and three JS files. Below is the code of each file.

Webpack

Index.html 

  1. <html>  
  2.     <head>  
  3.          
  4.         <link rel="stylesheet" type="text/css" href="src/css/style1.css">  
  5.         <link rel="stylesheet" type="text/css" href="src/css/style2.css">  
  6.     </head>  
  7.     <body>  
  8.         <div id="div1">              
  9.        <button class="button" id="btnToggle">Toggle Div</button>  
  10.        <br/>  
  11.        <div id="divred">  
  12.            This property is a shorthand property for border-bottom-width, border-bottom-style, and border-bottom-color.  
  13.        </div>  
  14.        <div id="divblue">  
  15.            This property is a shorthand property for border-bottom-width, border-bottom-style, and border-bottom-color.  
  16.        </div>  
  17.        </div>  
  18.            
  19.    
  20.         <script src="src/js/script1.js"  ></script>        
  21.        <script src="src/js/script2.js" ></script>   
  22.            
  23.     </body>  
  24. </html>   

Style1.css 

  1. .button {  
  2.     background-color: #4CAF50;  
  3.     border: none;  
  4.     color: white;  
  5.     padding: 15px 32px;  
  6.     text-align: center;  
  7.     text-decoration: none;  
  8.     display: inline-block;  
  9.     font-size: 16px;  
  10.     margin: 4px 2px;  
  11.     cursor: pointer;  
  12. }  
  13.  
  14. #div1  
  15. {  
  16.     margin-left: 450px;  
  17.     margin-top: 30px;  
  18.     margin-right: 150px  
  19. }   

Style2.css 

  1. #divred{  
  2.     border-bottom: 30px solid red;  
  3.     background-color: lightgrey;  
  4.     min-height: 150px;  
  5. }  
  6.  
  7. #divblue{  
  8.     border-bottom: 30px solid blue;  
  9.     background-color: lightgrey;  
  10.     min-height: 150px;  
  11. }   

script1.js 

  1. var divredId=document.getElementById("divred");  
  2. var divblueId=document.getElementById("divblue");  
  3. var btnToggle=document.getElementById("btnToggle");   

script2.js 

  1. var div='divred';  
  2. divredId.style.display='none';  
  3. btnToggle.addEventListener('click',toggleDiv);  
  4. function toggleDiv(){  
  5.   
  6. if(div=='divblue')  
  7. {  
  8.     div='divred';  
  9.     divblueId.style.display='block';  
  10.     divredId.style.display='none';  
  11. }  
  12. else if(div=='divred')  
  13. {  
  14.     div='divblue';  
  15.     divblueId.style.display='none';  
  16.     divredId.style.display='block';  
  17. }  
  18.   
  19. }   

After creating all the files, when we run the index.html file, the following result is achieved.

Webpack

When we click on the “Toggle Div” button, it will toggle the red and blue div.


Webpack
When we run this app, we will find that everything is going very well - the toggle button shows and hides the red and blue div and there is no issue in code. Let’s focus on some other aspects of this simple demo application.

Number of the Request for files

Go to the "Inspect Element" and click on “Network” tab of your browser. Here, I am using Google Chrome; if you are using another browser, then there are chances that the “Network” tab is called by another name.

Webpack

You can see that a total of five requests are generated - one for “index.html” page, two requests each for CSS and JS files. For such a small project, the numbers of requests is not such a big issue but if we are working on a large project that contains 100s of JavaScript files and 100s of StyleSheets, it will become a critical issue, and degrade the performance of application.

Order of the files

Webpack

In index.html page, the following is the order of JavaScript files. Order of files plays a very important role. If we change this order of included files, the performance of the application may vary. Let’s check by the changing the order of both the files. Place the “script2.js” file before “script1.js” and refresh the browser.

Webpack

When you refresh the browser, you will get the above error because after changing the order of the script files, now “divredId” and “divblueId” are not defined in “script2.js” files. So if you are creating a large application, it becomes very hard to manage the order of files in application. To overcome all these issues, we can use Webpack and maintain the dependency of files in order to increase the performance of application.

To add a Webpack in application, the easiest way is to use "npm (Node Package Manager)”. So, npm must be installed in your system while developing the application. If npm is not installed in your system, go to the official website of Node.js and install “Node.js”.

Webpack

After installing the “npm”, now open the command line terminal in your application and run the “npm init” command. The “npm init” command is used to tell the npm that this project will be handled by the npm.

Webpack

When you run the command, it will ask several questions, you can press enter on each question. After completing this process, you will find that “package.json” file has been added in your project. This file contains the information about all the packages that are added into application, and is a start point for the application.

Add Webpack Packages

Now, run the “npm install webpack --save-dev” command in your terminal. This command installs the Webpack dependency in our project and creates “node_modules” folder that contains the all the required modules.

Add build command and make the dependencies

Now, go to the packages.json file and add the "build":"webpack src/js/script1.js dist/bundle.js" line in script section.

Webpack

The “build” command runs the Webpack and tells that entry point for the application is “src/js/script2.js” and output of these files, the bundle will be stored in “dist/bundle.js” file. Now, in the “script1.js” file, replace the code with the following one. 

  1. export var divredId=document.getElementById("divred");  
  2. export var divblueId=document.getElementById("divblue");  
  3. export var btnToggle=document.getElementById("btnToggle");  

Webpack
In the above code, we have added the “Export” keyword before both variables. Export command provides the functionality to access the variable or code in other files, outside current file. Now, go to the “script2.js” file and import all three variables.

Webpack
Run Build command

After making all the required changes, now run “npm run build” command. This command will create a bundle for us.

Webpack

After successfully running this command, you will find that a “bundle.js” file has been added in dist folder. This file contains all the required code for us.

Webpack

Now, we have our “bundle.js” file so now, we don’t have to add the “script1.js” and “Script2.js” files in index.html page. Let's remove them both and add the “dist/bundle.js” file.

Webpack

After adding the “bundle.js” file, now refresh your browser. If everything is working till now that means we have done a successful configuration. If you “inspect element” now, you will find that “build.js” file is loaded in our application instead of “script1.js" and "script2.js”.

Webpack

Minified the code

Again, go to the “package.json” file and add "build:p":"webpack src/js/script2.js dist/bundle.js -p" script command in your file.

Webpack

This command runs the Webpack in production mode and minifies all the files. Now, we need to run this command in our command line terminal. Open the terminal and run “npm run build:p” command.

Webpack

Now, go to “dist” folder and you will find that our “bundle.js” file has been minified.

Webpack

Create Webpack Server

If you noticed, our application is not running on HTTP protocol. Instead, this is running on “file” protocol and all the files are loaded from the physical location of our system.

Webpack

So, if we are working with an application, it must be running on an HTTP Server. So, let's create a WebServer using Webpack.

Now, run the “npm install webpack-dev-server --save” command in your terminal.

Webpack

This command adds the required files for “webpack-server”. Actually, Webpack dev server uses “webpack-dev-middleware” under the hood and develops the Sever with live reloading functionality.

After installing the webpack-dev-server modules, now go to the “package.json” file and replace the “build” command with the following code.

"build": "webpack-dev-server --entry ./src/js/script2.js --output-filename ./dist/bundle.js"

Webpack

In build command, we have configured the webpack-dev-sever . The "--entry" option provides the entry point for the Webpack and "–output" option tells the Webpack where the output will store. We have configured the webpack-dev-server; now, run the “npm run build” command.

Webpack

You can see that our application is build successfully and now, it is running on “8080” port. Let's open the “localhost:8080” URL in our browser.

Webpack

You can see that our application is running of “HTTP” sever and all the files are loaded from the Server. One important thing to notice here is that now, we don’t need our “dist” folder. So, let's delete this folder from the project because now, Webpack creates the bundle.js file in memory and doesn’t store it to any physical path.

Add Configuration File

Until now, we have written all the build commands into “package.json” file but we are creating an application so we need to define multiple entry points. Also, we need to configure the loaders and plugins. The best way to perform all the tasks is to create a separate configuration file where we can put all our configuration code.

So, add a file in root directory of the project, name it as “webpack.config.json”, and paste the following code into this file.

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

In the above code, we have defined the entry point for the application and also defined the output path where all the assets of our application will store. Output is JavaScrip object that defines the path property. The publicPath property defines the location where Webpack looks for the created files.

After making the configuration file, now don't have to define the entry and output path in “package.json”. So, let's remove these files from “package.json” file.

Webpack

After making all these changes, now rebuild your project using ”npm run build” command and refresh the browser; and you will find that everything is working right.

Use Loaders

Loaders exactly transform our code into another form. Loaders take the resource and transform it into new format. If we are using JSX (JavaScript Syntax XML) or TypeScript, then browser doesn’t understand these codes.

It only knows JavaScript, so at this stage, we need loaders. We need to transform the code into another format that is browser friendly. In our “index.html” page, we have added “stylesheet” references. Now, we want that these files should be loaded by the Webpack. So, remove these files from index.html page and import these files into “scriptjs” file as below.
  1. import {divblueId,divredId,btnToggle} from './script1';  
  2. import '../css/style1.css';  
  3. import '../css/style2.css';  
  4. var div='divred';  
  5. divredId.style.display='none';  
  6.   
  7. btnToggle.addEventListener('click',toggleDiv);  
  8.   
  9. function toggleDiv(){  
  10.   
  11. if(div=='divblue')  
  12. {  
  13.     div='divred';  
  14.     divblueId.style.display='block';  
  15.     divredId.style.display='none';  
  16. }  
  17. else if(div=='divred')  
  18. {  
  19.     div='divblue';  
  20.     divblueId.style.display='none';  
  21.     divredId.style.display='block';  
  22. }  
  23.   
  24. }  .

When you save the changes, you will get the following error.

Webpack

We get this error because we don’t have a proper loader for the “css” files. So, let’s add the loader and configure. Run the following command in your terminal to add the style and css loader into our project.

“npm install --save-dev css-loader style-loader”

Here, we have added two loaders “css-loader” load transforms the “css” files but doesn’t add these files into our JavaScript code. So, we need another loader that can add these “styles” into our JavaScript files.

For this, we add the “style-loader”.  Now, go to the “webpack.config.js” file and add required rules for loaders. Now, replace the code of “webpack.config.js” file with the following code. 
  1. var path=require('path');  
  2. module.exports={  
  3.     entry:'./src/js/script2.js',  
  4.     output:{  
  5.         path:path.resolve(__dirname,'dist'),  
  6.         filename:'bundle.js',  
  7.         publicPath:'/dist'  
  8.     },  
  9.      module: {  
  10.         loaders: [  
  11.             { test: /\.css$/,  
  12.                 loader: [  
  13.                'style-loader',  
  14.                'css-loader'  
  15.                 ]  
  16.             },  
  17.             ]  
  18.     }  
  19. }  

Webpack

In the above code, we created a loader for the “.css” type files and defined the two loaders for this. The point to notice is that Webpack reads the loader in reverse direction means from last to first. So, the order of the loaders is important. If you place the “css-loader” before the “style-loader”, you will get errors.

 Now, restart your “Webpack” sever and refresh the pages. When you refresh the page, you will find that everything is working properly. Now, go to the “bundle.js” file in “Network” tab. You will find that “bundle.js” file also contains the "CSS” code that we have written in our “style1.css” and “style2.css” file.

Webpack

Conclusion

In this article, we took a brief introduction of Webpack and created a Webpack Server, added the loaders, defined entry and output paths and all the basic steps to setup an application using Webpack. In webpack configuration, we can create multiple entry points, add plug-ins.Plugins provide more configuration functionalities.

If you have any questions, then write in the comment section.