Closed ashur closed 2 years ago
@ashur Yeah, .addNunjucksAsyncFilter()
has a bit of an unexpected signature (spoiler: it uses callbacks).
/**
* @typedef {import('@11ty/eleventy/src/UserConfig')} EleventyConfig
* @typedef {ReturnType<import('@11ty/eleventy/src/defaultConfig')>} EleventyReturnValue
* @type {(eleventyConfig: EleventyConfig) => EleventyReturnValue}
*/
module.exports = function (eleventyConfig) {
const sleep = (ms=2000) => new Promise(resolve => setTimeout(resolve, ms));
https://www.11ty.dev/docs/languages/nunjucks/#asynchronous-nunjucks-filters
eleventyConfig.addNunjucksAsyncFilter( "greet", async (name, cb) => {
await sleep(3000);
return cb(null, `Hello, ${name}`);
});
return {
dir: {
input: "src",
output: "www",
}
};
};
---
# index.njk
---
<p>{{ "Dolly" | greet }}</p>
<p>Hello, Dolly</p>
> eleventy
[11ty] Writing www/index.html from ./src/index.njk
[11ty] Wrote 1 file in 3.03 seconds (v1.0.2)
Another option might be wrapping it in something like util.callbackify
:
const { callbackify } = require("node:util");
module.exports = function (eleventyConfig) {
const sleep = (ms=2000) => new Promise(resolve => setTimeout(resolve, ms));
// https://www.11ty.dev/docs/languages/nunjucks/#asynchronous-nunjucks-filters
eleventyConfig.addNunjucksAsyncFilter("greet", callbackify(async (name) => {
await sleep(1000);
if (!name) {
throw new Error("Missing a name");
}
return `Hallo, ${name}!`;
}));
return {
dir: {
input: "src",
output: "www",
}
};
};
---
# index.njk
---
<p>{{ "Dolly" | greet }}</p>
<p>{{ "" | greet }}</p>
Now this will throw an [expected] error due to that falsy name
; but now we don't need to think as much about callbacks, or promises, or error-first:
[11ty] 1. Having trouble rendering njk template ./src/index.njk (via TemplateContentRenderError) [11ty] 2. (./src/index.njk) [11ty] Error: Missing a name (via Template render error) [11ty] [11ty] Original error stack trace: Template render error: (./src/index.njk) [11ty] Error: Missing a name [11ty] at Object._prettifyError (/private/tmp/11ty-2578/node_modules/nunjucks/src/lib.js:3
@pdehaan Ugh, I'm super embarrassed I missed the callbacks part of the documentation, which are clearly described now that I'm looking again more closely 🤦
Thanks for pointing me in the right direction, and for the alternative idea! 🙏
As somebody who gets the above syntax wrong this every time I have to use async Nunjucks filters, I welcome the new 2.0 behavior:
"For projects using Eleventy 2.0, registering the filter using
addAsyncFilter
works as expected."
Summary
Using asynchronous filters registered with
addNunjucksAsyncFilter
seems to cause builds to exit prematurely.Environmnent
1.0.2
/2.0.0-canary.15
Steps
addNunjucksAsyncFilter
eleventyConfig.addNunjucksAsyncFilter( "greet", async (name) => { return
Hello, ${name}
; });npx eleventy
to build the sitenpx eleventy --serve
to start the built-in serverExpected Results
Building the site will log something like this to the terminal:
showing that the file has been built as expected. (See Attachments below for DEBUG logs.)
Starting the built-in server will log something like this to the terminal:
and continue running until the command is terminated. (See Attachments below for DEBUG logs.)
Actual Results
The file is not built:
The built-in server never starts, and the command exits automatically:
Frequency
Workaround
For projects using Eleventy 2.0, registering the filter using
addAsyncFilter
works as expected.Attachments
Debug
build
logsDebug
serve
logs