There is no me, there is no me. – chuang tzu
Introduction to the
Plug-ins are the backbone of WebPack. Webpack itself is also built on top of the same plugin system you use in your WebPack configuration! Plug-ins are designed to solve other things that loader cannot implement. To write plug-ins well, you need to know the two core concepts of Compiler, Compilation and tapable in Webpack. The compilation process is already documented in Webpack. Webpack makes it more flexible through the Plugin mechanism to adapt to various application scenarios. A number of events are broadcast during the life cycle of a Webpack run, and the Plugin can listen for these events and change the output when appropriate through the API provided by Webpack.
Implement a Plugin
A WebPack Plugin basically consists of the following steps:
- A JavaScript function or class
- Define an injection in the function prototype
compiler
The object’sapply
Methods. apply
In the functioncompiler
Inserts the specified event hook, retrieved in the hook callbackcompilation
object- use
compilation
Manipulation to modifywebapack
Internal instance data. - Asynchronous plug-in, used after data processing
callback
The callback
Finally, a simple clean-Webpack-plugin is implemented.
A simple plug-in
class WebpackCleanupPlugin {
// constructor
constructor(options) {
console.log("WebpackCleanupPlugin", options);
}
// Apply the function
apply(compiler) {
console.log(compiler);
// Bind the hook event
compiler.plugin("done", compilation => {
console.log(compilation); }); }}Copy the code
How to use it is introduced in webpack.config.js and used as follows:
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
// Introduce your own plugin
const WebpackCleanupPlugin = require("./WebpackCleanupPlugin");
module.exports = {
devtool: "source-map".mode: "production".entry: {
index: "./src/index.js".chunk1: "./src/chunk1.js"
},
output: {
filename: "[name].[chunkhash].js"
},
module: {
rules: [{test: /\.css$/.use: [MiniCssExtractPlugin.loader, "css-loader"]]}},plugins: [
// Extract the CSS plug-in
new MiniCssExtractPlugin({
// Options similar to the same options in webpackOptions.output
// both options are optional
filename: "[name].[contenthash].css"
}),
// Use your own plugin
new WebpackCleanupPlugin()
]
};
Copy the code
Self-written plug-ins are executed as follows:
webpack
After it is started, it is executed first during the reading of the configurationnew WebpackCleanupPlugin()
Initialize a Webpackage CleanupPlugin to get an example.- In the initialization
compiler
Object, and then calledWebpackCleanupPlugin.apply(compiler)
Pass in the plug-in instancecompiler
Object. - The plug-in instance is being retrieved
compiler
After the object can be passedcompiler.plugin
(Event name, callback function) onWebpack
An event broadcast. - And can be accessed through
compiler
Object to operatewebpack
.
The Compiler, Compilation,
- The Compiler object contains all configuration information for the Webpack environment, including
options
.hook
.loaders
.plugins
This information, this object is inWebpack
Instantiated at startup, it isGlobally uniqueIt can be simply interpreted asWebpack
Instance;Compiler
Contains the following:
- The Compilation object contains the current module resources, compile-generated resources, changing files, and so on. when
Webpack
Run in development mode whenever a file change is detected, a new oneCompilation
Will be created.Compilation
Object also provides many event callbacks for plug-ins to extend. throughCompilation
You can also read itCompiler
Object.
The Compilation contains something like this:
The difference between Compiler and Compilation is that Compiler represents the entire Webpack lifecycle from startup to shutdown, while Compilation simply represents a new Compilation.
Compiler hooks and compilation hooks
A simple file removal plug-in
If the file is modified each time, a new file will be generated, and the hash of the file will also change, so the changed file and its previous file will be invalid. To remove the previous file, we use the clean-webpack-plugin, which implements a simple file removal. If you don’t know the difference between hash, contenthash, and chunkhash, read this article.
It can be roughly divided into the following steps:
- To obtain
output
The path, the exit path, is generally zerodist
- Bind hook event
compiler.plugin('done', (stats) => {})
- Compiles the file, compares it with the original file, and deletes unmatched files (options can also be set to ignore files)
The code implementation is as follows
const recursiveReadSync = require("recursive-readdir-sync");
const minimatch = require("minimatch");
const path = require("path");
const fs = require("fs");
const union = require("lodash.union");
// Match the file
function getFiles(fromPath, exclude = []) {
const files = recursiveReadSync(fromPath).filter(file= >
exclude.every(
excluded= >! minimatch(path.relative(fromPath, file), path.join(excluded), {dot: true})));// console.log(files);
return files;
}
class WebpackCleanupPlugin {
constructor(options = {}) {
// Config file
this.options = options;
}
apply(compiler) {
// Get the output path
const outputPath = compiler.options.output.path;
// Bind the hook event
compiler.plugin("done", stats => {
if( compiler.outputFileSystem.constructor.name ! = ="NodeOutputFileSystem"
) {
return;
}
// Get the compile completion file name
const assets = stats.toJson().assets.map(asset= > asset.name);
console.log(assets);
// Most combinations are combined and de-duplicated
const exclude = union(this.options.exclude, assets);
console.log(exclude);
// console.log('outputPath', outputPath);
// Get the unmatched file
const files = getFiles(outputPath, exclude);
// const files = [];
console.log("files", files);
if (this.options.preview) {
// console.log('%s file(s) would be deleted:', files.length);
// Output file
files.forEach(file= > console.log(" %s", file));
// console.log();
} else {
// Delete unmatched files
files.forEach(fs.unlinkSync);
}
if (!this.options.quiet) {
// console.log('\nWebpackCleanupPlugin: %s file(s) deleted.', files.length);}}); }}module.exports = WebpackCleanupPlugin;
Copy the code
The above plug-in implements a clean compilation file effect. I won’t do the experiment here. If you are interested, you can copy the code locally and run it to see the results.
conclusion
With a general idea of how to write a simple file-clearing plugin for WebPack, you can do a lot more:
- Read output resources, code blocks, modules and their dependencies (in
emit
Event occurrence) - Listening for file changes
watch-run
- Modifying output Resources
compilation.assets
The concrete implementation can take a look at Webpack in a nutshell
reference
Dry! 内 容 提 示 webPack plugin (tapable + Webpack process)
Take a look at the real Webpack plug-in