diff --git a/lib/CleanPlugin.js b/lib/CleanPlugin.js index fe092f384..ef9a57657 100644 --- a/lib/CleanPlugin.js +++ b/lib/CleanPlugin.js @@ -10,6 +10,7 @@ const validateOptions = require("schema-utils"); const schema = require("../schemas/plugins/CleanPlugin.json"); /** @typedef {import("../declarations/plugins/CleanPlugin").CleanPluginArgument} CleanPluginArgument */ + /** @typedef {import("./Compiler")} Compiler */ /** @@ -49,6 +50,29 @@ function readDir(outputFS, from) { }; } +/** + * @param {import("./util/fs").OutputFileSystem} outputFS output fs + * @param {string} directory from directory + */ +const deleteFolderRecursive = (outputFS, directory) => { + // webpack supports node 10, but node 10 does not support fs.rmdir recursive option + if (!outputFS.existsSync(directory)) { + return; + } + + for (const item of outputFS.readdirSync(directory)) { + const curPath = path.join(directory, item); + + if (outputFS.statSync(curPath).isDirectory()) { + deleteFolderRecursive(outputFS, curPath); + } else { + outputFS.unlinkSync(curPath); + } + } + + outputFS.rmdirSync(directory); +}; + class CleanPlugin { /** * @param {CleanPluginArgument} [options] options @@ -70,25 +94,24 @@ class CleanPlugin { */ apply(compiler) { let emittedOnce = false; + let outputPath; const logger = compiler.getInfrastructureLogger("webpack.Clean"); - const handleDir = (outputPath, directory) => { + const handleDir = directory => { if (this.options.dry) { logger.info(`Directory [${directory}] will be removed in non-dry mode`); } else { const abs = path.join(outputPath, directory); - if (compiler.outputFileSystem.existsSync(abs)) { - compiler.outputFileSystem.rmdirSync(abs, { - recursive: true - }); - } + deleteFolderRecursive(compiler.outputFileSystem, abs); } }; - const handleFile = (outputPath, file) => { + const handleFile = file => { if (this.options.dry) { logger.info(`Asset [${file}] will be removed in non-dry mode`); } else { const abs = path.join(outputPath, file); - compiler.outputFileSystem.unlinkSync(abs); + if (compiler.outputFileSystem.existsSync(abs)) { + compiler.outputFileSystem.unlinkSync(abs); + } } }; @@ -103,7 +126,7 @@ class CleanPlugin { return; } - const outputPath = compilation.getPath(compiler.outputPath, {}); + outputPath = compilation.getPath(compiler.outputPath, {}); if ( !compiler.outputFileSystem || @@ -128,13 +151,13 @@ class CleanPlugin { for (const file of collected.files) { if (!(file in compilation.assets)) { - handleFile(outputPath, file); + handleFile(file); } } for (const directory of collected.directories) { if (!assetsDirectories.has(directory)) { - handleDir(outputPath, directory); + handleDir(directory); } }