实用

Metalsmith 能够支持你所已经掌握并使用的所有工具和数据格式:NodeJS、npm、markdown、json、yaml 以及你所选择的模板语言。

简单

Metalsmith 能够将整个目录及其包含的所有文件转换为一组普通的 JavaScript 对象,然后你就可以通过插件来操作这些 JavaScript 对象了。

插件

你无需被特定框架或工具束缚了你的项目的需求。Metalsmith 可以让你完全控制你对项目的构思、结构和构建方式。

多用途

使用 Metalsmith 可以生成任何内容,从静态站点到脚手架、备份、命令行或部署工具。无论是配置优先还是代码优先的模式,Metalsmith 都能支持。


安装 Metalsmith

npm install metalsmith
yarn add metalsmith
pnpm add metalsmith

Or use a starter


Get the feel of it

You want to build a website or blog with a static site generator. Well, here is our elevator pitch. It's as easy as that:

metalsmith.mjs
import { fileURLToPath } from 'node:url'
import { dirname } from 'node:path'
import Metalsmith from 'metalsmith'
import collections from '@metalsmith/collections'
import layouts from '@metalsmith/layouts'
import markdown from '@metalsmith/markdown'
import permalinks from '@metalsmith/permalinks'

const __dirname = dirname(fileURLToPath(import.meta.url))
const t1 = performance.now()

Metalsmith(__dirname)         // parent directory of this file
  .source('./src')            // source directory
  .destination('./build')     // destination directory
  .clean(true)                // clean destination before
  .env({                      // pass NODE_ENV & other environment variables
    DEBUG: process.env.DEBUG,
    NODE_ENV: process.env.NODE_ENV
  })           
  .metadata({                 // add any variable you want & use them in layout-files
    sitename: "My Static Site & Blog",
    siteurl: "https://example.com/",
    description: "It's about saying »Hello« to the world.",
    generatorname: "Metalsmith",
    generatorurl: "https://metalsmith.io/"
  })
  .use(collections({          // group all blog posts by internally
    posts: 'posts/*.md'       // adding key 'collections':'posts'
  }))                         // use `collections.posts` in layouts
  .use(markdown())            // 把所有 markdown 文件转换为 html 文件
  .use(permalinks())          // change URLs to permalink URLs
  .use(layouts({              // wrap layouts around html
    pattern: '**/*.html'
  }))
  .build((err) => {           // 启动构建流程
    if (err) throw err        // 必要的错误处理
    console.log(`Build success in ${((performance.now() - t1) / 1000).toFixed(1)}s`)
  });
metalsmith.cjs
const Metalsmith  = require('metalsmith')
const collections = require('@metalsmith/collections')
const layouts     = require('@metalsmith/layouts')
const markdown    = require('@metalsmith/markdown')
const permalinks  = require('@metalsmith/permalinks')

const t1 = performance.now()

Metalsmith(__dirname)         // parent directory of this file
  .source('./src')            // source directory
  .destination('./build')     // destination directory
  .clean(true)                // clean destination before
  .env({                      // pass NODE_ENV & other environment variables
    DEBUG: process.env.DEBUG,
    NODE_ENV: process.env.NODE_ENV
  })           
  .metadata({                 // add any variable you want & use them in layout-files
    sitename: "My Static Site & Blog",
    siteurl: "https://example.com/",
    description: "It's about saying »Hello« to the world.",
    generatorname: "Metalsmith",
    generatorurl: "https://metalsmith.io/"
  })
  .use(collections({          // group all blog posts by internally
    posts: 'posts/*.md'       // adding key 'collections':'posts'
  }))                         // use `collections.posts` in layouts
  .use(markdown())            // transpile all md into html
  .use(permalinks())          // change URLs to permalink URLs
  .use(layouts({              // wrap layouts around html
    pattern: '**/*.html'
  }))
  .build((err) => {           // build process
    if (err) throw err        // error handling is required
    console.log(`Build success in ${((performance.now() - t1) / 1000).toFixed(1)}s`)
  })
metalsmith.json
{
  "source": "src",
  "destination": "build",
  "clean": true,
  "env": {
    "DEBUG": "$DEBUG",
    "NODE_ENV": "$NODE_ENV"
  },
  "metadata": {
    "sitename": "My Static Site & Blog",
    "siteurl": "https://example.com/",
    "description": "It's about saying »Hello« to the world.",
    "generatorname": "Metalsmith",
    "generatorurl": "https://metalsmith.io/"
  },
  "plugins": [
    { "@metalsmith/collections": { "posts": "posts/*.md" }},
    { "@metalsmith/markdown": {}},
    { "@metalsmith/permalinks": { "relative": false }},
    { "@metalsmith/layouts": {}},
  ]
}

The package exposes both a JavaScript API, and a CLI if you prefer. To see how they're used check out the examples or the walkthrough.

You can follow along with a detailed walkthrough or have a go with a very minimal example:

git clone https://github.com/metalsmith/metalsmith.git
cd metalsmith/examples/static-site
npm install
npm start

Build anything

We mainly refer to Metalsmith as a "static site generator", but it's a lot more than that. Since everything is a plugin, the core library is just an abstraction for manipulating a directory of files.

Which means you could just as easily use it to make...


Deploy anywhere

Metalsmith builds are static folders. They can be compressed, archived, deployed to a CDN, Netlify, Github Pages, Gitlab Pages, SFTP'd to a shared host, or SSH'd to a custom server.


Showcase

Built with Metalsmith


Use a starter