为什么要学习插件?
- webpack基础配置无法满足需求
- 插件几乎能够任意更改webpack编译结果
- webpack内部也是通过大量内部插件实现的
步骤
- 找到合适的钩子注册监听,确保callback参数能满足需要
- 插件是一个class必须有一个名为apply方法,通常用来注册hooks监听
- 在监听的回调函数里添加逻辑
- 在webpack.config里注册插件
生命周期
- compiler.hooks.emit
即将写入文件到磁盘 - compiler.hooks.done
- 钩子
webpack-sources
写webpack插件修改资源文件用到
- RawSource
单个 - ConcatSource
多个源 - …
打包资源追加新文件
1 | compilation.assets[this.options.name] = |
修改即将写入磁盘的文件
1 | let content = assets[filename].source(); |
插件-压缩打包文件
可以将输出资源压缩成zip1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39const JSZip = require('jszip')
class DonePlugin{
constructor(options){
this.options = options;
}
apply(compiler){
//准备向
// assets有source方法
compiler.hooks.emit.tapPromise('EmitPlugin',(compilation,callback)=>{
var zip = new JSZip();
for(let filename in compilation.assets){
if(compilation.assets.hasOwnProperty(filename)){
zip.file(filename,compilation.assets[filename].source());
}
}
return zip.generateAsync({type:'nodebuffer'}).then(content=>{
//把数据挂到assets上自动会写入文件
//相当于是个接口
compilation.assets[this.options.name] =
{
source(){
return content;
},
size(){
return content.length;
}
};
});
});
}
}
/**
* 找到合适的钩子
* 知道钩子函数的参数和数据结果,加工
*
*
*/
module.exports = DonePlugin;
插件-时间戳插件(修改文件)
js/css文件加上build时间戳1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28const {ConcatSource,RawSource} = require('webpack-sources');
class TimePlugin {
constructor(options) {
this.options = options;
}
apply(compiler) {
compiler.hooks.emit.tapPromise('TimePlugin',(compilation,callback)=>{
return new Promise((resolve,reject)=>{
let assets = compilation.assets;
compilation.chunks.forEach(chunk=>{
// Webpack 会根据 Chunk 去生成输出的文件资源,每个 Chunk 都对应一个及其以上的输出文件
// 例如在 Chunk 中包含了 CSS 模块并且使用了 ExtractTextPlugin 时,
// 该 Chunk 就会生成 .js 和 .css 两个文件
chunk.files.forEach(filename=>{
let content = assets[filename].source();
content = `/* ${filename} build at ${Date.now()} */\n` + content;
assets[filename] = new RawSource(content);
});
});
resolve();
});
});
}
}
module.exports = TimePlugin;