Path Resolution Behavior
Yes, the resolution root adjusts automatically when using pug.renderFile(). By default, Pug uses file-relative resolution: any include or extends directive is resolved relative to the directory of the template file currently being processed, not the process working directory (CWD) or the entry-point template.
Likely Cause of ENOENT
An ENOENT error typically occurs in one of two scenarios:
- Path Mismatch: A template in a subdirectory (e.g.,
/views/admin/dashboard.pug) attempts to include a partial using a path that only works from the root (e.g., include partials/nav instead of include ../partials/nav).
- Missing Context: When using
pug.render() with a string instead of a file, Pug has no physical directory to reference. Without a filename or basedir option, all relative includes will fail.
Configuration and Overrides
Custom Path Resolvers
Pug does not provide a pluggable resolver function. However, you can control resolution without modifying source files using these options:
basedir: A string that overrides file-relative resolution. All paths are resolved relative to this directory.
includePaths: An array of strings. If a file isn't found relative to the template or basedir, Pug searches these directories in order.
Express Integration
When using Express, app.set('views', 'path/to/views') configures the basedir for the Pug engine. This effectively shifts the resolution logic: includes are often resolved relative to the views root rather than the individual template file, which can cause ENOENT if your templates rely on relative ../ navigation.
Verification Steps
To diagnose the current resolution scope, verify your setup with these scoped checks:
- Check Pug Version: Ensure you are on Pug 3.x, as behavior can vary slightly from 2.x.
- Test File-Relative Logic:
// Structure: views/pages/index.pug -> include ../partials/head.pug
const pug = require('pug');
pug.renderFile('views/pages/index.pug', (err, html) => {
if (err) console.error(err); // If ENOENT, check the resolved path in the error object
});
- Test Basedir Override:
// Forces resolution relative to 'views' regardless of template depth
pug.renderFile('views/pages/index.pug', { basedir: 'views' });
Diagnostic Detail Needed: Are you rendering via pug.renderFile(), pug.render() (string), or through res.render() in Express? The recommendation changes based on whether the engine is managing the file system lookup or a framework is passing a pre-loaded string.