11ty is great for JAMstack, but we have to use vanilla JavaScript and CSS to create templates. With Alpine and TailwindCSS, we can create templates by declarative style directly in HTML, and we can finally use HTMLMinifier to optimize our HTML under production mode.
Version
11ty 0.12.1
TailwindCSS 3.0
Alpine 3.7
HTMLMinifier 4.0.0
Create Folder
$ mkdir 11ty-tea
Create 11ty project directory.
Add Packages
$ yarn init -y
$ yarn add @11ty/eleventy tailwindcss alpinejs html-minifier npm-run-all --dev
Use Yarn to add related package with dev dependency
@11ty/eleventy
: build markdown to HTML/CSS/JavaScripttailwindcss
: use utilities to style HTMLalpinejs
: use attributes to integrate JavaScripthtml-minifier
: optimize HTML outputnpn-run-all
: run NPM scripts in sequential or in parallel
Tailwind Config
$ npx tailwindcss init
Use Tailwind CLI to generate default tailwind.config.js
.
tailwind.config.js
module.exports = {
content: ['./src/**/*.{md,html}'],
theme: {
extend: {},
},
plugins: [],
}
Line 3
content: ['./src/**/*.{md,html}'],
Purge unused CSS by specified file extensions.
11ty Config
.eleventy.js
let htmlMinifier = require ('html-minifier')
module.exports = config => {
// Alpine
config.addPassthroughCopy ({
'node_modules/alpinejs/dist/cdn.js': 'alpine.js',
})
// HTMLMinifier
config.addTransform ('htmlMinifier', content => {
if (process.env.NODE_ENV === 'production') {
return htmlMinifier.minify (content, {
useShortDoctype: true,
removeComments: true,
collapseWhitespace: true,
})
}
return content
})
// directory & template engine
return {
htmlTemplateEngine: 'njk',
dir: {
input: 'src',
output: 'dist',
includes: 'template',
}
}
}
Define 11ty settings.
Line 4
// Alpine
config.addPassthroughCopy ({
'node_modules/alpinejs/dist/cdn.js': 'alpine.js',
})
It will copy Alpine from the node_modules
to the dist
directory when running 11ty.
Line 9
// HTMLMinifier
config.addTransform ('htmlMinifier', content => {
if (process.env.NODE_ENV === 'production') {
return htmlMinifier.minify (content, {
useShortDoctype: true,
removeComments: true,
collapseWhitespace: true,
})
}
return content
})
config.addTransform
: modify the template’s output- Under production mode, call HTMLMinifier to optimize HTML page
Line 21
// directory & template engine
return {
htmlTemplateEngine: 'njk',
dir: {
input: 'src',
output: 'dist',
includes: 'template',
}
}
htmlTemplateEngine
: use Numjucks as the default template enginedir
: user-defined directoryinput
: define markdown directoryoutput
: define build directoryincludes
: define template directory underinput
directory
CSS File
src/input.css
@tailwind base;
@tailwind components;
@tailwind utilities;
- Add
index.css
onsrc
directory - Tailwind CLI transpiles
input.css
tooutput.css
Template
src/index.html
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="output.css">
<script src="alpine.js" defer></script>
<title>Hello 11ty</title>
</head>
<body>
<div class="text-4xl text-red-700">Hello TEAstack</div>
<div x-data="{ count: 0 }">
<button class="border border-gray-300 text-xs text-gray-700 px-2 py-1" @click="count++">+</button>
<span x-text="count"/>
</div>
</body>
</html>
Line 6
<link rel="stylesheet" href="output.css">
Link CSS file to template.
Line 7
<script src="alpine.js" defer></script>
Use CDN directly as we use Alpine on the HTML page.
Line 11
<div class="text-4xl text-red-700">Hello TEAstack</div>
Use TailwindCSS utilities for HTML.
Line 12
<div x-data="{ count: 0 }">
<button class="border border-gray-300 text-xs text-gray-700 px-2 py-1" @click="count++">+</button>
<span x-text="count"/>
</div>
Classical counter implemented by Alpine and TailwindCSS.
NPM Config
package.json
{
"name": "11ty-tea",
"version": "1.0.0",
"license": "MIT",
"scripts": {
"dev:css": "npx tailwindcss -i src/input.css -o dist/output.css -w",
"dev:11ty": "eleventy --serve",
"dev": "run-p dev:*",
"build:css": "NODE_ENV=production npx tailwindcss -i src/input.css -o dist/output.css -m",
"build:11ty": "NODE_ENV=production eleventy",
"build": " run-s build:*"
},
"devDependencies": {
"@11ty/eleventy": "^0.12.1",
"alpinejs": "^3.7.0",
"html-minifier": "^4.0.0",
"npm-run-all": "^4.1.5",
"tailwindcss": "^3.0.2"
}
}
Line 6
"dev:css": "npx tailwindcss -i src/input.css -o dist/output.css -w",
Use Tailwind CLI to build CSS under development mode :
-i src/input.css
: useinput.css
as the source CSS file-o dist/output.css
: useoutput.css
as the target CSS file-w
: watch for changes and rebuild as needed
Line 7
"dev:11ty": "eleventy --serve",
Run web server by 11ty.
Line 8
"dev": "run-p dev:*",
run-p
: run all dev:*
in parallel under development mode.
Line 9
"build:css": "NODE_ENV=production npx tailwindcss -i src/input.css -o dist/output.css -m",
Use Tailwind CLI to build CSS under production mode :
-i src/input.css
: useinput.css
as source CSS file-o dist/output.css
: useoutput.css
as target CSS file-m
: minify target CSS file
Line 10
"build:11ty": "NODE_ENV=production eleventy",
Set NODE_ENV=production
to optimize HTML under production mode.
Line 11
"build": " run-s build:*"
run-s
: run all build:*
in sequential under production mode.
Development Mode
$ yarn dev
Start web server under development mode.
TailwindCSS and Alpine with 11ty are enabled under development mode.
Production Mode
$ yarn build
$ serve dist
- Build 11ty with minified target CSS file under production mode
- Use
serve
to run web server
TailwindCSS and Alpine with 11ty are enabled under production mode.
HTML is optimized under production mode.
Conclusion
- It’s not too difficult to integrate TEAstack with 11ty. With Alpine and TailwindCSS, we can start to create templates by declarative style directly in HTML
- With HTMLMinifier, we can finally optimize our HTML under production mode