ejs
ejs copied to clipboard
Static includes should be resolved when `client` is true
I think static includes should be resolved during compilation so that we can have an actual standalone compiled function as the documentation says. Resolving includes on runtime defeats the purpose of pre-compilation.
When you say 'static includes,' are you talking about includes that use the old-and-deprecated preprocessor directive? It does resolve (and inline) the included code, but the intention is to remove that feature in the next major version because of the complexity it adds, and the necessary hackiness of the implementation.
The current include is a much simpler and recursively callable function, but as you point out, it resolves and compiles when the function is called. If templates are cached, all that stuff ends up in volatile memory after the first invocation though, so I haven't been able to see a significant advantage to having a precompiled function. Could you shed a little light on your particular use-case for this?
Could you shed a little light on your particular use-case for this?
I'm working on a program where I need to pre-compile templates and save them to file system, and require the pre-compiled template later. I can simply call this required function to render based on locals, without needing ejs environment.
...'static includes'
By static includes I meant includes which have arguments which are available during compile time for example:
<%- include("./index.ejs") %>
or
<%-
const template = "index.ejs";
include(template);
%>
but not for form: include(templateName), where templateName is a runtime local.
Ah, so the preprocessor directive would do the job for you, and its deprecation would seem to be a significant problem for you. Can I also ask what is the objection to using EJS as normal in your program? Just trying to understand the tradeoffs.
Can I also ask what is the objection to using EJS as normal in your program.
Do you mean using EJS without using pre-compiled templates? It's because I have multiple templates, most of which are not modified often, so I keep a pre-compiled version to improve performance.
Also, the program uses multiple template engines on different templates, so it's kind of a general structure of the Template class to pre-compile and load them from file-system.
The current preprocessor implementation is really hacky, effectively trying to do a require-style up-front specification of dependencies inside the executable code -- mixing compilation and runtime execution.
And ultimately supporting two totally different code paths for effectively the same functionality is really sloppy.
To pile on, we're planning to make the resolution and loading of templates async in the future, since the default mode of I/O in Node is async.
I would love to come up with a way to support both models -- eager/precompile, and lazy/eval-time. But the precompile functionality is not the EJS primary use-case.
Do you have any interest at helping out with an implementation that satisfies both use-cases? I am thinking about a way of specifying dependencies via an option passed into compile, effectively allowing us to side-load them and compile each of them, so the include function can potentially check for the existence of an already-loaded function to use, rather than resolving and compiling.
Does that make sense?
But the precompile functionality is not the EJS primary use-case.
Sad.
Do you have any interest at helping out with an implementation that satisfies both use-cases?
Yes I would love to help where I can.
I am thinking about a way of specifying dependencies via an option passed into
compile.
We can get the dependencies (static ones) during the parse stage though. But still would need to specify runtime dependencies the other way.
Does that make sense?
Yes it does.
I would much rather specify deps during the top-level compilation, explicitly passing all of them in. Doing it during the parse phase is problematic because that introduces yet another syntax to deal with (besides EJS-tag and JS). That is the current preprocessor style, and it's really hacky. I don't think passing in a list of filepaths with your initial compile is too high a price to get a free-standing function you can run with out EJS.