Skip to content

Nunjucks searchPaths precedence change introduced risk of cyclical includes via path name collisions #362

@robertdeniszczyc2

Description

@robertdeniszczyc2

Hi,

The issue

The Nunjucks searchPaths precedence order means there is a risk of cyclical includes which results in render errors when trying to build a project.

Why does it happen?

The issue lies where a consumer of x-govuk/govuk-eleventy-plugin has a directory structure matching the plugin, but where they might be extending layouts.

For example, if I am consuming x-govuk/govuk-eleventy-plugin and in my project I have a file layouts/post.njk which then extends the x-govuk/govuk-eleventy-plugin post.njk like:

{% extends "layouts/post.njk" %}

<!-- my extra content goes here. !-->

When I try to build the project with npx eleventy I will get the error like (redacted exact file paths):

[11ty] Problem writing Eleventy templates:
[11ty] 1. Having trouble writing to "<MY-BUILT-DIRECTORY-PATH>" from "<MY-SOURCE-DIRECTORY-PATH>" (via EleventyTemplateError)
[11ty] 2. (./_includes/layouts/post.njk)
[11ty]   RangeError: Maximum call stack size exceeded (via Template render error)

What I think is happening due to the precedence change, is when the files are being loaded into Nunjucks, the precedence change means that when my post.njk file is loaded and rendered, the extends statement now means that the build tries to extend the template from itself because the search path will match at layouts/post.njk, rather than the search first hitting the plugin version to extend from.

The searchPaths precedence reordering means the x-govuk/govuk-eleventy-plugin/layouts/*.njk files are now like reserved keyword/paths, and consumers of x-govuk/govuk-eleventy-plugin are at risk of path collisions because the file loader will try to load on the first hit, which is now potentially loading itself.

How have I tested this theory?

I've tested this is the cause through the methods:

  1. By testing locally reverting the searchPaths change and the project builds OK.
  2. Changing my project paths by renaming my layouts to be for example mypost.njk instead of post.njk to ensure there are no path collisions.
  3. Explicitly referencing the plugin layouts (like {% extends "../../node_modules/@x-govuk/govuk-eleventy-plugin/layouts/base.njk" %} ) resolves the issue

Where was the issue introduced?

The changes introduced in #354 to resolve #345

Is there an open source project I can see the issue?

Yes, the issue can be observed on this repo: UKHomeOffice/engineering-guidance-and-standards#497

What's the solution?

As per the discussion on our affected repo PR we as consumers of the plugin can get around the issue by using explicit path references where we want to use plugin layouts.

Perhaps this is something the plugin can warn for, or to be added into the docs?

Thankyou!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions