Webpack 5 Documentation
Webpack 5 Documentation
Article Source: https://webpack.js.org/concepts/
Webpack is a static module bundler for modern JavaScript applications.
Concepts
Entry
An entry point indicates which module webpack should use to begin building out its internal dependency graph. webpack will figure out which other modules and libraries that entry point depends on.
Single Entry (Shorthand) Syntax
Single Entry Syntax is useful for quickly setup a configuration for an application or tool with one entry point, such as a library.
To inject multiple dependent files together, we could pass an array of file paths.
Object Syntax
Object syntax is the most scalable way of defining entry/entries in your application.
EntryDescription object
dependOn
: The entry points that the current entry point depends on. (Must not be circular)filename
: The name of each output file on disk.import
: Modules that are loaded upon startup.library
: Options for library.
Separate App and Vendor Entries
With this you can import required libraries that aren't modified (e.g. Bootstrap, jQuery, images, etc) inside vendor.js
and the content hash remains the same, which allow the browser to cache them separately.
Multi Page Application
Use exactly one entry point for each HTML document.
Output
Configuring the output
configuration options tells webpack how to write the compiled files to disk.
This configuration would output a single bundle.js
file into the dist
directory.
Multiple Entry Points
Loaders
Loaders are transformations that are applied to the source code of a module. They allow you to pre-process files as you import or "load" them. Loaders can transform files from a different language (like TypeScript) to JavaScript or load inline images as data URLs.
Example
To load CSS files and TypeScript files:
Instruct webpack to use the css-loader
for every .css
file and the ts-loader
for all .ts
files:
Configuration
module.rules
allows you to specify several loaders within your webpack configuration. Loaders are evaluated/executed from bottom to top.
Loader Features
Loaders can be chained. Each loader in the chain applies transformations to the processed resource.
Loaders can be configured with an
options
object.Loaders run in Node.js and can do everything that’s possible there.
Plugins
Anatomy
A webpack plugin is a JavaScript object that has an apply
method. This apply
method is called by the webpack compiler, giving access to the entire compilation lifecycle.
Usage
Since plugins can take arguments/options, you must pass a new
instance to the plugins
property in your webpack configuration.
Configuration
Modules
What is a webpack Module
An ES2015
import
statementA CommonJS
require()
statementAn AMD
define
andrequire
statementAn
@import
statement inside of a css/sass/less file.An image url in a stylesheet
url(...)
or HTML<img src=...>
file.
Supported Module Types
ECMAScript modules
CommonJS modules
AMD modules
Assets
WebAssembly modules
Module Resolution
A resolver is a library which helps in locating a module by its absolute path.
Resolving rules
Absolute paths
Relative paths
Module paths
Dependency Graph
Any time one file depends on another, webpack treats this as a dependency. This allows webpack to take non-code assets, such as images or web fonts.
When webpack processes your application, it starts from a list of modules defined on the command line or in its configuration file. Starting from these entry points, webpack recursively builds a dependency graph that includes every module your application needs, then bundles all of those modules into a small number of bundles - often, just one - to be loaded by the browser.
Targets
Available targets: https://webpack.js.org/configuration/target/
The Manifest
In a typical application or site built with webpack, there are three main types of code:
The source code
Any third-party library or "vendor" code
A webpack runtime and manifest that conducts the interaction of all modules
Runtime
The runtime, along with the manifest data, is basically all the code webpack needs to connect your modularized application while it's running in the browser.
Manifest
As the compiler enters, resolves, and maps out your application, it keeps detailed notes on all your modules. This collection of data is called the "Manifest."
The "Manifest" is what the runtime will use to resolve and load modules once they've been bundled and shipped to the browser.
No matter which module syntax you have chosen, those import or require statements have now become __webpack_require__
methods that point to module identifiers.
The Problem
By using content hashes within your bundle file names, you can indicate to the browser when the content of a file has changed, thus invalidating the cache.
However, certain hashes change even when their content apparently does not. This is caused by the injection of the runtime and manifest, which changes every build.
Hot Module Replacement
Hot Module Replacement (HMR) exchanges, adds, or removes modules while an application is running, without a full reload.
Retain application state which is lost during a full reload.
Save valuable development time by only updating what's changed.
Instantly update the browser when modifications are made to CSS/JS in the source code.
In the Application
The application asks the HMR runtime to check for updates.
The runtime asynchronously downloads the updates and notifies the application.
The application then asks the runtime to apply the updates.
The runtime synchronously applies the updates.
In the Compiler
In addition to normal assets, the compiler needs to emit an "update" to allow updating from the previous version to the new version.
The updated manifest (JSON)
One or more updated chunks (JavaScript)
The manifest contains the new compilation hash and a list of all updated chunks. Each of these chunks contains the new code for all updated modules.
The compiler ensures that module IDs and chunk IDs are consistent between these builds.
In a Module
HMR is an opt-in feature that only affects modules containing HMR code. When implementing the HMR interface in a module, you can describe what should happen when the module is updated.
In the Runtime
For the module system runtime, additional code is emitted to track module parents
and children
. On the management side, the runtime supports two methods: check
and apply
.
A check
makes an HTTP request to the update manifest. If this request fails, there is no update available. If it succeeds, the list of updated chunks is compared to the list of currently loaded chunks. For each loaded chunk, the corresponding update chunk is downloaded. All module updates are stored in the runtime. When all update chunks have been downloaded and are ready to be applied, the runtime switches into the ready
state.
The apply
method flags all updated modules as invalid. For each invalid module, there needs to be an update handler in the module or in its parents. Otherwise, the invalid flag bubbles up and invalidates parents as well. Each bubble continues until the app's entry point or a module with an update handler is reached. If it bubbles up from an entry point, the process fails.
Afterwards, all invalid modules are disposed and unloaded. The current hash is then updated and all accept handlers are called. The runtime switches back to the idle
state and everything continues as normal.
Under The Hood
The bundling is a function that takes some files and emits others. Between input and output, it also has modules, entry points, chunks, chunk groups, and many other intermediate parts.
The main parts
Every file used in your project is a Module.
By using each other, the modules form a graph (ModuleGraph).
During the bundling process, modules are combined into chunks. Chunks combine into chunk groups and form a graph (ChunkGraph) interconnected through modules. When you describe an entry point - under the hood, you create a chunk group with one chunk.
Two chunk groups with names home and about are created. Each of them has a chunk with a module - ./home.js
for home
and ./about.js
for about
.
Chunks
initial
is the main chunk for the entry point. This chunk contains all the modules and its dependencies that you specify for an entry point.
non-initial
is a chunk that may be lazy-loaded. It may appear when dynamic import or SplitChunksPlugin
is being used.
Each chunk has a corresponding asset. The assets are the output files - the result of bundling.
Example
Initial chunk with name main
is created. It contains:
./src/index.jsx
react
react-dom
and all their dependencies, except ./app.jsx
Non-initial chunk for ./app.jsx
is created as this module is imported dynamically.
Output:
By default, there is no name for non-initial chunks so that a unique ID is used instead of a name.
Output
The names of the output files are affected by the two fields in the config:
output.filename
- for initial chunk filesoutput.chunkFilename
- for non-initial chunk files
A few placeholders are available in these fields. Most often:
[id]
- chunk id ([id].js
->485.js
)[name]
- chunk name ([name].js
->app.js
). If a chunk has no name, then its id will be used.[contenthash]
- md4-hash of the output file content ([contenthash].js
->4ea6ff1de66c537eb9b2.js
)
Last updated