-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
98 lines (85 loc) · 2.7 KB
/
index.js
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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
const fs = require('fs');
const path = require("path");
const sharp = require("sharp");
function getOutputPath(filename) {
return path.join(__dirname, filename);
}
function createCenterText(width, height) {
return Buffer.from(`
<svg width="${width}" height="${height}">
<rect width="100%" height="100%" fill="#aaaaaa" />
<text x="50%" y="50%" dominant-baseline="middle" text-anchor="middle" fill="#222222" font-size="24">${width} x ${height}</text>
</svg>
`);
}
class ImagePlaceholderResolverPlugin {
constructor() {}
apply(resolver) {
const pluginName = "ImagePlaceholderResolverPlugin";
const target = resolver.ensureHook("internal-resolve");
resolver.getHook("resolve").tapAsync(
{
name: pluginName,
stage: -99,
},
(request, resolveContext, callback) => {
const basename = request.request;
if (!basename) return callback();
const matchResult = basename.match(/^(\d+)x(\d+).(.*?)$/);
if (!matchResult) return callback();
const width = parseInt(matchResult[1]);
const height = parseInt(matchResult[2]);
const ext = matchResult[3];
const outputPath = getOutputPath(basename);
function doResolve(err) {
if (err) return callback(err);
const newRequest = {
...request,
request: `webpack-image-placeholder-plugin/${basename}`
};
resolver.doResolve(
target,
newRequest,
null,
resolveContext,
callback
);
}
if (fs.existsSync(outputPath)) return doResolve();
const centerText = createCenterText(width, height);
sharp({
create: {
width: width,
height: height,
channels: 3,
background: { r: 255, g: 255, b: 255 },
},
})
.composite([
{
input: centerText,
blend: "over",
},
])
[ext]()
.toFile(outputPath, doResolve);
}
);
}
}
class ImagePlaceholderPlugin {
constructor() {}
apply(compiler) {
const pluginName = "ImagePlaceholderPlugin";
compiler.hooks.afterResolvers.tap(pluginName, (compiler) => {
compiler.resolverFactory.hooks.resolver
.for("normal")
.tap(pluginName, (resolver) => {
const imagePlaceholderResolverPlugin =
new ImagePlaceholderResolverPlugin();
imagePlaceholderResolverPlugin.apply(resolver);
});
});
}
}
module.exports = ImagePlaceholderPlugin;