-
Notifications
You must be signed in to change notification settings - Fork 20
/
Copy pathindex.js
104 lines (89 loc) · 3.27 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
99
100
101
102
103
104
const NAME = "webpack-fix-style-only-entries";
const defaultOptions = {
extensions: ["less", "scss", "css", "sass", "styl"],
silent: false,
ignore: undefined,
};
class WebpackFixStyleOnlyEntriesPlugin {
constructor(options) {
this.apply = this.apply.bind(this);
this.options = Object.assign({}, defaultOptions, options);
}
apply(compiler) {
const extensionsWithoutDots = this.options.extensions.map(e =>
e[0] === "." ? e.substring(1) : e
);
const patternOneOfExtensions = extensionsWithoutDots
.map(ext => escapeRegExp(ext))
.join("|");
const reStylesResource = new RegExp(
`[.](${patternOneOfExtensions})([?].*)?$`
);
compiler.hooks.compilation.tap(NAME, compilation => {
const resourcesCache = [];
compilation.hooks.chunkAsset.tap(NAME, (chunk, file) => {
if (!file.endsWith(".js") && !file.endsWith(".mjs")) return;
if (!chunk.hasEntryModule()) return;
const rawResources = collectEntryResources(compilation, chunk.entryModule, resourcesCache);
const resources = this.options.ignore
? rawResources.filter(r => !r.match(this.options.ignore))
: rawResources;
const isStyleOnly =
resources.length &&
resources.every(resource => reStylesResource.test(resource));
if (isStyleOnly) {
if (!this.options.silent) {
console.error(
"webpack-fix-style-only-entries: removing js from style only module: " +
file
);
}
const filtered = [...chunk.files].filter(f => f != file);
chunk.files = (chunk.files instanceof Set) ? new Set(filtered) : filtered;
delete compilation.assets[file];
}
});
});
}
}
function collectEntryResources(compilation, module, cache) {
// module.index is unique per compilation
// module.id can be null, not used here
if (cache[module.index] !== undefined) {
return cache[module.index];
}
if (typeof module.resource == "string") {
const resources = [module.resource];
cache[module.index] = resources;
return resources;
}
const resources = [];
if (module.dependencies) {
const hasModuleGraphSupport = compilation.hasOwnProperty('moduleGraph');
module.dependencies.forEach(dep => {
if(dep) {
const module = hasModuleGraphSupport ? compilation.moduleGraph.getModule(dep) : dep.module;
const originModule = hasModuleGraphSupport ? compilation.moduleGraph.getParentModule(dep) : dep.originModule;
const nextModule = module || originModule;
if (nextModule) {
const depResources = collectEntryResources(compilation, nextModule, cache);
for (let index = 0, length = depResources.length; index !== length; index++) {
resources.push(depResources[index]);
}
}
}
});
}
cache[module.index] = resources;
return resources;
}
// https://github.com/lodash/lodash/blob/4.17.11/lodash.js#L14274
const reRegExpChar = /[\\^$.*+?()[\]{}|]/g;
const reHasRegExpChar = RegExp(reRegExpChar.source);
function escapeRegExp(string) {
string = String(string);
return string && reHasRegExpChar.test(string)
? string.replace(reRegExpChar, "\\$&")
: string;
}
module.exports = WebpackFixStyleOnlyEntriesPlugin;