当我决定尝试基于 Eleventy 构建我当前的个人网站时,我不想重新发明轮子:我在文档的 入门项目 中测试了所有使用 Tailwind CSS 构建的 Eleventy 入门项目。
许多入门项目似乎以一种牵强的方式集成了 Tailwind CSS。此外,其中一些似乎假设没有人会在开发网站时动态更新 Tailwind 的配置。这就是我将 Eleventy 与 Tailwind CSS 和 Alpine.js 集成在一起的原因。我有理由相信您会喜欢我的解决方案的简洁性。
好的设计就是尽可能少的进行设计。
——Dieter Rams,《良好设计的十项原则》
如果您对细节不感兴趣,可以随意 获取我的入门项目 并直接开始使用。
入门
我将假设您对 Tailwind CSS、HTML、JavaScript、Nunjucks、命令行和 npm 有基本的了解。
让我们从创建一个新文件夹开始,然后在命令行中 cd
到该文件夹,并使用 package.json
文件对其进行初始化
npm init -y
现在我们可以安装 Eleventy 和 Tailwind CSS 了
npm install -D @11ty/eleventy tailwindcss@latest
我们需要创建一个页面来测试我们是否已成功设置了所有内容。在实际用例中,我们的页面将使用模板,因此我们也将在此处这样做。这就是 Nunjucks 融入其中并充当模板引擎的地方。
让我们在项目文件夹中创建一个名为 index.njk
的新文件。我们将将其指定为主页
{% extends "_includes/default.njk" %}
{% block title %}It does work{% endblock %}
{% block content %}
<div class="fixed inset-0 flex justify-center items-center">
<div>
<span class="text-change">Good design</span><br/>
<span class="change">is<br/>as little design<br/>as possible</span>
</div>
</div>
{% endblock %}
基本模板
现在,让我们在项目文件夹中创建一个名为 _includes
的新文件夹(是的,文件夹名称很重要)。在这个新文件夹中,我们将创建一个名为 default.njk
的文件,我们将将其用作布局的默认模板。我们将使用基本的 HTML 骨架来保持简单
<!DOCTYPE html>
<html lang="en">
<head>
<title>
{% block title %}Does it work?{% endblock %}
</title>
<meta charset="UTF-8"/>
{% if description %}
<meta name="description" content="{{description}}"/>
{% endif %}
<meta http-equiv="x-ua-compatible" content="ie=edge"/>
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no, viewport-fit=cover"/>
<link rel="stylesheet" href="/style.css?v={% version %}"/>
{% block head %}{% endblock %}
</head>
<body>
{% block content %}
{{ content | safe }}
{% endblock %}
</body>
</html>
配置 Tailwind CSS
让我们尽可能少地进行操作,为 Tailwind CSS 进行测试。首先,创建一个名为 styles
的新子文件夹,并在其中创建一个名为 tailwind.config.js
的文件
module.exports = {
content: ['_site/**/*.html'],
safelist: [],
theme: {
extend: {
colors: {
change: 'transparent',
},
},
},
plugins: [],
}
然后,在同一个 styles
文件夹中创建一个名为 tailwind.css
的文件
@tailwind base;
@tailwind components;
@tailwind utilities;
@layer utilities {
.change {
color: transparent;
}
}
启动和构建项目
现在,让我们在同一根目录中创建另一个名为 .gitignore
的新文件。这将允许我们在将项目提交到存储库(例如 GitHub)时定义要跳过的文件
_site/
.DS_Store
node_modules/
接下来,我们将创建一个名为 .eleventy.js
(注意前面的点)的文件,该文件基本上配置了 Eleventy,告诉它要监视哪些文件以及将工作保存到哪里
const now = String(Date.now())
module.exports = function (eleventyConfig) {
eleventyConfig.addWatchTarget('./styles/tailwind.config.js')
eleventyConfig.addWatchTarget('./styles/tailwind.css')
eleventyConfig.addPassthroughCopy({ './_tmp/style.css': './style.css' })
eleventyConfig.addShortcode('version', function () {
return now
})
};
我们现在可以使用所有我们需要在开发过程中启动和构建站点的脚本更新 package.json
文件。初始设置中应该已经存在依赖项。
{
"scripts": {
"start": "eleventy --serve & npx tailwindcss -i styles/tailwind.css -c styles/tailwind.config.js -o _site/style.css --watch",
"build": "ELEVENTY_PRODUCTION=true eleventy && NODE_ENV=production npx tailwindcss -i styles/tailwind.css -c styles/tailwind.config.js -o _site/style.css --minify"
},
"devDependencies": {
"@11ty/eleventy": "^1.0.0",
"tailwindcss": "^3.0.0"
}
}
嘿,干得好!我们成功了。让我们正式启动网站
npm start
在浏览器中打开页面 http://localhost:8080
。它看起来可能不太起眼,但请查看浏览器选项卡中的页面标题

我们还可以进行更多检查以确保一切正常。打开 /styles/tailwind.config.js
并将 transparent
颜色值更改为其他内容,例如 black
。Tailwind 的配置应重新加载,以及浏览器中的页面。
不要离开浏览器,并通过将 transparent
再次更改为 black
来编辑 /styles/tailwind.css
。您的 CSS 文件应重新加载并在浏览器中刷新。
现在我们可以很好地使用 Eleventy 和 Tailwind CSS 了!
优化输出
此时,Tailwind CSS 可以与 Eleventy 一起使用,但生成的 HTML 并不完美,因为它包含诸如冗余换行符之类的内容。让我们清理一下
npm install -D html-minifier
将以下行添加到 .eleventy.js
文件的开头
const htmlmin = require('html-minifier')
我们还需要在 .eleventy.js
中配置 htmlmin
eleventyConfig.addTransform('htmlmin', function (content, outputPath) {
if (
process.env.ELEVENTY_PRODUCTION &&
outputPath &&
outputPath.endsWith('.html')
) {
let minified = htmlmin.minify(content, {
useShortDoctype: true,
removeComments: true,
collapseWhitespace: true,
});
return minified
}
return content
})
我们在这里使用了一个转换,这是一个 Eleventy 功能。 转换 可以修改模板的输出。此时,.eleventy.js
应该如下所示
const htmlmin = require('html-minifier')
const now = String(Date.now())
module.exports = function (eleventyConfig) {
eleventyConfig.addWatchTarget('./styles/tailwind.config.js')
eleventyConfig.addWatchTarget('./styles/tailwind.css')
eleventyConfig.addShortcode('version', function () {
return now
})
eleventyConfig.addTransform('htmlmin', function (content, outputPath) {
if (
process.env.ELEVENTY_PRODUCTION &&
outputPath &&
outputPath.endsWith('.html')
) {
let minified = htmlmin.minify(content, {
useShortDoctype: true,
removeComments: true,
collapseWhitespace: true,
})
return minified
}
return content
})
}
让我们再次运行 npm start
。您会看到没有任何变化,这是因为优化仅在构建期间发生。因此,我们改用 npm run build
,然后查看 _site
文件夹。index.html
文件中不应该存在任何不必要的字符。style.css
文件也是如此。
这样构建的项目现在已准备好部署。干得好!🏆
集成 Alpine.js
我决定从 Gatsby.js 切换到 Eleventy,因为它对我来说感觉 JavaScript 太多了。我更喜欢将适量的原生 JavaScript 与 Alpine.js 混合使用。我们这里不会深入探讨 Alpine.js 的细节,但值得 查看 Hugo DiFrancesco 的入门指南,因为它是一个完美的起点。
以下是如何从命令行将其安装到我们的项目中
npm install -D alpinejs
现在我们需要使用以下内容更新 .eleventy.js
,将其传递给 Alpine.js 的函数
eleventyConfig.addPassthroughCopy({
'./node_modules/alpinejs/dist/cdn.js': './js/alpine.js',
})
最后,我们将打开 _includes/default.njk
并将 Alpine.js 添加到结束 </head>
标记之前
<script src="/js/alpine.js?v={% version %}"></script>
我们可以通过将此添加到 index.njk
来检查 Alpine 是否正在工作
{% extends "_includes/default.njk" %}
{% block title %}It does work{% endblock %}
{% block content %}
<div class="fixed inset-0 flex justify-center items-center">
<div>
<span class="text-change">Good design</span><br/>
<span class="change">is<br/>as little design<br/>as possible</span><br/>
<span x-data="{message:'🤖 Hello World 🤓'}" x-text="message"></span>
</div>
</div>
{% endblock %}
启动项目
npm start
如果 Alpine.js 工作正常,您将在浏览器中看到“Hello World”。恭喜,双倍!🏆🏆
我希望您能看到设置 Eleventy 项目的速度有多快,包括与 Nunjucks 集成以进行模板化、与 Tailwind 集成以进行样式设置以及与 Alpine.js 集成以进行脚本编写。我知道使用新技术可能会让人不知所措,甚至令人困惑,因此如果您在启动时遇到问题或有简化此操作的想法,请随时发送电子邮件至 [email protected]
。
好文章!Tailwind 在最新版本中内置了 Purge 功能,可以在 tailwind 配置文件中进行配置。也许我们可以利用它而不是在 postcss 配置中进行配置? https://tailwind.org.cn/docs/controlling-file-size
嗨,Mario!很高兴你喜欢这篇文章。:)
感谢您的建议——这是一个有效的观点!
如果您在设置中没有将 PostCSS 用于其他任何内容,则利用“内置”Purge 很有意义。在这种情况下,设置尽可能简约,因此我不仅将 PostCSS 用于 Tailwind,还用于 autoprefixer,以在删除未使用的部分后缩小 CSS(这些只是文章中列出的元素;我在我的项目中将 PostCSS 用于其他用途)。
此外,这里使用 PostCSS 不是我的想法。:) Tailwind 的文档中说明
“对于大多数项目,您需要在构建链中将 Tailwind 作为 PostCSS 插件添加。”
本文旨在让 Eleventy、Tailwind 和 Alpine 以尽可能“自然”的方式协同工作。
再次感谢,Mario!:)
如果我遗漏了什么,请告诉我。
听起来马里奥并不是建议你完全放弃 PostCSS,而是利用 Tailwind 内置的 PurgeCSS 来进一步简化事情。
tailwind.config.js
postcss.config.js
tailwind.css
格雷格,好文章。一个小小的意见,但仍然是一个意见:我一边跟着做一边已经习惯了使用 Tailwind,当我发现我不能简单地测试 bg-blue-300 或类似的东西时,我感到很奇怪。没有颜色,然后我看到了你在 tailwind.config 中是如何定义颜色的。通过 extend 来做会更容易(更好)。
theme: {
extend: {
colors: {
cyan: “#9cdbff”,
},
},
},
因为未使用的样式无论如何都会被去除。也许甚至可以使用 Tailwind 本身的新 purge 选项。
https://tailwind.org.cn/docs/controlling-file-size/
谢谢,各位!你们说服我了。我更新了文章和启动器。马里奥、贾斯汀、汤姆,谢谢你们。:)
Tailwind 很奇怪。构建一个大型的 CSS 包,然后定义其中不存在的内容?
在开发过程中,拥有所有可用的实用程序样式触手可及非常有用。但是你不需要在生产环境中使用所有样式 - 仅需使用你正在使用的样式。
非常感谢这篇文章。我一直认为这个技术栈在可定制性和轻量级方面都很棒。很快就会将此指南用于一些个人项目。
嗨,格雷格!
很棒的文章!但是,你不再需要单独使用 purge 依赖项了!如果你使用 NODE_ENV 设置为 production 来运行你的 PostCSS 脚本,并在你的 tailwind 文件中配置 purge 键,它就会为你处理!
我的个人网站使用的是完全相同的技术栈,并且配置了更少的依赖项,所有 CSS 和 JS 都通过 Rollup 进行压缩!
它可以在此处找到:https://github.com/mattwaler/website
嗨,不太理解为什么我们将样式渲染到 _tmp 然后复制到 _site,为什么不直接渲染到 _site,谢谢!
嗨!:) 一个很好的问题。如果没有你提到的解决方法,我们就无法享受清爽的热重载体验。
遇到一个问题 :(
我这样做了,但是
bg-indigo-500
不起作用。我只能使用bg-indigo
。感谢这个启动器,我刚刚开始使用 Eleventy 并熟悉了 Tailwind CSS,自然也熟悉了 Alpine JS。期待构建和设计我多年来一直想做的项目。谢谢。
不错的工作,也许只需要将 README.md 添加到 .eleventyignore 中,我认为 js 输出文件仍然没有被压缩。
所以我认为将这个在链接中追加版本标签的想法复制到样式表中是个好主意。
但是检查由 eleventy 生成的不同页面的源代码,所有页面都使用相同的
head.njk
组件,该组件包含在我的base.njk
中,我可以看到同一个 CSS 文件的不同版本标签。我想这个结果使得使用这种策略变得没有意义。以下是一些生成的版本标签:1614537697642、1614537697643、1614537697634;对于三个不同的页面。
标签应该只为一个构建生成一次,现在每次写入单个页面时都会生成。也许使用稍微不同的方法可以解决这个问题。也许只是我,我不知道。
是否可以将此标签生成到一个变量中,无论是在 eleventy.js 中还是在外部的另一个 .js 文件中,然后在整个(重新)构建过程中使用相同的标签,直到另一次(重新)构建?
在 eleventy.js 中
在 default/head.njk 中
嗨,米歇尔!感谢你的评论。你说得对,对不起,我更新了文章。:)
我正在浏览你的教程,无法让 alpine 工作。使用以下内容更新 .eleventy.js
alpine 节点模块现在称为 cdn.js,而不是 alpine.js。
谢谢,eb!已更新。:)
感谢这篇文章,格雷格。作为一个相对新手(之前只使用过 Hugo)在 Eleventy/Tailwind/Alpine 组合方面,我发现它耳目一新。
我只有一个问题。你的“npm start”命令创建了一个版本控制的 css 文件,但构建命令只输出到 styles.css 文件。调整构建命令以将版本控制/缓存清除合并到我的最终 _site 文件夹中的方法是什么?
抱歉,这可能是一个很容易回答的问题,但正如我所说,我对这方面比较陌生,而且在线上找不到简单的帮助。
感谢你的精彩提问,理查德!:)
模板中的
<link rel="stylesheet" href="/style.css?v={% version %}"/>
负责版本控制/缓存清除。此外,如果你将你的网站托管在——例如——Netlify 上,据我所知,你不需要
?v={% version %}
进行版本控制/缓存清除。不错的组合。Alpine 看起来很不错。当一切设置好后,我确实喜欢 Tailwind,但设置起来确实很麻烦。
我真的很想让它工作,但我做不到。来自“此时,.eleventy.js 应该如下所示”的配置变体在 VSC 中给了我 3 个错误。预期声明或语句,但我看不出问题在哪里。
谢谢,利特尔!:) 我刚刚在 macOS 上的 VSC 中测试了它。没有错误。我怀疑问题根源在于你在 VSC 中安装的扩展之一。祝你好运!:)
嗯,我不明白为什么这种设置在 Windows 上不起作用。可能是服务器同步或路径中的 ./ 出现了一些问题,但 CORS 错误 No-sniff 出现,无法导入 css。也许只是我,但对我来说它不起作用 :(
@Ivan Windows 的问题是使用“&”或“&&”在 start 和 build 脚本中链接命令。试试这个
并将脚本更改为
你的代码里有个小错误,
const now = String(Date.now())
位于函数外部意味着在初始加载后不会重新计算该值。随后的热重载只会触发该函数。该行应该位于要导出的函数内部。