-
Notifications
You must be signed in to change notification settings - Fork 128
plugins
A (webpack) plugin is a object that has an apply
method with one parameter, the compiler. For example, a plugin is a function, and the function prototype defines a apply
method. But you also can define a "class" with the apply
method.
Many objects in webpack extends the Tapable class, which exposes a plugin
method. And with the plugin
method, plugins can use that to bind custom stuff.
The following examples is the Compiler exposing the "compile"
plugin interface, which is called when the Compiler compiles
compiler.plugin("compile", function(params) {
// Just print a text
console.log("Compiling...");
});
A plugin only gets a reference to the compiler object, so if it want to plugin stuff into other webpack objects it have to gain access to them. I. e. the Compilation object:
compiler.plugin("compilation", function(compilation) {
compilation.plugin("optimize", function() {
console.log("The compilation is now optimizing your stuff");
});
});
There are multiple types of plugin interfaces.
-
Timing
- sync (default): As seen above. Use return.
- async: Last parameter is a callback. Signature: function(err, result)
- parallel: The handlers are invoked parallel (async).
-
Return value
- not bailing (default): No return value.
- bailing: The handlers are invoked in order until one handler return something.
- parallel bailing: The handlers are invoked parallel (async). The first (by order) returned value is significant.
- waterfall: Each handler get the result value of the last handler as argument.
The run
method of the Compiler is used to start a compilation. This is not called in watch mode.
The watch
method of the Compiler is used to start a watching compilation. This is not called in normal mode.
A Compilation
is created. A plugin can use this to obtain a reference to the Compilation
object. The params
object contains useful references.
A NormalModuleFactory
is created. A plugin can use this to obtain a reference to the NormalModuleFactory
object.
A ContextModuleFactory
is created. A plugin can use this to obtain a reference to the ContextModuleFactory
object.
The Compiler starts compiling. This is used in normal and watch mode. Plugins can use this point to modify the params
object (i. e. to decorate the factories).
Plugins can use this point to add entries to the compilation or prefetch modules. They can do this by calling addEntry(context, entry, name, callback)
or prefetch(context, dependency, callback)
on the Compilation.
The compile process is finished and the modules are sealed. The next step is to emit the generated stuff. Here modules can use the results in some cool ways.
The handlers are not copied to child compilers.
The Compiler begins with emitting the generated assets. Here plugins have the last chance to add assets to the c.assets
array.
The Compiler has emitted all assets.
All is done.
The Compiler is in watch mode and a compilation has failed hard.
The Compiler is in watch mode and a file change is detected. The compilation will be begin shortly (options.watchDelay
).
All plugins extracted from the options object are added to the compiler.
All plugins extracted from the options object are added to the resolvers.
Before the factory starts resolving. The data
object has this properties:
-
context
The absolute path of the directory for resolving. -
request
The request of expression.
Plugins are allowed to modify the object or pass a new similar object to the callback.
After the factory has resolved the request. The data
object has this properties:
-
request
The resolved request. It acts as identifier for the NormalModule. -
userRequest
The request the user entered. It's resolved, but do not contain pre or post loaders. -
rawRequest
The unresolved request. -
loaders
A array of resolved loaders. This is passed to the NormalModule and they will be executed. -
resource
The resource. It will be loaded by the NormalModule. -
parser
The parser that will be used by the NormalModule.
The sealing to the compilation has started.
Optimize the compilation.
Async optimize of the tree.
Optimize the modules.
Optimizing the modules has finished.
Optimize the chunks.
Optimizing the chunks has finished.
Restore module info from records.
Sort the modules in order of importance. The first is the most important module. It will get the smallest id.
Optimize the module ids.
Optimizing the module ids has finished.
Store module info to the records.
Restore chunk info from records.
Sort the chunks in order of importance. The first is the most important chunk. It will get the smallest id.
Optimize the chunk ids.
Optimizing the chunk ids has finished.
Store chunk info to the records.
Before the compilation is hashed.
After the compilation is hashed.
Before creating the chunk assets.
Create additional assets for the chunks.
Store info about the compilation to the records
Optimize the assets for the chunks.
The assets are stored in this.assets
, but not all of them are chunk assets. A Chunk
has a property files
which points to all files created by this chunk. The additional chunk assets are stored in this.additionalChunkAssets
.
The chunk assets has been optimized.
Optimize all assets.
The assets are stored in this.assets
.
The assets has been optimized.
Before a module build has started.
A module has been build successfully.
The module build has been failed.
An assets from a module was added to the compilation.
An assets from a chunk was added to the compilation.
General purpose plugin interface for the while AST of a code fragment.
General purpose plugin interface for every statement of the code fragment.
abc(1)
=> call abc
a.b.c(1)
=> call a.b.c
abc
=> expression abc
a.b.c
=> expression a.b.c
(abc ? 1 : 2)
=> expression ?!
Return a boolean value to omit parsing of the wrong path.
typeof a.b.c
=> typeof a.b.c
if(abc) {}
=> statement if
Return a boolean value to omit parsing of the wrong path.
xyz: abc
=> label xyz
var abc, def
=> var abc
+ var def
Return false
to not add the variable to the known definitions.
Evaluate an expression.
Evaluate the type of an identifier.
Evaluate a identifier that is a free var.
Evaluate a identifier that is a defined var.
Evaluate a call to a member function of a successfully evaluated expression.
-
compiler.resolvers.normal
Resolver for a normal module -
compiler.resolvers.context
Resolver for a context module -
compiler.resolvers.loader
Resolver for a loader
Any plugin should use this.fileSystem
as fileSystem, as it's cached. It only has async named functions, but they may behave sync, if the user uses a sync file system implementation (i. e. in enhanced-require).
To join paths any plugin should use this.join
. It normalize the paths. There is a this.normalize
too.
A bailing async forEach implementation is available on this.forEachBail(array, iterator, callback)
.
To pass the request to other resolving plugins use the this.doResolve(types: String|String[], request: Request, callback)
method. types
are multiple possible request types that are tested in preference of order.
interface Request {
path: String // The current directory of the request
request: String // The current request string
query: String // The querystring of the request, if any
module: boolean // request begins with a module
directory: boolean // The request points to a directory
file: boolean // The request points to a file
resolved: boolean // The request is resolved/done
// undefined means false for boolean fields
}
// Examples
// from /home/user/project/file.js: require("../test?charset=ascii")
{
path: "/home/user/project",
request: "../test",
query: "?charset=ascii"
}
// from /home/user/project/file.js: require("test/test/")
{
path: "/home/user/project",
request: "test/test/",
module: true,
directory: true
}
Before the resolving process starts.
Before a single step in the resolving process starts.
A module request is found and should be resolved
A directory request is found and should be resolved
A file request is found and should be resolved
Here is a list what the default plugins in webpack offer. They are all (request: Request)
async waterfall
The process for normal modules and contexts is module -> module-module -> directory -> file
The process for loaders is module -> module-loader-module -> module-module -> directory -> file
A module should be looked up in a specified directory. path
contains the directory.
Used before module templates are applied to the module name. The process continues with module-module
.
webpack 👍