After I found how I could have valid JavaScript files with the front matter block, I rapidly come across a new challenge: how can I access non-string Eleventy data in JavaScript with Nunjucks? π€
It may seem easy at first, but the difficulty resides in that I still want to be able to lint my *.js.njk
as JavaScript⦠Let me show you an example:
/*---
html: "Hello world!"
tags:
- eleventy
- javascript
- html
---*/
import { LitElement, html } from 'lit-element';
class Post extends LitElement {
render() {
// Nunjunks variables are valid JavaScript inside a string
const body = `{{ post.html }}`;
// But outside, it will produce an error:
// "Uncaught SyntaxError: Unexpected token '{'"
const tags = {{ post.tags }};
return html`
${tags}
${body}
`;
}
}
window.customElements.define('br-post', Post);
Oops, I needed to find a workaround to that problem or my quick prototype to test if I could join Eleventy and Web Components will appear to be unsustainableβ¦ π±
Fortunately, you may think that if I am writing this post, there is a good chance that I found a solution. And you are right. π How? By using another time JavaScript comments. Let me show you how I came to that conclusion:
// Not valid JavaScript code :(
const anArray = {{ post.tags }};
const anObject = {{ post.author }};
// could be converted into
const anArray = [
// {{ post.tags }}
];
const anObject = {
// {{ post.author }}
};
// and it would be valid, but our data would be inside JavaScript comments...
// Maybe a shortcode will help us transform our code
const anArray = [
// {{ toJavaScriptArray post.tags }}
];
const anObject = {
// {{ toJavaScriptObject post.author }}
};
// to the content of the array *on a subsequent line*
const anArray = [
//
"eleventy", "javascript", "html"
];
const anObject = {
//
firstName: "Benjamin", lastName: "Rancourt"
};
// Oh oh, I think we may be into something! ;)
This solution may insert some blank comments, but if you minify your files before shipping them to production, they surely should be removed. π§
The shortcodes needed to do that are, in their simple forms, easy to implement:
const stringify = (object) => JSON.stringify(object);
const slice = (string) => string.slice(1, string.length - 1);
const decommentObject = (object) => `
${slice(stringify(object)}
`;
eleventyConfig.addShortcode('toJavaScriptArray', decommentObject);
eleventyConfig.addShortcode('toJavaScriptObject', decommentObject);
You could add and adapt these lines, but I recommend that you check on the @sherby/eleventy-plugin-javascript NPM package. I have included in it more robust functions to help you write JavaScript code with Eleventy. I also add some functionalities that I leave you to take a look at. π
To use this plugin, you only need to install the dependency with npm
npm install @sherby/eleventy-plugin-javascript --save-dev
@sherby/eleventy-plugin-javascript
module as a development dependency.and to add the plugin into your Eleventy config file (.eleventy.js
)
const eleventyPluginJavascript = require("@sherby/eleventy-plugin-javascript");
module.exports = (eleventyConfig) => {
eleventyConfig.addPlugin(eleventyPluginJavascript);
};
Let me know if this plugin helps you! π¬