-
-
Notifications
You must be signed in to change notification settings - Fork 501
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
addPreprocessor
doesn't work together with keyed addExtension
#3433
Comments
Hmm. Agree that this is a bug. Currently we handle template types that read file content separate from dynamic The most correct way to fix this is to restructure JavaScript templates to import during the file This is the place where it forks:
I’ve pushed a branch that has the fixes in place but I’m nervous to make this change 😅 https://github.com/11ty/eleventy/compare/issue-3433?expand=1 |
So I tried the changes from e221e19 locally by editing node_modules, but it still doesn't seem to fix the issue. I get the same SyntaxError in Node, and the Diffdiff --git a/src/Engines/JavaScript.js b/src/Engines/JavaScript.js
index b20db4e0dd43f8305aba431989a4f67d404017cd..568bff12a4c8aac24020f89528d586a6b04165e1 100644
--- a/src/Engines/JavaScript.js
+++ b/src/Engines/JavaScript.js
@@ -123,6 +123,10 @@ class JavaScript extends TemplateEngine {
return false;
}
+ useJavaScriptImport() {
+ return true;
+ }
+
async getExtraDataFromFile(inputPath) {
let inst = await this.getInstanceFromInputPath(inputPath);
return getJavaScriptData(inst, inputPath);
diff --git a/src/Engines/TemplateEngine.js b/src/Engines/TemplateEngine.js
index 05050b68b043a9a7d8383fbb7d3944642f339091..75937abe974b1fca36e75ff3ef0415dfed02ffbd 100644
--- a/src/Engines/TemplateEngine.js
+++ b/src/Engines/TemplateEngine.js
@@ -116,6 +116,10 @@ class TemplateEngine {
return true;
}
+ useJavaScriptImport() {
+ return false;
+ }
+
getExtraDataFromFile() {
return {};
}
diff --git a/src/TemplateContent.js b/src/TemplateContent.js
index 143d958282d43348c31b5f0d970f4b03d36d567c..2e00ca60fc8d42797b9e316227506b4221ac8a86 100644
--- a/src/TemplateContent.js
+++ b/src/TemplateContent.js
@@ -184,6 +184,12 @@ class TemplateContent {
let content = await this.inputContent;
if (content || content === "") {
+ if (this.engine.useJavaScriptImport()) {
+ return {
+ data: {},
+ content,
+ };
+ }
let options = this.config.frontMatterParsingOptions || {};
let fm;
try {
@@ -266,6 +272,14 @@ class TemplateContent {
async getInputContent() {
let tr = await this.getTemplateRender();
+
+ if (
+ tr.engine.useJavaScriptImport() &&
+ typeof tr.engine.getInstanceFromInputPath === "function"
+ ) {
+ return tr.engine.getInstanceFromInputPath(this.inputPath);
+ }
+
if (!tr.engine.needsToReadFileContents()) {
return "";
} |
Hmmmmmm—can you supply your test case? Here’s what I tested with (with the changes) and it had https://gist.github.com/zachleat/c54611d86ab2e5c521802b211904eb65 |
Ah, I mentioned this in the issue description (see "Note 2"). Here's a proper link to the branch which fails in Deno: https://github.com/mayank99/11ty-jsx-deno/tree/preprocessor One difference I noticed from your gist is that I also pass a
I also have a repro case for Node (without Deno) in the issue description. That one continues to fail with |
Ah—my apologies for bad reading comprehension! 😭 I’ll have a second look! |
I pushed some additional changes to the |
Thanks for looking into this again, Zach. I have some good news and more bad news. I tested out the new changes against both repros (Node stackblitz and Deno branch) and here's what I found:
|
Hmm, we’re iterating towards something :D Let’s start with the Node behavior first: I think there is some confusion about the When you remove Worse, I wouldn’t expect returning a string from I think I would classify that as a bigger enhancement request (not a bug right now). All that said, we do use the node-retrieve-globals package to implement the Finally, I would call out the method used by Open to suggestions here (of course). |
Yeah, it sounds like I might have misunderstood what I've definitely looked into I do wonder if it would be easier to recreate the Of course, the last resort is to run the pre-transform and 11ty as two separate steps, but I was hoping to avoid producing an intermediate set of files. |
I think you can avoid a lot of abstraction complexity tied to Something like this: import path from "node:path";
import { pathToFileURL } from "node:url";
import { Module } from "node:module";
import { renderToStringAsync } from 'preact-render-to-string';
import { isValidElement } from 'preact';
import * as esbuild from 'esbuild';
let elev = new Eleventy("./test/stubs-jsx/", undefined, {
config: eleventyConfig => {
eleventyConfig.addTemplateFormats('11ty.jsx');
eleventyConfig.addPreprocessor(
'jsx-transform',
['11ty.jsx'],
async (data, content) => {
const { code } = await esbuild.transform(content, {
loader: 'jsx',
jsx: 'automatic',
jsxImportSource: 'preact',
format: 'cjs',
});
let m = new Module();
let workingDir = pathToFileURL(path.resolve(".")) + "/";
m.paths = Module._nodeModulePaths(workingDir);
m._compile(code, workingDir);
return m.exports;
}
);
eleventyConfig.addExtension(['11ty.jsx'], {
compile: function (content) {
return async (data) => {
let page = content.default();
if (isValidElement(page)) {
return `<!doctype html>${await renderToStringAsync(page)}`;
}
return content;
};
},
});
}
}); Then you could use import { noop } from "@zachleat/noop";
export default function Page() {
return (
<div>Hello!</div>
);
} |
Regardless, I’ll have a deeper think about the additional changes made in this PR and slate it for 3.0 for now: #3452 I do think we made forward progress there—thank you! |
Oh wow, TIL about |
It is an off-the-books API but everyone uses it. I originally found it via Svelte’s repo I think? Pour one out for nodejs/node#40098 |
Just published a little research on the different methods that I know of for dynamic script execution in Node.js here: https://github.com/zachleat/node-eval-modules |
Shipping with 3.0.0-alpha.21 and 3.0.0-beta.2 |
Operating system
macOS 14
Eleventy
3.0.0-alpha.19
Describe the bug
I'm trying to use
addPreprocessor
to transform the input file contents before handing it off to a template renderer.This works for simple cases, but I've hit a wall when trying to use it with
key
edaddExtension
(for aliasing an existing template language). Specifically, I'm trying to usekey: "11ty.js"
so that I can accessthis.defaultRenderer
inside thecompile
function. What happens is 11ty tries to process this template too early, before it has been transformed by the logic inaddPreprocessor
, which means it fails when it encounters unsupported syntax.Reproduction steps
See stackblitz.
Note: I'm only using
"js"
to illustrate the problem more clearly. Using"jsx"
or"tsx"
also fails, but with a different "Unknown file extension" error (possibly related to #3393 (comment)).Note 2: A similar problem also happens in Deno (which natively supports JSX/TSX), except there is no error; the
content
inaddPreprocessor
is just empty. See minimal repro.Expected behavior
addPreprocessor
should execute before setting up a template alias (i.e. usingaddExtension
withkey
). Both features should be usable together.Reproduction URL
https://stackblitz.com/edit/github-qaud3e?file=eleventyJsxPlugin.js
Screenshots
No response
The text was updated successfully, but these errors were encountered: