即使您根本不使用任何客户端JavaScript来构建站点,也不意味着您必须放弃使用组件构建的方式。了解如何借助HTML预处理器构建静态站点。
用组件构建网站我敢说是一个很好的注意,并且现在非常流行。我们不是逐个构建整个页面,而是构建一个组件系统(想想:搜索表单,文章卡片,菜单,页脚),然后用这些组件将网站拼凑起来。
像React和Vue这样的JavaScript框架非常强调这种方式。但即使您根本不使用任何客户端JavaScript来构建网站,也并不意味着您必须放弃构建组件的方式!通过使用HTML预处理器,我们可以构建一个静态站点,并且仍然可以将我们的站点及其内容抽象为可重用的组件。
静态网站现在风靡一时,理所当然,因为它们快速,安全且便宜。甚至Smashing Magazine也是一个静态网站,信不信由你!
让我们来看看我最近使用这种技术建立的网站。我使用CodePen项目来构建它,它提供Nunjucks作为预处理器,完全适合这项工作。
具有一致的标题,导航和页脚的四页网站
这是一个微型网站。它不需要一个完整的CMS来处理数百页。它不需要JavaScript来处理交互性。但它确实需要一些共享相同布局的页面。
所有页面都有一致的页眉和页脚
仅HTML就没有很好的解决方案。我们需要的是imports。像PHP这样的语言可以用,但是静态文件主机不运行PHP(故意地)并且单独的HTML没有帮助。幸运的是,我们可以使用Nunjucks预处理includes。
可以使用PHP等语言导入组件
这里创建一个布局非常有意义,包括标题,导航和页脚的HTML块。 Nunjucks模板具有块的概念,允许我们在使用布局时将内容插入到该点。
The Power of Serverless
{% include "./template-parts/_header.njk" %}
{% include "./template-parts/_nav.njk" %}
{% block content %}
{% endblock %}
{% include "./template-parts/_footer.njk" %}
请注意,包含的文件名为_file.njk。这不是完全必要的。它可能是header.html或icons.svg,但是它们的命名是这样的,因为1)以下划线开头的文件是一种标准的方式,说它们是部分的。在CodePen项目中,这意味着他们不会尝试单独编译。2)通过命名.njk,我们可以在那里使用更多的Nunjucks东西。
这些位都没有任何特殊之处。它们只是我们四个页面中每一页都要使用的一小部分HTML。
Just a no-surprises footer, people. Nothing to see here.
通过这种方式,我们可以进行一次更改并将更改反映在所有四个页面上。
使用四页的布局
现在我们的四个页面中的每一个都可以是一个文件。让我们从index.njk开始,在CodePen项目中,它将自动处理并在每次保存时创建一个index.html文件。
从index.njk文件开始
这是我们可以放在index.njk中使用布局并删除该块中的一些内容:
{%extends"_layout.njk"%}
{%block content%}
Hello, World!
{%endblock%}
这将为我们带来一个功能齐全的主页!太好了!这四个页面中的每一个都可以做同样的事情,但在块中放入不同的内容,我们自己将有一个易于管理的四页网站。
index.njk文件被编译到index.html中
为了记录,我不确定我是否会将这些小块称为可重用组件。我们只是高效地将布局分解成块。我认为一个组件更像是一个可重用的块,它接受数据并用该数据输出自身的唯一版本。我们会做到这一点的。
制作动态导航
现在我们在四个页面上重复了相同的HTML块,是否可以将独特的CSS应用于各个导航项以识别当前页面?我们可以使用JavaScript并查看window.location等,但我们可以在没有JavaScript的情况下完成此操作。诀窍是在每个页面的上放一个类,并在CSS中使用它。
在我们的_layout.njk中,我们将body输出一个类名作为变量:
然后在我们在单个页面上调用该布局之前,我们设置该变量:
{%set body_class ="home"%}
{%extends"_layout.njk"%}
假设我们的导航结构如下
Home
...
现在我们可以根据需要定位该链接并应用特殊样式:
body.home .nav-home a,
body.services .nav-services a{
/* continue matching classes for all pages... *//* unique active state styling */
}
动态导航
哦,那些图标?这些只是我放在一个文件夹中的个别.svg文件,然后像这样引用
{%include"../icons/cloud.svg"%}
这样可以允许我像这样给它们加样式:
svg{fill:white;}
假设里面的SVG元素已经没有填充属性。
在Markdown中创作内容
我的微型网站的主页上有很多内容。我当然可以在HTML本身中编写和维护它,但有时将这种类型的东西留给Markdown是很好的。 Markdown感觉写得更干净,而且当它有很多副本时可能更容易查询。
这在CodePen项目中非常简单。我创建了一个以.md结尾的文件,它将自动处理成HTML,然后包含在index.njk文件中。
markdown中的文件在CodePen Projects上编译成HTML
{%block content%}
{%include"content/about.html"%}
{%endblock%}
构建实际组件
让我们将组件视为可重复的模块,这些模块在数据中传递以创建自己。在像Vue这样的框架中,您将使用单个文件组件,这些组件是模板化HTML,作用域CSS和特定于组件的JavaScript的孤立部分。这太酷了,但我们的微型网站不需要任何花哨的东西。
我们需要基于一个简单的模板创建一些“卡片”,所以我们可以构建这样的东西:
使用模板创建可重复的组件
使用Nunjucks中的Macros方法可以构建可重复的组件。Macros非常简单。它们就像HTML有函数一样!
{%macrocard(title, content)%}
{{title}}
{{content}}
{%endmacro%}
然后根据需要调用它:
{{card('My Module','Lorem ipsum whatever.')}}
这里的原则是数据和标记分离。这给了我们一些非常明确和切实的好处:
如果我们需要对HTML进行更改,我们可以在macro中更改它,并在使用该macro的任何地方进行更改。
数据不会跟标记耦合。
数据可能来自任何地方!正如我们上面所做的那样,我们将数据编码为对macro的调用。或者我们可以引用一些JSON数据并循环它。我相信你甚至可以想象成一个JSON数据的设置,这个数据可能来自某种无头CMS,构建过程,无服务器功能,cron作业等等。
现在我们有了这些可重复的卡片,它们结合了数据和标记,正是我们所需要的:
HTML在macro中受到控制,而数据可以来自任何地方
随心所欲地制作多个组件
你可以采取这个想法,并与它一起运行。例如,想象一下Bootstrap本质上是一堆CSS,你遵循HTML模式使用它。您可以将这些模式中的每一个都设置为macro并根据需要调用它们,实质上是对框架进行组件化。
如果您愿意,可以嵌套组件,采用一种原子设计理念。 Nunjucks也提供逻辑,这意味着只需传入不同的数据就可以创建条件组件和变量。
在我制作的简单网站中,我为网站的创意部分制作了一个不同的macro,因为它涉及略有不同的数据和略有不同的卡片设计。
可以根据需要创建任意数量的组件
针对静态站点的快速案例
我可能会争辩说,大多数站点都受益于基于组件的体系结构,但只有一些站点适合静态。我在许多后端语言主导的网站上工作过。
我的一个网站CSS-Tricks,有一些像用户登录一样的复杂的权限系统:论坛,评论,电子商务。虽然这些都没有使我完全停止静态化的想法,但我常常很高兴我有一个数据库和后端语言可以使用。它帮助我建立我需要的东西,并将事物保持在一个屋檐下。
走向并拥抱静态生活!
请记住,以我们在本文中所做的方式构建的好处之一是最终结果只是一堆静态文件。这种方式易于托管,快速,安全。然而,我们不必放弃对开发人员友好的方式工作。此站点将很容易更新和维护。
最终的项目是一个名为“The Power of Serverless for Front-End Developers ”的微型网站(https://thepowerofserverless.info/)
静态文件托管是无服务器运动的一部分。
您可以在CodePen上查看所有代码(甚至可以为自己分配一份副本)。它使用CodePen Projects在CodePen上构建,维护和托管。
CodePen Projects处理我们在这里谈到的所有Nunjucks内容,以及Sass处理和图像托管等内容,我利用这些内容进行搭建网站。您可以基于Gulp或Grunt构建一个相同的副本。相关demo地址:https://github.com/ericmotil/gulp-nunjucks-sass。
END
本文由大前端学堂编译出品,原文来自smashingmagazine,作者Chris Coyier,若转载请注明出处,转发感激不尽。
领取专属 10元无门槛券
私享最新 技术干货