forked from allexcd/webpack-clean
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
140 lines (119 loc) · 3.3 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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
/**
* Created by AlexCD on 07/09/2015.
*/
const path = require('path');
const join = path.join;
const fs = require('fs-extra');
const logger = require('winston-color');
const fileExists = require('file-exists');
const pluginName = 'WebpackClean';
const INFO = 'info';
const WARN = 'warn';
const ERROR = 'error';
function log (type, msg) {
logger[type](`${pluginName} - ${msg}`);
}
function throwErr (msg, err) {
throw new Error(msg, err);
}
function getFileList (files) {
if (!files) {
return [];
}
return Array.isArray(files) ? files : new Array(files);
}
function addMapExtension (file) {
return `${file}.map`;
}
function getContext (basePath) {
return basePath || path.dirname(module.parent.filename);
}
function removeFile (file) {
const self = this;
const promise = new Promise((resolve, reject) => {
fs.unlink(file, (err) => {
if (err) {
reject(err);
} else {
log(INFO, `removed ${file}`);
resolve(self.pluginName, 'file removed:', file);
}
});
});
return promise;
}
function isExistingFile (filePath) {
return fileExists(filePath)
.then((exists) => {
if (exists) {
return removeFile(filePath);
} else {
log(WARN, `file ${filePath} does not exist`);
}
})
.catch((err) => throwErr(pluginName, err));
}
function checkFiles (files, context, removeMaps) {
const fileExistsPromises = [];
// check if each file exists
files.forEach((file) => {
const filePath = join(context, file);
const fileMapPath = addMapExtension(filePath);
// add to list the file to be removed
fileExistsPromises.push(isExistingFile(filePath));
// add to list the map file to be removed
if (removeMaps) {
fileExistsPromises.push(isExistingFile(fileMapPath));
}
});
return fileExistsPromises;
}
function doRemove () {
const self = this;
Promise.all(checkFiles(self.files, self.context, self.removeMaps))
.then((removalPromises) => Promise.all(removalPromises))
.then(() => {
log(INFO, 'DONE');
})
.catch((err) => throwErr(pluginName, err));
}
// allow the options object to be omitted in the constructor function
function WebpackClean (
files,
{ basePath = null, removeMaps = false, forceDelete = false } = {}
) {
this.files = getFileList(files);
this.context = getContext(basePath); // get webpack roots
this.removeMaps = removeMaps;
this.forceDelete = forceDelete;
}
WebpackClean.prototype.apply = function (compiler) {
const self = this;
// eslint-disable-next-line no-prototype-builtins
const hasLifecycleHooks = Object.prototype.hasOwnProperty.call(compiler, 'hooks'); // Webpack 4.x.x
const logErrMsg = 'Files removal aborted due to:';
if (hasLifecycleHooks) {
compiler.hooks.failed.tap(pluginName, (err) => {
if (!self.forceDelete) {
log(ERROR, `${logErrMsg} \n${err}`);
return false;
}
});
compiler.hooks.done.tap(pluginName, (stats) => {
doRemove.call(self);
});
} else {
compiler.plugin('done', (stats) => {
if (
!self.forceDelete &&
stats.compilation.errors &&
stats.compilation.errors.length > 0
) {
log(ERROR, `${logErrMsg} \n${stats.compilation.errors}`);
return false;
}
doRemove.call(self);
});
}
};
module.exports = WebpackClean;