Webpack
webpack is a static module bundler for modern JavaScript applications. When webpack processes your application, it internally builds a dependency graph which maps every module your project needs and g
Entry
Output
Loaders
Plugins
Mode
Browser Compatibility
Performance dev:
hmr hot module
source-map
oneOf in matching
babel cache
contenthash
multi thread pack
import externals, like jquery, cnd react.
Performance product:
code split
lazy loading, pre loading
use tree shaking
use pwa
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, and also provide them as dependencies for your application.
When webpack processes your application, it starts from a list of modules defined on the command line or in its config 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.
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 (directly and indirectly).
webpack.config.js
Output
The output property tells webpack where to emit the bundles it creates and how to name these files. It defaults to ./dist/main.js
for the main output file and to the ./dist
folder for any other generated file.
You can configure this part of the process by specifying an output
field in your configuration:
webpack.config.js
the output.filename
and the output.path
properties to tell webpack the name of our bundle and where we want it to be emitted to.
Loaders
Out of the box, webpack only understands JavaScript and JSON files. Loaders allow webpack to process other types of files and convert them into valid modules that can be consumed by your application and added to the dependency graph.
Note that the ability to
import
any type of module, e.g..css
files, is a feature specific to webpack and may not be supported by other bundlers or task runners. We feel this extension of the language is warranted as it allows developers to build a more accurate dependency graph.
At a high level, loaders have two properties in your webpack configuration:
The
test
property identifies which file or files should be transformed.The
use
property indicates which loader should be used to do the transforming.
webpack.config.js
Plugins
While loaders are used to transform certain types of modules, plugins can be leveraged to perform a wider range of tasks like bundle to improve proformance, asset management and injection of environment variables.
In order to use a plugin, you need to require()
it and add it to the plugins
array. Most plugins are customizable through options. Since you can use a plugin multiple times in a config for different purposes, you need to create an instance of it by calling it with the new
operator.
Tapable
This small library is a core utility in webpack but can also be used elsewhere to provide a similar plugin interface. Many objects in webpack extend the Tapable
class. The class exposes tap
, tapAsync
, and tapPromise
methods which plugins can use to inject custom build steps that will be fired throughout a compilation.
Please see the documentation to learn more. An understanding of the three tap
methods, as well as the hooks that provide them is crucial. The objects that extend Tapable
(e.g. the compiler), the hooks they provide, and each hook's type (e.g. the SyncHook
) will be noted.
webpack.config.js
In the example above, the html-webpack-plugin
generates an HTML file for your application by injecting automatically all your generated bundles.
By setting the mode
parameter to either development
, production
or none
, you can enable webpack's built-in optimizations that correspond to each environment. The default value is production
.
Hot Module Replacement
(HMR) exchanges, adds, or removes modules while an application is running, without a full reload. This can significantly speed up development in a few ways:
Retain application state which is lost during a full reload.
Save valuable development time by only updating what's changed.
Modifications made to CSS/JS in the source code results in an instant browser update which is almost comparable to changing styles directly in the browser's dev tools.
The following steps allow modules to be swapped in and out of an 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 addition to normal assets, the compiler needs to emit an "update" to allow updating from previous version to the new version. The "update" consists of two parts:
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 (or a flag indicating that the module was removed).
The compiler ensures that module IDs and chunk IDs are consistent between these builds. It typically stores these IDs in memory (e.g. with webpack-dev-server), but it's also possible to store them in a JSON file.
Last updated
Was this helpful?