webpack中的插件以及如何编写一个插件
SunShinewyf opened this issue · 0 comments
webpack中的插件
webpack
中的插件主要是为webpack添加功能的,webpack
中的每个插件都会在webpack
启动时被安装一次,webpack主要是通过调用插件的apply
方法来安装它们,插件可以完成更多loader不能完成的功能。
插件的使用一般是在webpack
的配置信息plugins
选项中指定。下面是一个简单的使用webpack插件的配置代码:
const webpack = require('webpack');
const extractTextPlugin = require('extract-text-webpack-plugin');
const WebpackMd5Hash = require('webpack-md5-hash')
module.exports = {
entry: {
'a': './a',
'b': './b'
},
output:{
filename:'[name]-[chunkhash].js'
},
module: {
loaders: [
{
test: /\.css$/,
loader: extractTextPlugin.extract({ fallback: 'style-loader', use: 'css-loader' })
},
{
test: /\.(png|jpg)$/,
loader:'url-loader?limit=1000&name=images/[name].[hash].[ext]'
}
],
},
plugins: [
new extractTextPlugin('[name].[contenthash:4].css'),
new WebpackMd5Hash()
],
}
如上面的配置信息所示,该配置文件使用了extractTextplugin
和WebpackMd5Hash
这两个插件。关于webpack
的更多插件信息可以移步这里.
怎么样编写一个插件
关于如何开发一个新的webpack插件,通过搜索可以发现,基本上很少有这方面的资料。除了官方文档里面的寥寥数语就只有几篇博客稍微介绍了一下。原因是编写webpack插件需要首先去通读compile
和
compilation
的源码,有一定的门槛。这里是官方的how to write a plugin
的介绍。并且给出了一个插件的基本结构如下:
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;
也就是需要定义一个含有apply
的原型方法的对象并将其导出。原因是这个apply
方法在安装插件时将被webpack
编译器调用一次,apply
方法提供了一个对应的编译器对象的引用,从而可以在回调函数中访问到
compile
对象。但是这个文档也是写得很简单,所以笔者在接触和实践的时候还是花了很多时间去看已经有的webpack 插件的源码。
编写webpack插件的关键部分是要在compile
和compilation
对象的构建流程中进行提供回调函数来进行拓展处理。关于compile
和compilation
的回调和信息,以及一些重要的对象,可以参考这里
下面就根据下面这个例子来讲解:
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;
上面这个例子主要是将compilation
生成的assets
模块写进filelist.md
这个文件中。上面是在compile
对象的emit
构建阶段提供来一个回调函数来进行拓展处理。查阅官方文档可以知道,emit
流程时,
编译器开始输出生成资源。这里是插件向 c.assets
数组添加生成资源的最后机会,这样的话就会在指定目录中生成一个filelist.md
文件,而不用自己去写fs.writeFileSync
去生成该文件,而是借助于
webpack帮我们生成。
当然根据开发人员不同的业务需求,对插件的要求不一样,所以可以在compile
和compilation
的不同构建流程来提供一些拓展的回调函数,从而可以达到自己的业务需求。
下面是笔者通过阅读源码而总结的从命令行敲入命令后,webpack
编译器执行的一系列流程:
参考资料: