Skip to content

Commit eb12eb3

Browse files
alexander-akaitevilebottnawi
authored andcommitted
feat: cleaner plugin
1 parent 4d00edc commit eb12eb3

File tree

13 files changed

+182
-1
lines changed

13 files changed

+182
-1
lines changed

lib/CleanerPlugin.js

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/*
2+
MIT License http://www.opensource.org/licenses/mit-license.php
3+
Author Tobias Koppers @sokra
4+
*/
5+
"use strict";
6+
const del = require("del");
7+
8+
class CleanerPlugin {
9+
constructor(options) {
10+
this.options = options || {};
11+
12+
this.patterns = [];
13+
this.cleanerOptions = {};
14+
15+
if (typeof this.options === "string") {
16+
this.patterns = [this.options];
17+
} else if (Array.isArray(this.options)) {
18+
this.patterns = this.options;
19+
} else {
20+
this.patterns = this.options.patterns;
21+
this.cleanerOptions = this.options.options;
22+
}
23+
}
24+
25+
apply(compiler) {
26+
compiler.hooks.beforeRun.tapPromise(
27+
"CleanerPlugin",
28+
this.runCleaner.bind(this)
29+
);
30+
compiler.hooks.watchRun.tapPromise(
31+
"CleanerPlugin",
32+
this.runCleaner.bind(this)
33+
);
34+
}
35+
36+
runCleaner(compiler, callback) {
37+
return del(this.patterns, this.cleanerOptions);
38+
}
39+
}
40+
41+
module.exports = CleanerPlugin;

lib/WebpackOptionsApply.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ const RequireIncludePlugin = require("./dependencies/RequireIncludePlugin");
4141

4242
const WarnNoModeSetPlugin = require("./WarnNoModeSetPlugin");
4343

44+
const CleanerPlugin = require("./CleanerPlugin");
45+
4446
const EnsureChunkConditionsPlugin = require("./optimize/EnsureChunkConditionsPlugin");
4547
const RemoveParentModulesPlugin = require("./optimize/RemoveParentModulesPlugin");
4648
const RemoveEmptyChunksPlugin = require("./optimize/RemoveEmptyChunksPlugin");
@@ -193,6 +195,12 @@ class WebpackOptionsApply extends OptionsApply {
193195
throw new Error("Unsupported target '" + options.target + "'.");
194196
}
195197

198+
if (options.output.clean)
199+
new CleanerPlugin(
200+
options.output.clean === true
201+
? [compiler.outputPath.replace(/\/$/, "") + "/**/*"]
202+
: options.output.clean
203+
).apply(compiler);
196204
if (options.output.library || options.output.libraryTarget !== "var") {
197205
let LibraryTemplatePlugin = require("./LibraryTemplatePlugin");
198206
new LibraryTemplatePlugin(

lib/WebpackOptionsDefaulter.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,18 @@ class WebpackOptionsDefaulter extends OptionsDefaulter {
8888
}
8989
});
9090

91+
this.set("output.clean", "call", (value, options) => {
92+
if (!value) return false;
93+
if (typeof value === "boolean") {
94+
return value;
95+
} else if (typeof value === "string") {
96+
return [value];
97+
} else if (Array.isArray(value)) {
98+
return value;
99+
} else {
100+
return Object.assign({}, value);
101+
}
102+
});
91103
this.set("output.filename", "[name].js");
92104
this.set("output.chunkFilename", "make", options => {
93105
const filename = options.output.filename;

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
"ajv": "^6.1.0",
1111
"ajv-keywords": "^3.1.0",
1212
"chrome-trace-event": "^0.1.1",
13+
"del": "^3.0.0",
1314
"enhanced-resolve": "^4.0.0",
1415
"eslint-scope": "^3.7.1",
1516
"loader-runner": "^2.3.0",

schemas/WebpackOptions.json

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -327,6 +327,41 @@
327327
"type": "string",
328328
"absolutePath": false
329329
},
330+
"clean": {
331+
"description": "Enable auto deletion of files from `output.path` directory.",
332+
"anyOf": [
333+
{
334+
"description": "`true` enables auto deletion of files from `output.path`.",
335+
"type": "boolean"
336+
},
337+
{
338+
"description": "Pattern by which files will be deleted (see `del` package).",
339+
"type": "string"
340+
},
341+
{
342+
"description": "Array pattern by which files will be deleted (see `del` package).",
343+
"type": "array"
344+
},
345+
{
346+
"type": "object",
347+
"additionalProperties": false,
348+
"properties": {
349+
"patterns": {
350+
"description": "Array pattern by which files will be deleted (see `del` package).",
351+
"items": {
352+
"description": "Pattern by which files will be deleted (see `del` package).",
353+
"type": "string"
354+
},
355+
"type": "array"
356+
},
357+
"options": {
358+
"description": "Cleaner options (see `del` package).",
359+
"type": "object"
360+
}
361+
}
362+
}
363+
]
364+
},
330365
"webassemblyModuleFilename": {
331366
"description": "The filename of WebAssembly modules as relative path inside the `output.path` directory.",
332367
"type": "string",

test/ConfigTestCases.test.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ describe("ConfigTestCases", () => {
101101
} catch (e) {
102102
// ignored
103103
}
104+
if (testConfig.beforeExecute) testConfig.beforeExecute(options);
104105

105106
webpack(options, (err, stats) => {
106107
if (err) {
@@ -258,7 +259,7 @@ describe("ConfigTestCases", () => {
258259
);
259260
if (exportedTests.length < filesCount)
260261
return done(new Error("No tests exported by test case"));
261-
if (testConfig.afterExecute) testConfig.afterExecute();
262+
if (testConfig.afterExecute) testConfig.afterExecute(options);
262263
const asyncSuite = describe("exported tests", () => {
263264
exportedBeforeEach.forEach(beforeEach);
264265
exportedAfterEach.forEach(afterEach);
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
const path = require("path");
2+
3+
it("should not find old file", function() {
4+
var fs = require("fs");
5+
expect(() =>
6+
fs.readFileSync(path.join(__dirname, "file.js"), "utf-8")
7+
).not.toThrow();
8+
});
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
const mkdirp = require("mkdirp");
2+
const fs = require("fs");
3+
const path = require("path");
4+
5+
module.exports = {
6+
beforeExecute(options) {
7+
const outputPath = options.output.path;
8+
9+
mkdirp.sync(outputPath);
10+
fs.writeFileSync(path.join(outputPath, "file.js"), "module.exports = 1;");
11+
}
12+
};
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
module.exports = {
2+
output: {
3+
clean: false
4+
},
5+
node: {
6+
__dirname: false,
7+
__filename: false
8+
}
9+
};
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
const path = require("path");
2+
3+
it("should not find old file", function() {
4+
var fs = require("fs");
5+
expect(() =>
6+
fs.readFileSync(path.join(__dirname, "file.js"), "utf-8")
7+
).toThrow();
8+
});

0 commit comments

Comments
 (0)