Skip to content

Instantly share code, notes, and snippets.

@Jessidhia
Last active August 7, 2016 13:30
Show Gist options
  • Save Jessidhia/f1e556d0dc758f6fb207c7442efad138 to your computer and use it in GitHub Desktop.
Save Jessidhia/f1e556d0dc758f6fb207c7442efad138 to your computer and use it in GitHub Desktop.
// Removes all files from outputPath that are not in webpack's output
// @this webpack
function cleanArtifacts () {
const result = new Set()
// globs to ignore when deleting
const cleanIgnore = [ '.gitignore' ]
this.plugin('done', () => {
if (result.size > 0) {
// eslint-disable-next-line no-console
console.error(
`\rOutdated artifacts deleted:\n\n${
Array.from(result).map(artifact => `\t${artifact}`).join('\n')
}\n`
)
result.clear()
}
})
const prefix = `${outputPath}/`
// const recursiveReaddirAsync =
// require('bluebird').promisify(require('recursive-readdir'))
this.plugin('after-emit', (compilation, callback) =>
Promise.resolve(compilation.getStats())
.then(stats =>
Promise.all([
// the first argument is not a promise, so it's just like Promise.resolve
new Set(stats.toJson().assets.map(asset => asset.name)),
// this is, so the Promise.all will await on it
recursiveReaddirAsync(outputPath, cleanIgnore)
])
)
// node4 doesn't have destructuring :(
// .then(([assets, files]) => ...)
.then(results => {
const assets = results[0]
const files = results[1]
return files.map(file => {
const artifact = file.replace(prefix, '')
if (!assets.has(artifact)) {
return fs.unlinkAsync(file)
.then(() => { result.add(artifact); return })
}
// the .map results in an array of either undefined
// or Promises that resolve to undefined
})
})
// await on all unlinks
.then(unlinks => Promise.all(unlinks))
// the next .then's argument is just array of undefined,
// but we don't care about the result anyway, just that it resolved :D
.then(() => callback(), err => callback(err))
)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment