-
Notifications
You must be signed in to change notification settings - Fork 0
how to write a plugin.cn
Plugins expose the full potential of the Webpack engine to third-party developers. Using staged build callbacks, developers can introduce their own behaviors into the Webpack build process. Building plugins is a bit more advanced than building loaders, because you'll need to understand some of the Webpack low-level internals to hook into them. Be prepared to read some source code!
webpack 引擎的所有潜力由插件体系提供给第三方开发者。使用分阶段构建的回调,开发者可以向 webpack 构建流程注入自定义行为。建立插件比建立 loader 更为高级一点,因为你需要了解部分 webpack 底层的内部对象以便挂接进去。做好心理准备阅读更多的源代码吧!
Among the two most important resources while developing plugins are the compiler
and compilation
objects. Understanding their roles is an important first step in extending the Webpack engine.
开发插件时最重要的两个资源是 compiler
和compilation
对象。
-
The
compiler
object represents the fully configured Webpack environment. This object is built once upon starting Webpack, and is configured with all operational settings including options, loaders, and plugins. When applying a plugin to the Webpack environment, the plugin will receive a reference to this compiler. Use the compiler to access the main Webpack environment. -
compiler
对象表示配置完整的 webpack 环境。这个对象在 webpack 启动时构建一次,配置有所有操作设定,包括选项、loader 和插件。当一个插件应用到 webpack 环境中,该插件将获得这个 compiler 对象的引用。可使用这个 compiler 来访问 webpack 主环境。 -
A
compilation
object represents a single build of versioned assets. While running Webpack development middleware, a new compilation will be created each time a file change is detected, thus generating a new set of compiled assets. A compilation surfaces information about the present state of module resources, compiled assets, changed files, and watched dependencies. The compilation also provides many callback points at which a plugin may choose to perform custom actions. -
一个
compilation
对象代表对版本化资源的单次构建。在运行 webpack 开发中间件事时,每当侦测到文件变更,会创建一个新的 compilation,从而生成一套新的编译过的资源。一个 compilation 透露了很多数据的信息,包括模块资源的当前状态,编译过的资源,变更的文件,以及监视的依赖。而且,它也提供了很多回调点,插件可以选用来进行自定义操作。
These two components are an integral part of any Webpack plugin (especially a compilation
), so developers will benefit by familiarizing themselves with these source files:
这两个组件都被集成到每个 webpack 插件(特别是compilation
),所以开发者熟悉它们的源码的话会受益不少。
Plugins are instanceable objects with an apply
method on their prototype. This apply
method is called once by the Webpack compiler while installing the plugin. The apply
method is given a reference to the underlying Webpack compiler, which grants access to compiler callbacks. A simple plugin is structured as follows:
function HelloWorldPlugin(options) {
// Setup the plugin instance with options...
}
HelloWorldPlugin.prototype.apply = function(compiler) {
compiler.plugin('done', function() {
console.log('Hello World!');
});
};
module.exports = HelloWorldPlugin;
Then to install the plugin, just include an instance in your Webpack config plugins
array:
var HelloWorldPlugin = require('hello-world');
var webpackConfig = {
// ... config settings here ...
plugins: [
new HelloWorldPlugin({options: true})
]
};
Using the compiler object, you may bind callbacks that provide a reference to each new compilation. These compilations provide callbacks for hooking into numerous steps within the build process.
function HelloCompilationPlugin(options) {}
HelloCompilationPlugin.prototype.apply = function(compiler) {
// Setup callback for accessing a compilation:
compiler.plugin("compilation", function(compilation) {
// Now setup callbacks for accessing compilation steps:
compilation.plugin("optimize", function() {
console.log("Assets are being optimized.");
});
});
});
module.exports = HelloCompilationPlugin;
For more information on what callbacks are available on the compiler
, compilation
, and other important objects, see the plugins API doc.
Some compilation plugin steps are asynchronous, and pass a callback function that must be invoked when your plugin is finished running.
function HelloAsyncPlugin(options) {}
HelloAsyncPlugin.prototype.apply = function(compiler) {
compiler.plugin("emit", function(compilation, callback) {
// Do something async...
setTimeout(function() {
console.log("Done with async work...");
callback();
}, 1000);
});
});
module.exports = HelloAsyncPlugin;
Once we can latch onto the Webpack compiler and each individual compilations, the possibilities become endless for what we can do with the engine itself. We can reformat existing files, create derivative files, or fabricate entirely new assets.
Let's write a simple example plugin that generates a new build file called filelist.md
; the contents of which will list all of the asset files in our build. This plugin might look something like this:
function FileListPlugin(options) {}
FileListPlugin.prototype.apply = function(compiler) {
compiler.plugin('emit', function(compilation, callback) {
// Create a header string for the generated file:
var filelist = 'In this build:\n\n';
// Loop through all compiled assets,
// adding a new line item for each filename.
for (var filename in compilation.assets) {
filelist += ('- '+ filename +'\n');
}
// Insert this list into the Webpack build as a new file asset:
compilation.assets['filelist.md'] = {
source: function() {
return filelist;
},
size: function() {
return filelist.length;
}
};
callback();
});
};
module.exports = FileListPlugin;