11ty / eleventy-plugin-bundle

Little bundles of code, little bundles of joy.
70 stars 3 forks source link

getBundleFileUrl Crashes When Bundling CSS from NJK Macro #17

Open cekstedt opened 1 year ago

cekstedt commented 1 year ago

It appears that trying to bundle css from a nunjucks macro file using getBundleFileUrl results in a fatal error.

Here is the stacktrace (<project folder> substituted for actual pc path):

[11ty] Problem writing Eleventy templates: (more in DEBUG output)
[11ty] 1. Having trouble rendering njk template ./index.njk (via TemplateContentRenderError)
[11ty] 2. (./index.njk)
[11ty]   EleventyShortcodeError: Error with Nunjucks paired shortcode `css` (via Template render error)
[11ty] 3. Cannot read properties of undefined (reading 'url') (via Template render error)
[11ty]
[11ty] Original error stack trace: TypeError: Cannot read properties of undefined (reading 'url')
[11ty]     at Object.addContent (<project folder>\node_modules\@11ty\eleventy-plugin-bundle\eleventy.shortcodes.js:24:39)
[11ty]     at Object.<anonymous> (<project folder>\node_modules\@11ty\eleventy\src\BenchmarkGroup.js:32:26)
[11ty]     at <project folder>\node_modules\@11ty\eleventy\src\Engines\Nunjucks.js:283:31
[11ty]     at eval (eval at _compile (<project folder>\node_modules\nunjucks\src\environment.js:527:18), <anonymous>:32:1)
[11ty]     at PairedShortcodeFunction.run (<project folder>\node_modules\@11ty\eleventy\src\Engines\Nunjucks.js:251:9)
[11ty]     at Template.root [as rootRenderFunc] (eval at _compile (<project folder>\node_modules\nunjucks\src\environment.js:527:18), <anonymous>:29:31)
[11ty]     at Template.getExported (<project folder>\node_modules\nunjucks\src\environment.js:508:10)
[11ty]     at eval (eval at _compile (<project folder>\node_modules\nunjucks\src\environment.js:527:18), <anonymous>:14:5)
[11ty]     at createTemplate (<project folder>\node_modules\nunjucks\src\environment.js:254:9)
[11ty]     at handle (<project folder>\node_modules\nunjucks\src\environment.js:265:11)
[11ty] Wrote 0 files in 0.06 seconds (v2.0.1)

Here is my project structure:

package.json:

{
  "devDependencies": {
    "@11ty/eleventy": "^2.0.1",
    "@11ty/eleventy-plugin-bundle": "^1.0.4"
  }
}

.eleventy.js:

const bundlerPlugin = require("@11ty/eleventy-plugin-bundle");

module.exports = function(eleventyConfig) {
    eleventyConfig.addPlugin(bundlerPlugin);
};

index.nkj:

<link rel="stylesheet" href="{% getBundleFileUrl "css" %}">
{% from "foo.njk" import foo %}
{{ foo({content: "FOO"}) }}

_includes/foo.nkj:

{% macro foo(params) %}
    <p>{{ params.content }}</p>
{% endmacro %}

{% css %}
    p {background-color: purple;}
{% endcss %}

When I comment out the {% css %} block in foo.njk, then the project renders with no errors (albeit without any css).

I am still very green in 11ty, so hopefully I am just missing something obvious. Thank you for your time and assistance.

bennypowers commented 1 year ago

I have a similar issue when trying to print syntax-highlighted html snippets using markdown fenced code blocks in a webc,md file.

Example markdown source

<code-tabs> and <code-tab> have webc definitions in scope. Also note the use of webc:raw and webc:keep which doesn't seem to have any effect on the error). With sources like this, eleventy --watch --serve builds on initial run, but crashes with the below error when saving the markdown file.

Let's define a component which performs the following tasks:
1. queries for messages
2. subscribes to any new messages
3. when new messages arrive, integrate them with the cached messages from the query.

We'll accomplish this by calling `subscribeToMore` on our element once it's 
connected to the DOM, passing in an `updateQuery` function to define the merge 
for new data:

<code-tabs collection="libraries" default-tab="lit">
  <code-tab @tab="$data.codeTabs.html">

  ```html
  <apollo-client id="messages-client">
    <apollo-query id="messages-query">
      <script webc:keep type="application/graphql" src="Messages.query.graphql"></script>
      <template webc:raw>
        <link webc:keep rel="stylesheet" href="messages.css">
        <ol>
          <template type="repeat" repeat="{{ data.messages ?? [] }}">
            <li>
              <h4>
                <time datetime="{{ date }}">{{ formatDate(item.date) }}</time>
                <span class="user">{{ item.user }} said:</span>
              </h4>
              <p>{{ item.message }}</p>
            </li>
          </template>
        </ol>
      </template>
    </apollo-query>
  </apollo-client>
  ```

  </code-tab>
</code-tabs>

error:

[11ty] Problem writing Eleventy templates: (more in DEBUG output)
[11ty] 1. Having trouble rendering md template ./docs/guides/usage/subscriptions/index.webc.md (via TemplateContentRenderError)
[11ty] 2. Cannot read properties of undefined (reading 'url') (via TypeError)
[11ty] 
[11ty] Original error stack trace: TypeError: Cannot read properties of undefined (reading 'url')
[11ty]     at Object.addContent (/home/bennyp/Developer/apollo-elements/node_modules/@11ty/eleventy-plugin-bundle/eleventy.shortcodes.js:25:39)
[11ty]     at Object.css (/home/bennyp/Developer/apollo-elements/node_modules/@11ty/eleventy/src/BenchmarkGroup.js:32:26)
[11ty]     at Object.<anonymous> (/home/bennyp/Developer/apollo-elements/node_modules/@11ty/eleventy-plugin-webc/src/eleventyWebcTemplate.js:155:37)
[11ty]     at async Template._render (/home/bennyp/Developer/apollo-elements/node_modules/@11ty/eleventy/src/TemplateContent.js:514:22)
[11ty]     at async Template._getLink (/home/bennyp/Developer/apollo-elements/node_modules/@11ty/eleventy/src/Template.js:251:24)
[11ty]     at async Template.getOutputPath (/home/bennyp/Developer/apollo-elements/node_modules/@11ty/eleventy/src/Template.js:336:16)
[11ty]     at async Object.<anonymous> (/home/bennyp/Developer/apollo-elements/node_modules/@11ty/eleventy/src/Template.js:586:25)
[11ty]     at async ComputedData._setupDataEntry (/home/bennyp/Developer/apollo-elements/node_modules/@11ty/eleventy/src/ComputedData.js:90:19)
[11ty]     at async ComputedData.processRemainingData (/home/bennyp/Developer/apollo-elements/node_modules/@11ty/eleventy/src/ComputedData.js:111:5)
[11ty]     at async ComputedData.setupData (/home/bennyp/Developer/apollo-elements/node_modules/@11ty/eleventy/src/ComputedData.js:101:5)

in which case the state of the shortcode function in eleventy.shortcodes.cjs:24 is

{ name: 'css', content: [], bucket: 'default', urlOverride: '' }

proposed fix:

// e.g. `css` shortcode to add code to page bundle
// These shortcode names are not configurable on purpose (for wider plugin compatibility)
eleventyConfig.addPairedShortcode(name, function addContent(content, bucket, urlOverride) {
  let url = urlOverride || this.page?.url;
    if (url) {
      managers[name].addToPage(url, content, bucket);
    }
  return "";
});

I used this patch with patch-package to unblock myself while this issue is open:

diff --git a/node_modules/@11ty/eleventy-plugin-bundle/eleventy.shortcodes.js b/node_modules/@11ty/eleventy-plugin-bundle/eleventy.shortcodes.js
index 6bb73b8..56260c7 100644
--- a/node_modules/@11ty/eleventy-plugin-bundle/eleventy.shortcodes.js
+++ b/node_modules/@11ty/eleventy-plugin-bundle/eleventy.shortcodes.js
@@ -21,8 +21,10 @@ module.exports = function(eleventyConfig, options = {}) {
        // e.g. `css` shortcode to add code to page bundle
        // These shortcode names are not configurable on purpose (for wider plugin compatibility)
        eleventyConfig.addPairedShortcode(name, function addContent(content, bucket, urlOverride) {
-           let url = urlOverride || this.page.url;
-           managers[name].addToPage(url, content, bucket);
+           let url = urlOverride || this.page?.url;
+      if (url) {
+        managers[name].addToPage(url, content, bucket);
+      }
            return "";
        });
    });
cekstedt commented 1 year ago

@bennypowers, your patch does indeed suppress the error, but the CSS is still not being rendered from nunjucks macro files. I suspect that the macro's {% import %} tag isn't being recognized by the bundler like an {% include %} tag is.

JanDW commented 8 months ago

Just wanted to report I also ran into this issue, using {% js %} in a nunjucks macro and using {% getBundleFileUrl "js" %} and {% getBundle "js" %}