Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support asynchronous configuration callback function in .elventy.js #1994

Closed
kleinfreund opened this issue Oct 3, 2021 · 1 comment
Closed

Comments

@kleinfreund
Copy link
Contributor

kleinfreund commented Oct 3, 2021

Is your feature request related to a problem? Please describe.

I’m updating dependencies in my project and ran into a problem. I use make-synchronous to register an asynchronous universal filter (which isn’t supported by Eleventy, see #518). The package make-synchronous was updated to be distributed as an ES module and can no longer be imported using require("make-synchronous"). To import it in a CommonJS module (which .eleventy.js is), one can use dynamic imports instead (i.e. import("make-synchronous")). However, I can’t await the dynamic import in the callback function exported in the .eleventy.js because it itself cannot be asynchronous either.

Describe the solution you'd like

One way to solve this would be allowing asynchronous callback functions to be exported as the Eleventy configuration. Then, one could await import("…") stuff inside of it. I can see this being useful for many other things in modern web development.

Describe alternatives you've considered

Alternatively, and that would certainly be a much bigger change, Eleventy configurations could simply™ be ES modules and so one could natively import ES module packages. Of course, ideally, Eleventy would support both asynchronous configuration callback functions and the configuration file being an ES module. 🤓

Additional context

I wouldn’t need this issue to be solved if Eleventy were to support asynchronous universal filters which as far as I understand is difficult to do because not all template languages support asynchronous filters themselves. I’m not sure if this can be abstracted away.


Implementation challenge of allowing asynchronous configuration callback functions

Some notes made while trying to implement this myself

The big challenge of implementing support for asynchronous configuration callback functions is the massive amount of changes this would result in due to need to await internal calls.

In particular, one would have to await the call to localConfig(this.userConfig) in eleventy/src/TemplateConfig.js. This causes several methods in TemplateConfig.js alone to become asynchronous which then cascades into other files.

After spending a couple of hours chasing one async/await change after another between tests and inter-connected depending core functionalities, I’ve come to the realization that this change can only be implemented in a reasonable fashion if one can avoid constantly calling TemplateConfig::getConfig (this routine is what’s calling mergeConfig which has to resolve an asynchronous configuration callback function). About 12 files call TemplateConfig::getConfig(), but I think the majority of those calls primarily cares for the configuration’s content and not for remerging it.

Also, unfortunately, because some of the public configuration functions like setPathPrefix rely on re-merging the configuration which would now always be an asynchronous function, these public configuration functions would turn asynchronous as well; thus, they would need to be awaited and that’s a breaking change.

@kleinfreund
Copy link
Contributor Author

I just realized this is a duplicate of #614.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant