Webpack — Step by step installation
A complete practical guide to webpack’s capabilities, our objective is to build a module bundler similar to create-react-app.
Nowadays tools like create-react-app or Vue CLI force us to use their default configuration for our web development workflow. Even then, understanding how things work under the hood would be beneficial. That helps us to modify its configuration that suits our needs.
In this guide, we would try to build a module bundler similar to create-react-app using a simple Javascript project.
Before that, you need to understand a few terms and concepts that make yourself comfortable towards the topic.
Terms
Modules
In simple words, modules are a partition of a single javascript program into small bits of subprograms based on their functionalities, related to each other with their references (export and import statements).
Webpack
Webpack is a static module bundler, treats all files/assets as modules, combines all these different sources and module types in a way that’s possible to import everything in your JavaScript code, and finally produce a shippable output.
In this way, webpack traverses all modules to build the graph and uses it to generate a single bundle (or several bundles)- single JavaScript file containing the code from all modules combined in the appropriate order. Statically means that, when webpack builds its dependency graph, it doesn’t execute the source code but stitches modules and their dependencies together into a bundle. This can then be included in your HTML files.
Concepts
Entry point
An entry point for a webpack is a javascript file, where webpack initiates building its internal dependency graph by collecting its dependencies (modules and libraries) until no dependency is left.
By default, the entry property is set to ./src/index.js, but we can modify its default setting in the webpack configuration file.
Output
Output instructs webpack where to emit the resultant bundle(s) generated.
By default, the module generated would be ./dist/main.js and for other generated files — such as images. We can specify different values in the configuration file depending upon our needs.
Loaders
By default, webpack only understands JavaScript and JSON files. Loaders are third party extensions that help webpack deal with various file extensions other than javascript files.
Loaders transform non-JavaScript modules, allowing us to pre-process those files before adding them to the dependency graph.
Plugins
Plugins are third-party extensions that help with asset management, bundle minimization and optimization, and so on.
Mode
Webpack has three modes of operations: development, production or none.
By default, the value of mode would be production. The none mode specifies that there won’t be any default optimization options. The main difference between them is that production mode automatically applies minification and other optimizations to your JavaScript code.
Getting started with Webpack
It is going to be a complete practical guide, with a simple javascript program (Calculator), for better coordination kindly import our Github Project.The project has no pre-webpack configuration.
By Following this practical guide, you are going to set up a module bundler similar to create-react-app with me.
Divided this course into categories
- Project Context
- Installing and Running Webpack and Webpack-CLI
- Configuring Webpack
- Modularization — Imports, Exports
- CSS/SASS Loaders
- Cache Busting & Plugins
- Extract CSS
- Html-loader/File- loader/Clean-Webpack plugin
- Splitting Development and Production environment
Project Context
Our Project Simple Calculator built with basic mathematical operations of two numerical inputs with few validations.The computed results computed will be displayed under the result section.
Our Project built with bootstrap, having an external css file, svg icon and app.js is the entry point of our project.
By executing index.html, you can see the following app displayed in your browser.
Installing and Running Webpack and Webpack-CLI
To start with webpack, move to initialize an NPM in our project directory:
To install webpack and webpack-cli packages.
To run webpack from an NPM project, configure a start script in our package.json:
When you start running the script npm start under the project directory, you can see that bundle generation is getting failed. This failure occurs due to an ERROR in the Entry module not found: Can’t resolve ‘./src’ under your project directory.Entry module error occured when Webpack is unable to find index.js under our src directory.
By default, webpack will look ./src/index.js inside the project directory to initiate the bundling process.As our directory does not contain any index.js file it throws an error. For our project, app.js is an entry module.To modify our default settings,we need to configure our Webpack.
Configuring Webpack
To override our default configuration, we need to create webpack.config.json under the project directory.
In webpack.config.json, entry property represents the module starting module of bundle generation.The path specified to app.js in your project directory.
The output property specifies the path where the bundle needs to be generated after compilation. The default configuration of value would be ./dist/main.js.
To configure in webpack, you need to modify the start script in package.json.
Once webpack configuration completed, execute start script using npm start. You can see Output Bundle will be generated under the src directory.
To evaluate our bundle generated, we need to remove existing scripts and add your main.js bundle into your index.html.
On Execution,you can find the result is not generated.
Modularization — Imports, Exports
You can see all javascript files have compiled into a bundle and imported in our index.html. But still, you can find calculations are not happening in our app.This is due to the absence of communication between files.
We need to modularize our files, to establish connections between our files (using import and export statements). As it is out of scope, added to the GitHub link here modularized code of the project.
After modularization, on executing index.html you will find the app working with proper functionalities.
CSS/SASS Loaders
To work with CSS in webpack we need to install at least two loaders.
Loaders help webpack to understand how to deal with files other than js.
To test CSS in webpack create a simple stylesheet in src/main.css :
Unpacking stylesheet from our index.html file
Finally, load the CSS in src/app/app.js
Before testing the page we need to install the loaders:
- css-loader for importing CSS files.
- style-loader for adding the stylesheet to DOM
Install the loaders using
To configure them in webpack.config.js
The relevant configuration starts with the module key. Inside this key, we configure each loader’s group inside rules.
Files that want to treat as a module, we configure an object with a test key, and with use,
test property helps to filter files with .filename extension.
Use property helps to define loaders.Loaders help to import files with .filename extension and initiate processing to DOM.
Order of webpack loaders matters
In webpack, the order in which loaders appear in the configuration is of high importance. Loaders will execute from right to left.
On Execution,you would see svg file is not loaded.
styles added to DOM
module bundler output style Embedded in HTML element
Cache Busting & Plugins
Whenever you try to generate a build in create-react-app, you would see our bundle file generated with hash content [main.335ac2354ba122403085.js] in its filename.It helps to avoid browsers from caching file content.
The value of Hash modifies or generates with every new change in our source code.
To configure them in webpack.config.js, we need to modify our output property
[contentHash] inside filename property helps in a hash generation in our filename.It uses a cryptography algorithm.
Path inside the output property instructs the webpack path to emit our bundle needs to be generated.The value of path should be build with our directory.It helps to generate bundle files inside the build folder under our project directory.
After execution you can find bundle js in our index.html.
To enable dynamic file name updation in our index.html.
To Install html-webpack-plugin.
To configure them in webpack.config.json
The property template inside HTML Webpack Plugin helps to add template needs to be generated.The value of our template should be the path of our index.html.On execution of npm start to command you would see index.html file gets generate with our template and js bundle mapped inside index.html.
Extract CSS
Once CSS loaders are in place you can extract CSS files with MiniCssExtractPlugin to avoid delay of loading styles in browsers DOM.
To install MiniCssExtractPlugin
To configure you need import min-css-extract-plugin in our webpack.config.json under plugins.
Clean webpack plugin helps to clean up our old hash files in our build folder. Once the configuration is done, try to execute npm start command.
You can now see that css file gets generated and added inside our build folder.
Html-loader/File- loader/Clean-Webpack plugin
To work with images in webpack we need to install two loaders
- html-loader
- file-loader
Html loader helps webpack to generate and configure the path of the file to our index.html.File loader helps to load content-of files specified in our index.html to browser DOM.
To install html and file loaders.
To configure them in webpack.config.json
options under file-loader specifies the path [location and name] where the file needs to be emitted.
On execution, you can see the assets folder gets added inside the build folder with our svg icon.
Splitting Development and Production environment
Final Step, To categorize configurations based on environments.
Few parameters like Entry, html-webpack-plugin would be common between environments.
Few dis-similarities like in development need a server to reflect live updates of our code changes in our browser.To create a server, we need to install webpack -dev-server.
Install webpack-dev-server using npm i webpack-dev-server — save
To configure, we need to modify our scripts in package.json
Webpack-dev-server works similar to nodemon in node js.It helps to build and reflect live updates of our code changes to our local server.
Webpack merge helps to interconnect our common conditions with production and development environment configurations .To install webpack-merge
Resultant configuration of files after splitting would be
webpack.config.js
webpack.dev.js
webpack.prod.js
Mode property helps the webpack to identify environments.The mode can be either development or production. Unlike development, webpack optimizes our code using Terser-webpack-plugin in our production mode.This process is termed as minification.
Our code is ready for execution.
To validate our development settings, Use npm start command, that helps to bring up the webpack-dev-server into your browser.You can see our app gets run on http://localhost:8080/.
To validate our production settings, use npm run build command that helps to generate the build module inside project directory.
Bundle generated
Chrome dev tools
In Chrome dev tools, on the execution of index.html, you can verify the bundle generated under the source tab.
To check our complete project source code, click here.
Thanks for reading. Happy coding 😊.