首页 >web前端 >js教程 >如何使用金属史密斯创建静态站点

如何使用金属史密斯创建静态站点

Christopher Nolan
Christopher Nolan原创
2025-02-18 09:00:21761浏览

How to Create a Static Site with Metalsmith

之前文章探讨了是否应该使用静态网站生成器的理由。简而言之,静态网站生成器从模板和原始数据(通常包含在 Markdown 文件中)构建仅包含 HTML 的页面文件。它提供了一些 CMS 的好处,而没有托管、性能和安全方面的开销。

静态网站可能适合各种项目,包括:

  • 小型网站或个人博客。拥有几十个页面、不频繁的帖子和一两个作者的网站可能是理想的选择。
  • 技术文档,例如 REST API。
  • 需要一系列网页视图的应用程序原型。
  • 电子书——Markdown 文件可以转换为 PDF 或其他格式以及 HTML。

本质上,静态网站生成器是一个构建工具。您可以像使用 Grunt 或 Gulp 一样,使用它来运行任务或项目脚手架。

关键要点

  • Metalsmith 是一款灵活的可插入静态网站生成器,非常适合创建轻量级网站,而无需传统 CMS 的开销。
  • Metalsmith 的安装和设置需要 Node.js,此过程涉及初始化新的项目目录并通过 npm 安装必要的插件。
  • Metalsmith 中的项目结构涉及组织源文件、模板和资产,并明确区分开发和生产构建。
  • Metalsmith 利用各种插件来扩展功能,例如处理 Markdown 文件、创建 RSS 提要和生成站点地图,这些都配置在构建文件中。
  • 可以创建自定义插件来处理特定任务,例如设置元数据或添加调试信息,从而增强 Metalsmith 在管理网站内容和结构方面的多功能性。
  • Metalsmith 的构建过程可以与 Gulp 等任务运行器集成,以应对更复杂的场景,尽管对于更简单的流程,Metalsmith 本身就足够了。

为什么选择 Metalsmith?

无可争议的静态网站冠军是 Jekyll——一个 2008 年启动的 Ruby 项目。您不一定需要 Ruby 专业知识来使用 Jekyll,但这会有所帮助。幸运的是,大多数流行语言都有各种各样的开源静态网站生成器。JavaScript 选项包括 Hexo、Harp 和 Assemble。对于更简单的项目,您也可以使用 Gulp 等构建工具。

我选择 Metalsmith 用于本教程是因为它:

  1. 不针对特定类型的项目(例如博客)
  2. 支持各种模板和数据格式选项
  3. 轻量级
  4. 依赖项很少
  5. 使用模块化结构
  6. 提供简单的插件架构,以及
  7. 易于上手。

本教程已经构建了一个演示网站。它不会赢得任何设计奖项,但它说明了基本概念。Metalsmith 构建代码可以从 GitHub 存储库中检查和安装。或者,您可以按照此处的说明操作并创建您自己的基本站点。

我已经使用过几次 Metalsmith 了——请不要认为这是构建每个静态网站的最终方法!

安装 Metalsmith

确保您已安装 Node.js(例如使用 nvm),然后创建一个新的项目目录,例如 project 并初始化您的 package.json 文件:

<code>cd project && cd project
npm init -y
</code>

现在安装 Metalsmith 和我们将用于构建站点的各种插件。这些是:

  • metalsmith-assets — 在您的 Metalsmith 构建中包含静态资产
  • metalsmith-browser-sync — 将 BrowserSync 集成到您的工作流程中
  • metalsmith-collections — 将文件集合添加到全局元数据
  • metalsmith-feed — 为集合生成 RSS 提要
  • metalsmith-html-minifier — 使用 kangax/html-minifier 压缩 HTML 文件
  • metalsmith-in-place — 在源文件中呈现模板语法
  • metalsmith-layouts — 将布局应用于您的源文件
  • metalsmith-mapsite — 生成 sitemap.xml 文件
  • metalsmith-markdown — 转换 Markdown 文件
  • metalsmith-permalinks — 将自定义永久链接模式应用于文件
  • metalsmith-publish — 支持草稿、私有和未来日期的帖子
  • metalsmith-word-count — 计算 HTML 文件中所有段落的字数/平均阅读时间
<code>npm install --save-dev metalsmith metalsmith-assets metalsmith-browser-sync metalsmith-collections metalsmith-feed metalsmith-html-minifier metalsmith-in-place metalsmith-layouts metalsmith-mapsite metalsmith-markdown metalsmith-permalinks metalsmith-publish metalsmith-word-count handlebars
</code>

项目结构

我们将在项目中使用以下结构作为源 (src) 和构建 (build) 目录。

您可以按照以下说明创建示例文件,也可以直接从演示 src 目录复制它们。

页面

页面 Markdown 文件包含在 src/html 中。这可以包含每个网站部分的一级子目录,即

  • src/html/start — 按特定顺序描述项目的页面
  • src/html/article — 按反时间顺序排列的各种文章
  • src/html/contact — 单个联系页面

每个目录包含一个 index.md 文件,它是该部分的默认页面。其他页面可以使用任何唯一名称。

构建过程会将这些文件转换为基于目录的永久链接,例如

  • src/html/start/index.md 变成 /start/index.html
  • src/html/start/installation.md 变成 /start/installation/index.html

每个 Markdown 文件都提供内容和元信息,称为“前题”位于 --- 标记之间的顶部,例如

<code>---
title: My page title
description: A description of this page.
layout: page.html
priority: 0.9
date: 2016-04-19
publish: draft
---

This is a demonstration page.

## Example title
Body text.</code>

大多数前题都是可选的,但您可以设置:

  • priority:介于 0(低)和 1(高)之间的数字,我们将使用它来排序菜单和定义 XML 站点地图。
  • publish:可以设置为草稿、私有或未来日期,以确保它不会在需要之前发布。
  • date:文章的日期。如果没有设置,我们将使用任何未来的发布日期或文件创建日期。
  • layout:要使用的 HTML 模板。

模板

HTML 页面模板包含在 src/template 中。已定义两个模板:

  • src/html/template/page.html 默认布局
  • src/html/template/article.md 显示日期、前后链接等的文章布局

虽然支持其他选项,但使用了 Handlebars 模板系统。典型的模板需要一个 {{{ contents }}} 标记来包含页面内容以及任何前题值,例如 {{ title }}:

<code>cd project && cd project
npm init -y
</code>

对 {{> meta }}、{{> header }} 和 {{> footer }} 的引用是部分……

部分

部分——或 HTML 代码片段文件——包含在 src/partials 中。这些主要用于模板中,但也可以使用以下代码包含在内容页面中:

<code>npm install --save-dev metalsmith metalsmith-assets metalsmith-browser-sync metalsmith-collections metalsmith-feed metalsmith-html-minifier metalsmith-in-place metalsmith-layouts metalsmith-mapsite metalsmith-markdown metalsmith-permalinks metalsmith-publish metalsmith-word-count handlebars
</code>

其中 partialname 是 src/partials 目录中文件的名称。

静态资产

静态资产(例如图像、CSS 和 JavaScript 文件)包含在 src/assets 中。所有文件和子目录都将按原样复制到网站的根目录。

自定义插件

构建站点所需的自定义插件包含在 lib 目录中。

构建目录

网站将在构建目录中构建。我们将通过两种方式构建网站:

  • 开发模式:HTML 不会被压缩,并且会启动测试 Web 服务器。
  • 生产模式:如果 NODE_ENV 设置为 production,则会清除构建目录并生成最终压缩的文件。

定义您的第一个构建文件

可以在项目目录的根目录中创建一个名为 build.js 的基本示例:

<code>---
title: My page title
description: A description of this page.
layout: page.html
priority: 0.9
date: 2016-04-19
publish: draft
---

This is a demonstration page.

## Example title
Body text.</code>

使用 node ./build.js 运行它,一个静态网站将在构建目录中创建。Markdown 将被解析为 HTML,但它不可用,因为我们没有在构建过程中包含模板。

Metalsmith 插件

从表面上看,Metalsmith 构建文件看起来类似于 Gulp 中使用的构建文件(尽管它不使用流)。通过使用任何适当的参数将其传递给 Metalsmith use 方法来调用插件。插件本身必须返回另一个函数,该函数接受三个参数:

  • 一个 files 数组,包含有关每个页面的信息
  • 一个 metalsmith 对象,包含全局信息,例如元数据,以及
  • 一个 done 函数,在插件完成工作后必须调用该函数

这个简单的示例将所有元数据和页面信息记录到控制台(它可以在 build.js 中定义):

<code>
 lang="en">
  >
    {{> meta }}
  >
  >

  {{> header }}

  <main>></main>
    >

      {{#if title}}
        <h1>></h1>{{ title }}>
      {{/if}}

      {{{ contents }}}

    >
  >

  {{> footer }}

>
>
</code>

Metalsmith 构建代码可以更新为使用此插件:

<code>{{> partialname }}</code>

此调试函数可以帮助您创建自己的自定义插件,但是您可能需要的绝大多数功能都已经编写好了——Metalsmith 网站上列出了很长的插件列表。

制作更好的构建

下面解释了演示站点构建文件的主要部分。

如果 NODE_ENV 环境变量已设置为 production(在 Mac/Linux 上导出 NODE_ENV=production 或在 Windows 上设置 NODE_ENV=production),则变量 devBuild 将设置为 true:

<code>cd project && cd project
npm init -y
</code>

主目录在 dir 对象中定义,以便我们可以重复使用它们:

<code>npm install --save-dev metalsmith metalsmith-assets metalsmith-browser-sync metalsmith-collections metalsmith-feed metalsmith-html-minifier metalsmith-in-place metalsmith-layouts metalsmith-mapsite metalsmith-markdown metalsmith-permalinks metalsmith-publish metalsmith-word-count handlebars
</code>

加载 Metalsmith 和插件模块。注意:

  • 优秀的 Browsersync 测试服务器仅在创建开发构建时才需要
  • htmlmin 引用的 HTML 压缩程序模块仅在创建生产构建时才需要
  • 已定义三个自定义插件:setdate、moremeta 和 debug(下面将更详细地解释)
<code>---
title: My page title
description: A description of this page.
layout: page.html
priority: 0.9
date: 2016-04-19
publish: draft
---

This is a demonstration page.

## Example title
Body text.</code>

siteMeta 对象使用应用于每个页面的信息定义。重要的值是 domain 和 rootpath,它们根据开发或生产构建进行设置:

<code>
 lang="en">
  >
    {{> meta }}
  >
  >

  {{> header }}

  <main>></main>
    >

      {{#if title}}
        <h1>></h1>{{ title }}>
      {{/if}}

      {{{ contents }}}

    >
  >

  {{> footer }}

>
>
</code>

还定义了一个 templateConfig 对象来设置模板默认值。这将由 metalsmith-in-place 和 metalsmith-layouts 插件使用,它们启用使用 Handlebars 的页面内和模板渲染:

<code>{{> partialname }}</code>

Metalsmith 对象现在像以前一样初始化,但我们还将 siteMeta 对象传递给 metadata 方法,以确保该信息可用于每个页面。因此,我们可以在任何页面中引用诸如 {{ name }} 之类的项目以获取站点名称。

<code>// basic build

'use strict';

var
  metalsmith = require('metalsmith'),
  markdown   = require('metalsmith-markdown'),

  ms = metalsmith(__dirname) // the working directory
    .clean(true)            // clean the build directory
    .source('src/html/')    // the page source directory
    .destination('build/')  // the destination directory
    .use(markdown())        // convert markdown to HTML
    .build(function(err) {  // build the site
      if (err) throw err;   // and throw errors
    });
</code>

我们的第一个插件调用调用 metalsmith-publish,它删除任何其前题 publish 值设置为草稿、私有或未来日期的文件:

<code>function debug(logToConsole) {
  return function(files, metalsmith, done) {
    if (logToConsole) {
      console.log('\nMETADATA:');
      console.log(metalsmith.metadata());

      for (var f in files) {
        console.log('\nFILE:');
        console.log(files[f]);
      }
    }

    done();
  };
};
</code>

setdate 是包含在 lib/metalsmith-setdate.js 中的自定义插件。它确保每个文件都设置了“date”值,即使在前题中没有定义任何值,也可以通过尽可能回退到发布日期或文件创建时间来实现:

<code>ms = metalsmith(__dirname) // the working directory
  .clean(true)             // clean the build directory
  .source('src/html/')     // the page source directory
  .destination('build/')   // the destination directory
  .use(markdown())         // convert Markdown to HTML
  .use(debug(true))        // *** NEW *** output debug information
  .build(function(err) {   // build the site
    if (err) throw err;    // and throw errors
  });
</code>

metalsmith-collections 是最重要的插件之一,因为它根据页面在源目录中的位置或其他因素将每个页面分配给类别或分类法。它可以使用前题(例如日期或优先级)重新排序文件,并允许您为该集合设置自定义元数据。代码定义:

  • src/html/start 目录中每个文件的 start 集合。它按文件中前题中设置的优先级值对它们进行排序。
  • src/html/article 目录中每个文件的 article 集合。它按反时间顺序对它们进行排序
  • 每个名为 index.* 的默认页面的 page 集合。它按文件中前题中设置的优先级值对它们进行排序。
<code>devBuild = ((process.env.NODE_ENV || '').trim().toLowerCase() !== 'production')
</code>

接下来是 Markdown 到 HTML 的转换,然后是 metalsmith-permalinks 插件,它为构建定义了目录结构。请注意,moremeta 在下面为每个文件设置了 :mainCollection:

<code>dir = {
  base:   __dirname + '/',
  lib:    __dirname + '/lib/',
  source: './src/',
  dest:   './build/'
}
</code>

metalsmith-word-count 计算文章中的字数并计算大约需要多长时间才能阅读。参数 { raw: true } 仅输出数字:

<code>metalsmith  = require('metalsmith'),
markdown    = require('metalsmith-markdown'),
publish     = require('metalsmith-publish'),
wordcount   = require("metalsmith-word-count"),
collections = require('metalsmith-collections'),
permalinks  = require('metalsmith-permalinks'),
inplace     = require('metalsmith-in-place'),
layouts     = require('metalsmith-layouts'),
sitemap     = require('metalsmith-mapsite'),
rssfeed     = require('metalsmith-feed'),
assets      = require('metalsmith-assets'),
htmlmin     = devBuild ? null : require('metalsmith-html-minifier'),
browsersync = devBuild ? require('metalsmith-browser-sync') : null,

// custom plugins
setdate     = require(dir.lib + 'metalsmith-setdate'),
moremeta    = require(dir.lib + 'metalsmith-moremeta'),
debug       = consoleLog ? require(dir.lib + 'metalsmith-debug') : null,
</code>

moremeta 是包含在 lib/metalsmith-moremeta.js 中的另一个自定义插件。它将其他元数据附加到每个文件:

  • root:到根目录的绝对或计算出的相对文件路径
  • isPage:对于名为 index.* 的默认部分页面设置为 true
  • mainCollection:主要集合名称,即 start 或 article
  • layout:如果未设置,则可以从主集合的元数据中确定布局模板
  • navmain:顶级导航对象的数组
  • navsub:二级导航对象的数组

插件代码比较复杂,因为它处理导航。如果您需要更简单的层次结构,则有更简单的选项。

<code>cd project && cd project
npm init -y
</code>

metalsmith-in-place 和 metalsmith-layouts 插件分别控制页面内和模板布局。传递上面定义的相同 templateConfig 对象:

<code>npm install --save-dev metalsmith metalsmith-assets metalsmith-browser-sync metalsmith-collections metalsmith-feed metalsmith-html-minifier metalsmith-in-place metalsmith-layouts metalsmith-mapsite metalsmith-markdown metalsmith-permalinks metalsmith-publish metalsmith-word-count handlebars
</code>

如果设置了 htmlmin(在生产构建中),我们可以压缩 HTML:

<code>---
title: My page title
description: A description of this page.
layout: page.html
priority: 0.9
date: 2016-04-19
publish: draft
---

This is a demonstration page.

## Example title
Body text.</code>

debug 是包含在 lib/metalsmith-debug.js 中的最终自定义插件。它类似于上面描述的 debug 函数:

<code>
 lang="en">
  >
    {{> meta }}
  >
  >

  {{> header }}

  <main>></main>
    >

      {{#if title}}
        <h1>></h1>{{ title }}>
      {{/if}}

      {{{ contents }}}

    >
  >

  {{> footer }}

>
>
</code>

启动 Browsersync 测试服务器,以便我们可以测试开发构建。如果您以前没有使用过它,它看起来就像魔法:每次您进行更改时,您的网站都会神奇地刷新,并且当您滚动或浏览网站时,两个或多个浏览器中的视图会同步:

<code>{{> partialname }}</code>

最后,我们可以使用:

  • metalsmith-mapsite 生成 XML 站点地图
  • metalsmith-feed 为 article 集合中的页面生成 RSS 提要
  • metalsmith-assets 直接将 src/assets 中的文件和目录复制到 build,而无需修改。
<code>// basic build

'use strict';

var
  metalsmith = require('metalsmith'),
  markdown   = require('metalsmith-markdown'),

  ms = metalsmith(__dirname) // the working directory
    .clean(true)            // clean the build directory
    .source('src/html/')    // the page source directory
    .destination('build/')  // the destination directory
    .use(markdown())        // convert markdown to HTML
    .build(function(err) {  // build the site
      if (err) throw err;   // and throw errors
    });
</code>

剩下的就是最后的 .build() 步骤来创建网站:

<code>function debug(logToConsole) {
  return function(files, metalsmith, done) {
    if (logToConsole) {
      console.log('\nMETADATA:');
      console.log(metalsmith.metadata());

      for (var f in files) {
        console.log('\nFILE:');
        console.log(files[f]);
      }
    }

    done();
  };
};
</code>

完成后,您可以再次运行 node ./build.js 来构建您的静态网站。

需要注意的地方

我在构建简单的 Metalsmith 网站时学到了很多东西,但请注意以下问题:

不兼容的插件

插件可能会与其他插件冲突。例如,计算相对根路径的 metalsmith-rootpath 与创建自定义构建目录结构的 metalsmith-permalinks 不太兼容。我通过在 lib/metalsmith-moremeta.js 插件中编写自定义根路径计算代码解决了此问题。

插件顺序至关重要

如果插件放置的顺序错误,则插件可能会相互依赖或冲突。例如,生成 RSS 的 metalsmith-feed 插件必须在 metalsmith-layouts 之后调用,以确保不会在页面模板中生成 RSS XML。

Browsersync 重新构建问题

当 Browsersync 运行并编辑文件时,集合会被重新解析,但旧数据似乎仍然存在。这可能是 lib/metalsmith-moremeta.js 自定义插件的问题,但菜单和前后链接可能会不同步。要修复它,请使用 Ctrl/Cmd C 停止构建并重新启动构建。

您是否仍然需要 Gulp?

使用 Gulp 等任务管理器的人会注意到 Metalsmith 提供了一个熟悉的构建过程。有用于使用 Sass 进行 CSS 预处理、图像压缩、文件连接、丑化和更多功能的插件。对于更简单的流程,它可能就足够了。

但是,Gulp 具有更广泛的插件范围,并允许进行复杂的构建活动,例如 lint、部署和使用 auto-prefixer 的 PostCSS 处理。有一些 Gulp/Metalsmith 集成插件,尽管我遇到了一些问题,并且它们不应该是必要的,因为 Gulp 任务可以直接运行 Metalsmith,例如

<code>cd project && cd project
npm init -y
</code>

此过程可以防止上面提到的 Browsersync 重新构建问题。请记住使用 .clean(false) 以确保当其他任务处于活动状态时,Metalsmith 永远不会清除构建文件夹。

Metalsmith 适合您吗?

如果您有简单或高度定制的网站需求,Metalsmith 是理想的选择。也许可以尝试使用文档项目并一次添加一个功能。Metalsmith 并不像 Jekyll 等替代方案那样功能齐全,但它并非旨在如此。您可能需要编写自己的插件,但这样做很容易,这对 JavaScript 开发人员来说是一个巨大的好处。

创建 Metalsmith 构建系统需要时间,我们还没有考虑 HTML 模板和部署所涉及的工作量。但是,一旦您拥有一个可用的流程,添加、编辑和删除 Markdown 文件就会变得非常简单。它可能比使用 CMS 更容易,并且您拥有静态网站的所有好处。

关于使用 Metalsmith 创建静态网站的常见问题

什么是 Metalsmith,为什么我应该使用它来创建静态网站?

Metalsmith 是一款简单易用的可插入静态网站生成器。它基于 Node.js,并使用模块化结构,允许您通过插件根据需要添加功能。这使其具有令人难以置信的灵活性和可定制性。您应该使用 Metalsmith 创建静态网站,因为它允许您完全按照自己的意愿构建网站,而无需受传统 CMS 的限制。此外,静态网站比动态网站更快、更安全且更易于维护。

如何安装 Metalsmith?

要安装 Metalsmith,您需要在计算机上安装 Node.js 和 npm。安装这些后,您可以通过在终端中运行命令 npm install metalsmith 来安装 Metalsmith。这将安装 Metalsmith 及其所有依赖项。

如何创建一个新的 Metalsmith 项目?

要创建一个新的 Metalsmith 项目,首先在终端中导航到要创建项目的目录。然后,运行命令 metalsmith 创建一个新项目。这将创建一个新的目录,其名称为您的项目名称,在此目录内,它将为您的静态网站创建一个基本结构。

如何在我的 Metalsmith 项目中添加插件?

要向您的 Metalsmith 项目添加插件,您需要通过 npm 安装它们,然后在您的 Metalsmith 配置文件中引用它们。例如,要添加 markdown 插件,您首先需要运行 npm install metalsmith-markdown,然后在您的配置文件中,您需要添加 var markdown = require('metalsmith-markdown'); 并将 .use(markdown()) 添加到您的 Metalsmith 构建链中。

如何构建我的 Metalsmith 网站?

要构建您的 Metalsmith 网站,您需要在终端中运行命令 metalsmith build。这将编译所有文件并将它们输出到构建目录,然后您可以将其部署到您的服务器。

如何自定义我的 Metalsmith 网站的布局?

要自定义您的 Metalsmith 网站的布局,您可以使用 Handlebars 或 Jade 等模板引擎。这些允许您为网站的不同部分(如页眉、页脚和各个页面)创建可重用的模板。

如何在我的 Metalsmith 网站中添加内容?

要向您的 Metalsmith 网站添加内容,您可以在源目录中创建 markdown 文件。构建网站时,这些文件将转换为 HTML。您还可以使用 Netlify CMS 等 CMS 来管理您的内容。

如何部署我的 Metalsmith 网站?

要部署您的 Metalsmith 网站,您可以使用 Netlify 或 GitHub Pages 等服务。这些服务将托管您的静态网站,并在您推送到存储库时自动部署更改。

如何更新我的 Metalsmith 网站?

要更新您的 Metalsmith 网站,您只需更改源文件,然后重新构建您的网站。更改将反映在构建目录中,然后您可以将其部署到您的服务器。

我可以将 Metalsmith 用于大型复杂网站吗?

是的,Metalsmith 具有高度可扩展性,可用于大型复杂网站。其模块化结构允许您根据需要添加功能,并且它使用静态文件意味着它可以处理大量内容而不会减慢速度。

以上是如何使用金属史密斯创建静态站点的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn