Pug 3.x cache invalidation for included partials after template edits
0 reputation · 16 May 2023, 06:30 UTC
0 reputation · 16 May 2023, 06:30 UTC
Pug 3.x compiles templates into cached functions keyed by the entry file path, but the cache validation only checks the entry template's modification time. When a template uses include or extends, changes to those dependency files do not trigger recompilation in production mode where view cache is enabled. This creates a divergence between development (where cache: false recompiles everything) and production behavior that surfaces during integration testing with mock data.
The goal is to understand whether a test suite can reliably detect stale partial output without restarting the process or disabling caching globally. Constraints include: Express automatically enables view cache in production via NODE_ENV, direct pug.renderFile() calls ignore this setting unless explicitly passed { cache: true }, and the basedir option creates separate cache entries that may mask the issue in test configurations.
include or extends dependencies change?pug.cache export?32275 reputation · 16 May 2023, 14:51 UTC
In Pug 3.0.2+, the cache invalidation logic remains tied exclusively to the mtime (modification time) of the entry template. When cache: true is enabled, Pug checks whether the entry file has changed; however, it does not recursively track the modification times of files referenced via include or extends. Consequently, edits to partials will not trigger a recompilation of the parent template in production mode. This is the likely explanation for the divergence you see between development and production, though it is worth verifying against your exact Pug version, since earlier 3.x releases may differ.
The pug.cache export was removed in Pug 3.x. The internal LRU cache is no longer exposed via a public API, so there is no built-in method to programmatically inspect or clear the default internal cache without restarting the Node.js process.
To maintain production-level performance while gaining control over partial invalidation, replace the default boolean cache setting with a custom cache object. Pug's compileFile and renderFile accept a cache option that can be a Map or any object implementing a similar get/set interface, as described in the Pug 3.x API reference.
Implementation Steps:
Map or a bounded LRU cache instance shared across all rendering calls.cache: true, pass the instance to pug.renderFile() or your Express view settings.const pug = require('pug');
const customCache = new Map();
// Render using the custom cache
const html = pug.renderFile('views/index.pug', {
cache: customCache,
basedir: 'views/'
});
// To force recompilation of partials, clear the cache
function invalidateTemplates() {
customCache.clear();
}To verify this in a test suite, render a page containing a partial, modify the partial file on disk, and render again — the output should remain stale. After calling customCache.clear(), the subsequent render should reflect the changes. You can also instrument the cache object with logging on get, set, and delete to confirm entries are stored and removed as intended.
Caveats: All parts of the application must share the same cache instance, or stale entries will persist. An unbounded Map can grow memory usage, so prefer a bounded LRU in long-running processes. If using Express, note that app.set('view cache', true) manages its own layer, so integration tests should confirm the custom cache is actually consulted. The basedir option also matters: different basedir values create different cache keys for the same file, which can mask stale-output bugs in test configurations.
One diagnostic detail that changes the recommendation: are you rendering via Express's app.render()/res.render(), or calling pug.renderFile() directly? With direct calls you control the options object yourself; with Express you must coordinate with its view engine settings, which changes where the custom cache is injected.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.