forked from andrewmilligan/metatagger-webpack-plugin
-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
84 lines (69 loc) · 2.51 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
import HtmlWebpackPlugin from 'html-webpack-plugin';
import cheerio from 'cheerio';
import createElement from 'create-html-element';
import optionsSchema from './schema';
import validateOptions from 'schema-utils';
const getTagString = (name, attr = {}) => {
const attributes = Object.assign({}, attr);
const html = attributes.html || '';
delete attributes.html;
try {
return createElement({ name, attributes, html });
} catch (e) {
throw new Error(`Metatagger Plugin: Error creating '${name}' element with attributes: \n${JSON.stringify(attributes, null, 2)}`);
}
};
export default class MetataggerPlugin {
constructor(options) {
validateOptions(optionsSchema, options, 'MetataggerPlugin');
this.options = options;
}
addMetatag = (selector, tag, attributes, prepend = false) => {
const parent = this.$(selector);
if (parent.length === 0) {
throw new Error(`Metatagger Plugin: Can't locate any elements with '${selector}' selector.`);
}
if (parent.length > 1) {
console.warn(`Metatagger Plugin: More than one element foound with '${selector}' selector.`);
}
if (prepend) {
parent.prepend(getTagString(tag, attributes));
} else {
parent.append(getTagString(tag, attributes));
}
};
apply(compiler) {
const { tags, pages } = this.options;
if (!tags) return;
compiler.hooks.compilation.tap('MetataggerPlugin', (compilation) => {
HtmlWebpackPlugin.getHooks(compilation).beforeEmit.tapAsync(
'MetataggerPlugin',
(data, cb) => {
const emittedPageName = data.plugin.childCompilationOutputName || data.outputName;
if (pages && pages.indexOf(emittedPageName) < 0) return cb(null, data);
try {
this.$ = cheerio.load(data.html);
} catch (e) {
throw new Error('Metatagger Plugin: Error loading HTML:\n' + e);
}
Object.keys(tags).forEach((selector) => {
const prepend = /__prepend$/.test(selector);
const tagTypes = tags[selector];
selector = selector.replace(/__prepend$/, '');
Object.keys(tagTypes).forEach((tag) => {
tagTypes[tag].forEach((attrs) => {
this.addMetatag(selector, tag, attrs, prepend);
});
});
});
try {
data.html = this.$.html();
} catch (e) {
throw new Error('Metatagger Plugin: Error rendering HTML:\n' + e);
}
cb(null, data);
}
);
});
}
};