liquidjs: Can’t find layout template in v9.26.0 (using Eleventy v1.0.0-canary.44)

Updating the dependencies for my Eleventy-based website (currently using v1.0.0-canary.44), and updating LiquidJS from v9.25.1 to v9.26.0 generates the following error:

[11ty] Problem writing Eleventy templates: (more in DEBUG output)
[11ty] > Having trouble writing template: www/bookmarks/2010/06/star_wars_ipad/index.html

`TemplateWriterWriteError` was thrown
[11ty] > ENOENT: Failed to lookup "default" in "src/includes", file:./src/layouts/bookmark.liquid, line:1, col:1

`RenderError` was thrown
[11ty] > ENOENT: Failed to lookup "default" in "src/includes"

`Error` was thrown:
[11ty]     Error: ENOENT: Failed to lookup "default" in "src/includes"
        at Liquid.lookupError (/Users/paulrobertlloyd/Sites/paulrobertlloyd-v4/node_modules/liquidjs/dist/liquid.node.cjs.js:3121:21)
        at Liquid._parseFile (/Users/paulrobertlloyd/Sites/paulrobertlloyd-v4/node_modules/liquidjs/dist/liquid.node.cjs.js:3063:20)
        at _parseFile.next (<anonymous>)
        at reduce (/Users/paulrobertlloyd/Sites/paulrobertlloyd-v4/node_modules/liquidjs/dist/liquid.node.cjs.js:1737:25)
        at async TemplateLayout.render (/Users/paulrobertlloyd/Sites/paulrobertlloyd-v4/node_modules/@11ty/eleventy/src/TemplateLayout.js:160:25)
        at async Template.renderPageEntry (/Users/paulrobertlloyd/Sites/paulrobertlloyd-v4/node_modules/@11ty/eleventy/src/Template.js:781:17)
        at async /Users/paulrobertlloyd/Sites/paulrobertlloyd-v4/node_modules/@11ty/eleventy/src/Template.js:803:21
        at async Promise.all (index 0)
        at async Promise.all (index 9)
        at async Eleventy.executeBuild (/Users/paulrobertlloyd/Sites/paulrobertlloyd-v4/node_modules/@11ty/eleventy/src/Eleventy.js:958:13)

As to some background, I have Eleventy set up to look for includes and layouts in separate specified folders. At the top of my templates, I extend a common default.liquid template, i.e.:

{%- layout 'default' -%}
{%- block 'main' -%}
  …
{%- endblock -%}

Eleventy looks for this default template in ./src/layouts/, but since updating to the latest version of LiquidJS, it appears to now be looking for it in /src/includes/. Reverting to v9.25.1 of LiquidJS prevents this error from occurring. Looks like there was a bit of refactoring in the most recent release, which may be the culprit!

Happy to provide more details if required. My site’s code can be found at https://github.com/paulrobertlloyd/paulrobertlloyd-v4

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Comments: 31 (28 by maintainers)

Commits related to this issue

Most upvoted comments

The fix for this has made it into Eleventy master and will ship with 1.0.0-beta.5.

Tracking at https://github.com/11ty/eleventy/issues/1995

Thank you @harttle for the PR!

I appreciate the movement here but I do think this was a semver breaking change, right?

Are we not allowed to use options or options.root in the third argument to render any more?

Should this have been bundled with a major version API change?

Can confirm that using layouts and partials options in place of root now works as of v9.28.0 🎉

Oooh, I understand. I can use my own Liquid instance with 11ty again and use these new options, certainly. Might me doing so be a good way to test this is a good approach, as well?

Supporting customize LiquidOptions on .render() have 10%-50% performance impact (with cache enabled, since we care about production perf only). After some investigation, the bottleneck is customizing LiquidOptions will postpone cache validation. For example:

  • options being static (root, cache, etc.): by {% render "foo" %}, we can directly check cache with key "foo".
  • options being determined when render: we need resolve "foo" from filesystem against currrent root, then check cache with key like /www/includes/foo.liquid.
    • Resolving a file from filesystem is very costly, we even support npm style resolving that makes it even worse. Contributs 80% of regression.
    • Passing options around in parse*(), render*(), parseAndRender(), tag implementations is also contributing 10%-20% of regression.

I think we can do this differently to allow @paulrobertlloyd 's scenario and achieve good perf at the same time. Maybe:

  • let 11ty have different liquid engine instances for different root configs.
  • support root for includes and layout natively in LiquidJS

The second approach maybe better, but still need LiquidJS make changes and 11ty then make corresponding changes (move these root configs from render to new Liquid). And I want to remove opts from .render() for good, not sure whether there’s elsewhere 11ty depends on it. @zachleat how do you think?