Webpack Loaders and Plugins
In this blog, we will learn about what are loaders and plugins and how to use them with webpack.
This blog is the continuation of the Webpack tutorial series so if you haven’t read/watched the previous blog/videos. You can read/watch the Setting up webpack for your project
and Webpack dev server
Loaders
Loaders enable us to bundle static assets. Loaders tell webpack how to interpret and translate files. The transformation happens on a per-file basis before adding to the dependency graph.
Use of loaders:
- As webpack only understands javascript, we use loaders to parse stylesheets and images and outputs it as javascript.
- Can check linting issues
- Resolve static assets
- Transpiling non-compliant codes.
Basic Loaders:
style-loader, css-loader, sass-loader, babel-loader, postcss-loader, file-loader, url-loader
style-loader and css-loader
npm i -D style-loader css-loader
The style-loader
and css-loader
go hand in hand. When we include below rules and add these loaders when webpack finds a .css
file, the css-loader
will convert the css into JavaScript in array format, which is then consumed by style-loader
which then converts it into a JavaScript module.
module: {
rules: [
{
test: /\.css$/,
use: ["style-loader", "css-loader"]
}
]
},
Let's take another example where we want to use loaders for .less
files.
Loaders execute from right to left. They just take a source and return another source.
rules: [
{
test: /\.less$/,
use: ["style-loader", "css-loader", "less-loader"]
}
]
},
Hence, just before the code is bundled webpack checks if there are any rules defined. In the below case, if the entry point is header.less
,
- the
less-loader
will convert the file into CSS. - then the
css-loader
will convert into a javascript file in an array format - which can be consumed by
style-loader
and -style-loader
converts the file into a JavaScript module.
url-loader & file-loader
The url-loader
converts image into base 64 format, or a url for the image. You need to install file-loader as well.
npm i -D url-loader file-loader
Let's add an image to the src directory called react-logo.jpeg.Now add the rule for the url-loader
in webpack.config.js
module: {
rules: [
{
test: /\.css$/,
use: ["style-loader", "css-loader"]
},
{
test: /\.(png|jp?g|svg)$/,
use: [{
loader: "url-loader",
options: {
limit: 5000
}
}]
}
]
},
Webpack treats this image now as javaScript and it can be imported into the file. If we console log this image we will see base 64 format
. Since we are passing an option limit as 5000, it means only if the image is 5000 bytes then emit that as a base 64 url
, otherwise take that file and emit it to the dist directory and return the hashed URL of where that file will be. So when you console the image it will return the URL of the file where its created in the dist directory
Hot module replacement
Loaders support a unique Webpack feature called hot module replacement. This means that webpack is able to patch changes incrementally and apply them without having to reload the browser.
So if you add a flag — hot in your script then it will render the changes on the browser without even browser reload.
"scripts": {
"webpack-dev-server": "webpack-dev-server",
"dev": "webpack-dev-server --mode=development --hot",
"prod": "webpack --mode=production"
},
Plugins
Plugins are like objects ( with an apply property ) that can be instantiated. It allows you to hook into the entire webpack lifecycle of events.
80% of the webpack is made up of its own plugin system. Webpack itself is an event-driven architecture.
Plugins add additional functionality to Compilation( optimized bundle modules ). Loaders are only applied on a profile basis but you can access a whole bundle with plugins.
We should not pass the vendor files( like jquery ) through loader as it will add the webpack module wrapper to those files as well. We can directly copy those vendor files to the build file.
Common Plugins
html-webpack-plugin, mini-css-extract-plugin, extract-text-webpack-plugin
You can also check out popular plugins on Webpack Contrib.
mini-css-extract-plugin
This plugin extracts CSS into separate files. It creates a CSS file per JS file which contains CSS. It supports On-Demand-Loading of CSS and SourceMaps.
npm i -D mini-css-extract-plugin
We can require this plugin as MiniCssExtractPlugin
and then add this to the rules and plugins as mention below
// webpack.config.js
const path = require( 'path' );
const HtmlWebPackPlugin = require( 'html-webpack-plugin' );
const MiniCssExtractPlugin = require( 'mini-css-extract-plugin' );
module.exports = {
context: __dirname,
entry: './src/index.js',
output: {
path: path.resolve( __dirname, 'dist' ),
filename: 'main.js',
},
module: {
rules: [
{
test: /\.js$/,
use: 'babel-loader',
},
{
test: /\.css$/,
exclude: /node_modules/,
use: [
{
loader: MiniCssExtractPlugin.loader,
},
"css-loader"
]
}
]
},
plugins: [ new HtmlWebPackPlugin(), new MiniCssExtractPlugin() ]
};
Let's create a src/style.css file and import it into src/index.js
// src/index.js
import style from './style.css';
import homeStyle from './home.css';
const test = () => {
console.log( 'test something change' );
};
test();
When we run npm run prod
the mini-css-extract-plugin
is going to create a main.css
file inside the dist folder and html-webpack-plugin
will automatically include the stylesheet using the link tag.
We can also import multiple css file and it will just add the css codes from those files incrementally inside the main.css file, so it won’t create a separate css file for each one.
For more you can watch the video above