-
Notifications
You must be signed in to change notification settings - Fork 19
/
index.js
77 lines (71 loc) · 2.53 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
const path = require('path');
const chalk = require('chalk');
const { searchFiles } = require('./lib/utils');
function UnusedPlugin(options) {
this.sourceDirectories = options.directories || [];
this.exclude = options.exclude || [];
this.root = options.root;
this.failOnUnused = options.failOnUnused || false;
this.useGitIgnore = options.useGitIgnore || true;
}
UnusedPlugin.prototype.apply = function apply(compiler) {
const checkUnused = (compilation, callback) => {
// Files used by Webpack during compilation
const usedModules = Array.from(compilation.fileDependencies)
.filter(file => this.sourceDirectories.some(dir => file.indexOf(dir) !== -1))
.reduce((obj, item) => Object.assign(obj, { [item]: true }), {});
// Go through sourceDirectories to find all source files
Promise.all(
this.sourceDirectories.map(directory => searchFiles(directory, this.exclude, this.useGitIgnore)),
)
// Find unused source files
.then(files => files.map(array => array.filter(file => !usedModules[file])))
.then(display.bind(this))
.then(continueOrFail.bind(this, this.failOnUnused, compilation))
.then(callback);
};
// webpack 4
if (compiler.hooks && compiler.hooks.emit) {
compiler.hooks.emit.tapAsync('UnusedPlugin', checkUnused);
// webpack 3
} else {
compiler.plugin('emit', checkUnused);
}
};
module.exports = UnusedPlugin;
function continueOrFail(failOnUnused, compilation, allFiles) {
if (allFiles && allFiles.length > 0) {
if (failOnUnused) {
compilation.errors.push(new Error('Unused files found'));
} else {
compilation.warnings.push(new Error('Unused files found'));
}
}
}
function display(filesByDirectory) {
const allFiles = filesByDirectory.reduce(
(array, item) => array.concat(item),
[],
);
if (!allFiles.length) {
return [];
}
process.stdout.write('\n');
process.stdout.write(chalk.green('\n*** Unused Plugin ***\n'));
process.stdout.write(
chalk.red(`${allFiles.length} unused source files found.\n`),
);
filesByDirectory.forEach((files, index) => {
if (files.length === 0) return;
const directory = this.sourceDirectories[index];
const relative = this.root
? path.relative(this.root, directory)
: directory;
process.stdout.write(chalk.blue(`\n● ${relative}\n`));
files.forEach(file => process.stdout.write(
chalk.yellow(` • ${path.relative(directory, file)}\n`),
));
});
process.stdout.write(chalk.green('\n*** Unused Plugin ***\n\n'));
return allFiles;
}