📄 Table of Contents

  • Webpack Introduction

◉ Webpack

Webpack is an asset bundler that powers an entire React app. In a nutshell, it takes all of the JavaScript, CSS, and any other front-end assets, and produces the output that you see in your browser. It can do advanced things like code splitting to improve the performance of your application, lazy loading, caching, tree shaking, and it helps you create entire libraries that you can distribute across teams.

◉ Code Splitting

Code splitting is one of the most compelling features of webpack. This feature allows you to split your code into various bundles which can then be loaded on demand or in parallel. It can be used to achieve smaller bundles and control resource load prioritization which, if used correctly, can have a major impact on load time.

  • Prevent Duplication: Use the SplitChunksPlugin to dedupe and split chunks.
  • Dynamic Imports: Split code via inline function calls within modules.

Entry Points

This is by far the easiest and most intuitive way to split code. However, it is more manual and has some pitfalls we will go over. Let’s take a look at how we might split another module from the main bundle:

webpack-demo
|- package.json
|- webpack.config.js
|- /dist
|- /src
|- index.js
+ |- another-module.js
|- /node_modules
import _ from 'lodash';console.log(
_.join(['Another', 'module', 'loaded!'], ' ')
);
const path = require('path');module.exports = {
mode: 'development',
entry: {
index: './src/index.js',
+ another: './src/another-module.js',
},
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, 'dist'),
},
};
...
Asset Size Chunks Chunk Names
another.bundle.js 550 KiB another [emitted] another
index.bundle.js 550 KiB index [emitted] index
Entrypoint index = index.bundle.js
Entrypoint another = another.bundle.js
...
  • It isn’t as flexible and can’t be used to dynamically split code with the core application logic.

Prevent Duplication

Entry dependencies

The dependOn option allows to share the modules between the chunks

const path = require('path');  module.exports = {
mode: 'development',
entry: {
- index: './src/index.js',
- another: './src/another-module.js',
+ index: { import: './src/index.js', dependOn: 'shared' },
+ another: { import: './src/another-module.js', dependOn: 'shared' },
+ shared: 'lodash',
},
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, 'dist'),
},
};

optimization.runtimeChunk

optimization.runtimeChunk: 'single' is needed when multiple entry points are being used on a single HTML page.

SplitChunksPlugin

The SplitChunksPlugin allows us to extract common dependencies into an existing entry chunk or an entirely new chunk. Let's use this to de-duplicate the lodash dependency from the previous example:

const path = require('path');  module.exports = {
mode: 'development',
entry: {
index: './src/index.js',
another: './src/another-module.js',
},
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, 'dist'),
},
+ optimization: {
+ splitChunks: {
+ chunks: 'all',
+ },
+ },
};
...
Asset Size Chunks Chunk Names
another.bundle.js 5.95 KiB another [emitted] another
index.bundle.js 5.89 KiB index [emitted] index
vendors~another~index.bundle.js 547 KiB vendors~another~index [emitted] vendors~another~index
Entrypoint index = vendors~another~index.bundle.js index.bundle.js
Entrypoint another = vendors~another~index.bundle.js another.bundle.js
...

Dynamic Imports

Lazy Loading

Lazy, or “on demand”, loading is a great way to optimize your site or application. This practice essentially involves splitting your code at logical breakpoints, and then loading it once the user has done something that requires, or will require, a new block of code. This speeds up the initial load of the application and lightens its overall weight as some blocks may never even be loaded.

{
"presets": ["@babel/preset-react"],
"plugins": ["@babel/plugin-syntax-dynamic-import"]
}
import loadable from "@loadable/component";
import Loading from "./Loading.js";
const LoadableComponent = loadable(() => import("./Dashboard.js"), {
fallback: <Loading />
});
export default class LoadableDashboard extends React.Component {
render() {
return <LoadableComponent />;
}
}

Experience with Front-end Technologies and MERN / MEAN Stack. Working on all Major UI Frameworks like React, Angular.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store