Table of Contents
Page 8 of 10

Eleventy Excellent

Move the assets pipeline to Baseline

Entry points replace the starter's per-page bundle calls, and PostCSS and esbuild run inside the plugin.

postcss.config.js                      new, at the project root
src/assets/css/global/global.css  ->   global/index.css     entry point
src/assets/css/local/index.css         new, ten explicit imports
src/assets/scripts/               ->   src/assets/js/
src/assets/js/index.js                 new, entry point

Those entry points reach the page through settings.head, which is why this step follows the head one rather than leading it.

Create the three entry points

Baseline compiles one bundle per directory, from the index file it finds there, so you need three. global/index.css is the starter's existing entry renamed and keeps its layer order and its globs untouched, local/index.css is new and replaces the eleven per-page bundles, and the JS entry is two lines because most of this starter's JavaScript stays page-scoped.

View the three entry points
/* src/assets/css/global/index.css */
@import 'tailwindcss/base' layer(tailwindBase);

@import 'base/reset.css' layer(reset);
@import 'base/fonts.css' layer(fonts);

@import 'tailwindcss/components' layer(tailwindComponents);

@import 'base/variables.css' layer(variables);
@import 'base/global-styles.css' layer(global);
@import 'base/view-transitions.css' layer(global);

@import-glob 'compositions/*.css' layer(compositions);
@import-glob 'blocks/*.css' layer(blocks);
@import-glob 'utilities/*.css' layer(utilities);

@import 'tailwindcss/utilities' layer(tailwindUtilities);

Its imports are listed one by one rather than globbed. A glob would work here, since this is an entry file, but @import-glob fails silently the moment a file stops being one, and the next part covers what that costs:

/* src/assets/css/local/index.css */
@import './custom-card.css';
@import './details.css';
@import './footnotes.css';
@import './gallery.css';
@import './nav-main-drawer-cls.css';
@import './pagination.css';
@import './post.css';
@import './styleguide.css';
@import './table.css';
@import './forms.css';

And the JS entry:

// src/assets/js/index.js
import './bundle/is-land.js';

is-land.js moves here because it is site-wide and worth caching once. Everything else stays where it is used.

Only is-land.js graduates to the entry point. The rest of the JavaScript keeps its per-page scoping, by a different route covered in the next part.

Declare them in settings

The three files reach the page through the settings you already wrote, and PostCSS needs a config at the project root because it runs inside the plugin now rather than through postcss-cli.

View the declaration and the PostCSS config
link:   [{rel: 'stylesheet', href: '/assets/css/global/index.css'},
         {rel: 'stylesheet', href: '/assets/css/local/index.css'}],
script: [{src: '/assets/js/index.js', defer: true, module: true}]
// postcss.config.js
import postcssImportExtGlob from 'postcss-import-ext-glob';
import postcssImport from 'postcss-import';
import tailwindcss from 'tailwindcss';
import autoprefixer from 'autoprefixer';
import cssnano from 'cssnano';

const isProd = process.env.ELEVENTY_ENV === 'production';

const plugins = [postcssImportExtGlob, postcssImport, tailwindcss, autoprefixer];

if (isProd) {
  plugins.push(cssnano);
}

export default {
  map: !isProd,
  plugins
};

PostCSS normalises plugins itself, so tailwindcss and tailwindcss() both work. Call one only to pass it options.

With the entry points declared, what is left is the eleven CSS blocks and five JS blocks in the templates that used to do this work per page.