The ultimate guide to webpack and babel: Loaders pt2

This article is in continuation to my series on configuring Webpack and babel for your react app. Please find part 1 here and the Link to the GitHub repo

Loaders: Introduction

Loaders are nothing but the transformation applied to the source code of a module. They are used to handle build steps and acts as a build tool. They have a wide variety of use cases like Converting TS to JS, Loading CSS, loading inline images as data URLs.

Also as webpack would only understand JS so loaders help us convert various assets to JS.

Loaders follow the module resolution & are mostly loaded from the module path. A loader is just a function that can be written in Node.js compatible JS all it should do in end is to return JS.

Another reason for the popularity of loaders is that it runs in Node.js and can leverage its capabilities. It also supports chaining and execution is chain is in reverse order.

CSS Loader

It’s hard to imagine a Front-end without some CSS. To add CSS files to our bundle we will be using the Following Loaders

CSS Loader For parsing our CSS files and resolving external resources referenced by our CSS files.

style-loader Injects CSS into the DOM

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. It allows us to take advantage of Browser Caching.

npm install -D css-loader style-loader mini-css-extract-plugin

And then we need to add the below code to our webpack.config.js

const MiniCssExtractPlugin = require(‘mini-css-extract-plugin’); // at top of the file// Add below code in rules.
{
test: /\.css$/, use: [ isProduction ? MiniCssExtractPlugin.loader : ‘style-loader’, ‘css-loader’, ], },

Additionally, we will have to configure the MiniCSSExtractPlugin for production Mode by adding below code in plugins array:

isProduction &&new MiniCssExtractPlugin({filename: ‘assets/css/[name].[contenthash:8].css’,chunkFilename: ‘assets/css/[name].[contenthash:8].chunk.css’,}),

CSS Modules

A CSS Module is a CSS file in which all class names and animation names are scoped locally by default. CSS Modules compile to a low-level interchange format called ICSS. When importing the CSS Module from a JS Module, it exports an object with all mappings from local names to global names.

import styles from "./style.css";
// import { className } from "./style.css";
element.innerHTML = '<div class="' + styles.className + '">';

The good news is that support for CSS Modules is present in CSS Loader.

{
test: /\.module.css$/,
use: [
isProduction ? MiniCssExtractPlugin.loader : "style-loader",
{
loader: "css-loader",
options: {
modules: true
}
}
]
},

So if you want the CSS file to be transformed by this the name should end with .module.css .

Sass/SCSS

Sass is another popular CSS processing framework. It is one of the most popular CSS extension languages. Since it has already matured in pas 14 years you would typically see it in your enterprise app.

npm install -D sass-loader node-sass resolve-url-loader

Then, add a new loader to our Webpack configuration:

        {
test: /\.s[ac]ss$/,
use: [
isProduction ? MiniCssExtractPlugin.loader : "style-loader",
{
loader: "css-loader",
options: {
importLoaders: 2
}
},
"resolve-url-loader",
{
loader: "sass-loader",
options: {
sourceMap: true
}
}
]
},

Image Loaders

Webpack can load any binary static files like images, videos. This can be easily handled by a file-loader or url-loader.

npm install -D url-loader

And then adding below section in Rules in webpack.config.js

{ test: /\.(png|jpg|gif)$/i,  use: {   loader: 'url-loader',   options: {      limit: 8192,      name: 'static/media/[name].[hash:8].[ext]',},},},

As you may notice there is a limit added in the options, this is a threshold size, if the resource is smaller than this then it will be embedded as the base64 string saving us a request.

File Loader

As we have just discussed that file-loader can work for any type of file. Please note that it doesn’t apply any optimizations.

npm install -D file-loader

And then adding below section in the Rules in webpack.config.js

{   test: /\.(eot|otf|ttf|woff|woff2)$/,    loader: require.resolve('file-loader'),    options: {      name: 'static/media/[name].[hash:8].[ext]', },},

Configuring Environments

Typically any react-app we would make would be expected to run across multiple environments so it becomes important to configure it. To do so we will be using DefinePlugin() which is provided by webpack out of the box.

const webpack = require("webpack");//Add below code in plugins array
new webpack.DefinePlugin({
‘process.env.NODE_ENV’: JSON.stringify( isProduction ? ‘production’ : ‘development’ ),}),

These are some of the common loaders you would encounter. However, my intent was to get you familiar with a couple of loaders and how they can be configured.

Feel free to play around with it. In the upcoming parts, we will be discussing Code Splitting, Tree Shaking, HMR, and many more topics.

Happy Learning!

A tech geek who loves to solve problems and coming up with meaningful, simplistic solutions.