Eleventy Plugin for JSX Bundling
eleventy-plugin-smol-jsx-bundler is an Eleventy plugin designed to bring robust bundling capabilities to projects leveraging JSX, React, Preact, or MDX. It currently stands at version 1.2.9 and provides a lightweight, pure JavaScript approach to managing CSS, JavaScript, or HTML bundles within an Eleventy site, conceptually mirroring Eleventy's built-in bundler but with direct support for JSX syntax. This plugin allows developers to embed bundle content directly within JSX or MDX components using functions like `bundle()`, `getBundle()`, and `getBundleFile()`, offering an integrated workflow for modern frontend development within Eleventy. Its key differentiators include enabling easily unit-testable JSX files, greater extensibility, and features like deduplication of bundle content. It also supports post-processing of bundles with external tools such as PostCSS, providing flexibility for complex build pipelines. While it doesn't specify a strict release cadence, its 1.x versioning suggests a stable API and active maintenance.
Common errors
-
Error [ERR_REQUIRE_ESM]: require() of ES Module path/to/eleventy-plugin-smol-jsx-bundler.js Not supported.
cause Attempting to import the plugin using CommonJS `require()` syntax in an environment configured for ES Modules, or vice-versa.fixIf your `.eleventy.js` is an ES Module, use `import jsxBundle from 'eleventy-plugin-smol-jsx-bundler';`. If it's CommonJS, ensure the plugin itself supports CJS (though this one is primarily ESM-first) or configure Eleventy for ESM. -
TypeError: Cannot read properties of undefined (reading 'addPlugin')
cause The `eleventyConfig` object was not correctly passed to or recognized by your Eleventy configuration function, or the function is not exported correctly.fixEnsure your `.eleventy.js` file exports a default async function `export default async (eleventyConfig) => { ... }` as shown in the quickstart, and that `eleventyConfig` is the first parameter. -
ReferenceError: bundle is not defined
cause The `bundle`, `getBundle`, or `getBundleFile` functions were used in a template without being explicitly imported from `eleventy-plugin-smol-jsx-bundler`.fixAdd `import { bundle, getBundle, getBundleFile } from 'eleventy-plugin-smol-jsx-bundler';` to the top of any JSX/MDX template or component file where these functions are used.
Warnings
- gotcha Eleventy configuration files often need to be set up for ES Modules (using `import`/`export`) to correctly import and use modern plugins like `eleventy-plugin-smol-jsx-bundler`.
- gotcha Bundles created with `bundle()` are currently global to the entire Eleventy build process for a given type (e.g., 'css', 'js'). Be mindful of potential naming collisions if different components or pages try to define bundles of the same type with conflicting content, or if you expect isolated component-level bundling.
- gotcha When migrating from Eleventy's built-in bundler to `eleventy-plugin-smol-jsx-bundler`, ensure all `{% css %}`/`{% js %}` shortcodes are replaced with the equivalent `bundle()` function calls in your JSX/MDX templates.
Install
-
npm install eleventy-plugin-smol-jsx-bundler -
yarn add eleventy-plugin-smol-jsx-bundler -
pnpm add eleventy-plugin-smol-jsx-bundler
Imports
- jsxBundle
const jsxBundle = require('eleventy-plugin-smol-jsx-bundler');import jsxBundle from 'eleventy-plugin-smol-jsx-bundler';
- bundle
import bundle from 'eleventy-plugin-smol-jsx-bundler';
import { bundle } from 'eleventy-plugin-smol-jsx-bundler'; - getBundle
import { getBundle as retrieveBundle } from 'eleventy-plugin-smol-jsx-bundler';import { getBundle } from 'eleventy-plugin-smol-jsx-bundler'; - getBundleFile
const getBundleFile = require('eleventy-plugin-smol-jsx-bundler').getBundleFile;import { getBundleFile } from 'eleventy-plugin-smol-jsx-bundler';
Quickstart
// .eleventy.js
import jsxBundle from 'eleventy-plugin-smol-jsx-bundler';
import postcss from 'postcss';
import postcssNested from 'postcss-nested';
export default async (eleventyConfig) => {
eleventyConfig.addPlugin(jsxBundle);
// Example: Add a PostCSS filter to process CSS bundles
eleventyConfig.addFilter('postcss', async (content) => {
if (!content) return content;
const result = await postcss([postcssNested]).process(content, { from: undefined });
return result.css;
});
// Apply this filter to all 'css' bundles
eleventyConfig.addTransform('css', 'postcss');
};
// src/index.tsx (or .mdx)
import { bundle, getBundle, getBundleFile } from 'eleventy-plugin-smol-jsx-bundler';
// Bundle some CSS specific to this page
bundle('css', `
.page-header {
font-family: sans-serif;
color: #333;
&__title {
font-size: 2em;
text-decoration: underline;
}
}
`);
// You can also bundle JavaScript, e.g., for interactivity
bundle('js', `
console.log("Hello from Smol JSX Bundler!");
document.addEventListener('DOMContentLoaded', () => {
const button = document.getElementById('myButton');
if (button) {
button.addEventListener('click', () => alert('Button clicked!'));
}
});
`);
const MyPage = (props) => {
return (
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>My Smol JSX Bundler Page</title>
{/* Render inline CSS from the bundle */}
<style dangerouslySetInnerHTML={{ __html: getBundle('css') }} />
{/* Or link to a content-hashed CSS file */}
<link rel="stylesheet" href={getBundleFile('css', 'css')} />
</head>
<body>
<header className="page-header">
<h1 className="page-header__title">Welcome to Eleventy with JSX!</h1>
</header>
<main>
{/* Render page content, typically from markdown or other templating */}
<div dangerouslySetInnerHTML={{ __html: props.content }} />
<button id="myButton">Click Me</button>
</main>
<footer>
<p>© 2023 My Site</p>
</footer>
{/* Render inline JS from the bundle */}
<script dangerouslySetInnerHTML={{ __html: getBundle('js') }} />
{/* Or link to a content-hashed JS file */}
<script src={getBundleFile('js', 'js')}></script>
</body>
</html>
);
};
export const render = (props) => {
return <MyPage content={props.content} />;
};