Skip to content

Commit

Permalink
fix(worker): workaround webpack4 fs write caching
Browse files Browse the repository at this point in the history
Ref #126
  • Loading branch information
jbedard committed Nov 8, 2023
1 parent 18ac3b0 commit 7623f19
Showing 1 changed file with 36 additions and 3 deletions.
39 changes: 36 additions & 3 deletions webpack/private/webpack_worker.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,10 +88,43 @@ class WebpackWorker extends WebpackCLI {
this.compiler = await super.createCompiler(options, cb)
this.options = options

// The output directory will be cleaned between runs, webpack assumes the output directory will not be modified:
// Webpack5: https://github.com/webpack/webpack/blob/v5.36.2/lib/Compiler.js#L783-L788
// The output directory will be cleaned between runs, however webpack assumes the
// output directory will not be modified and caches the file system state.

// Webpack5: clear the "previously emitted" cache
// https://github.com/webpack/webpack/blob/v5.36.2/lib/Compiler.js#L783-L788
if (this.compiler._assetEmittingPreviousFiles) {
this.compiler.hooks.afterEmit.tap("rules_webpack", () => this.compiler._assetEmittingPreviousFiles.clear())
this.compiler.hooks.afterEmit.tap("rules_webpack", this.compiler._assetEmittingPreviousFiles.clear());
} else {
// Webpack4: patch the compiler to ensure all assets are re-written on each completion
const fsCache = new Map()
const fsWrites = new Set()

// Clear the "writes" before compilation.
this.compiler.hooks.emit.tap('rules_webpack', () => fsWrites.clear())

// Cache all file write operations throughout compilation
const originalWriteFile = this.compiler.outputFileSystem.writeFile
this.compiler.outputFileSystem.writeFile = function workerWriteFile(p, data, cb) {
fsCache.set(p, data)
fsWrites.add(p)
return originalWriteFile.apply(this, arguments)
}

// Ensure all past write operations are rewritten.
this.compiler.hooks.afterEmit.tap('rules_webpack', () => {
for (const [p, data] of fsCache.entries()) {
if (!fsWrites.has(p)) {
// TODO: wait for async write?
originalWriteFile.call(this.compiler.outputFileSystem, p, data, () => {})
}
}

// Clear the writes-done for the next compilation.
fsWrites.clear()
})

// TODO: clear entries when no longer outputted by webpack
}
}
}
Expand Down

0 comments on commit 7623f19

Please sign in to comment.