静筑 Apistatic
开源 CLI 工具,对接 api工厂开放 API,一键生成整套纯静态 HTML 站点。
产物可直接部署至 GitHub Pages、OSS、CDN 等任意静态空间,天然 SEO 友好,支持全量 / 增量构建、自定义 Nunjucks 主题模板、文章图片自动本地化。
目录
- 特性
- 快速开始
- 配置项详解
- CLI 命令
- 自定义模板教程
- 二次开发指南
- 常见问题 FAQ
- 开源协议
特性
- 零服务器:产物全部为纯 HTML,可部署至任意静态空间
- 增量构建:只重新渲染有变化的文章,海量内容场景高效构建
- 自动 SEO:生成
sitemap.xml、robots.txt、RSS 订阅文件 - 图片本地化:文章内远程图片自动下载到本地,告别图片失效
- 响应式主题:内置大气博客主题,PC / Pad / 手机完美自适应
- 多主题支持:基于 Nunjucks 模板引擎,可自由替换主题
- Markdown / HTML 双格式:自动识别文章内容格式,无需额外配置
- 富内容支持:Banner 轮播、文章分类、标签云、评论、友情链接、公告栏
快速开始
1. 安装
npm install -g apistatic
或在项目内本地使用:
git clone https://github.com/apistatic/apistatic.git
cd apistatic
npm install
2. 初始化配置
apistatic init
在当前目录生成 config.yaml,按注释填写参数即可。
3. 填写商户信息
打开 config.yaml,找到 api 配置块,分别填写 subDomain(专属域名)和 merchantId(商户ID):
api:
subDomain: "你的专属域名" # 在后台「工厂设置 → 专属域名」查看
merchantId: "你的商户ID" # 在后台「工厂设置 → 商户ID」查看(通常为纯数字)
注意:
subDomain和merchantId是两个不同的值,请分别查看后台对应配置项填写,不一定相同。快速测试:两个字段均可填写
180,再在「api工厂」后台 → 工厂设置 → 数据克隆 → 将别人的数据克隆给我 → 对方商户ID 填写180,将测试数据导入自己账号。
4. 构建站点
# 增量构建(默认,只更新变化页面)
apistatic build
# 全量重建
apistatic build --full
# 指定配置文件
apistatic build -c ./my-config.yaml
构建完成后,dist/ 目录即为完整的静态站点,直接上传部署即可。
配置项详解
config.yaml 完整说明:
# 站点基本信息
site:
title: "我的博客" # 站点标题
description: "站点简介" # 用于 meta description
url: "https://your-domain.com" # 站点根域名(不含末尾斜杠)
author: "作者昵称"
keywords: "博客,技术" # 全局关键词
footer: "© 2024 我的博客" # 页脚版权文字
language: "zh-CN"
postsPerPage: 10 # 每页文章数
logo: "" # 站点 logo 图片 URL(留空则只显示文字)
icp: "" # ICP 备案号
customPages: # 导航栏显示的单页面 key(在后台「单页面」中配置)
- "about"
# api工厂接口配置
api:
subDomain: "myblog" # 【必填】专属域名(用于 common.apifm.com 接口)
merchantId: "180" # 【必填】商户ID(用于 cms.apifm.com 接口,与 subDomain 不一定相同)
baseUrl: "https://api.it120.cc" # 一般无需修改
token: "" # 用户 token(公开内容无需填写)
timeout: 15000 # 请求超时(毫秒)
retries: 3 # 失败自动重试次数
retryDelay: 1000 # 重试间隔(毫秒)
# 构建配置
build:
outputDir: "./dist" # 静态网站输出目录
cacheDir: "./cache" # 构建缓存目录
template: "default" # 主题模板(对应 templates/ 下的文件夹名)
incremental: true # 默认使用增量构建
cleanOutput: true # 全量构建时先清空输出目录
articlesPageSize: 50 # 每次拉取文章数(最大 50)
# 资源处理
assets:
downloadImages: true # 是否下载远程图片到本地
imageDir: "images" # 本地图片存储目录名(在 dist/ 下)
compressImages: false # 图片压缩(需额外安装 sharp)
# SEO 配置
seo:
generateSitemap: true # 生成 sitemap.xml
generateRobots: true # 生成 robots.txt
generateRss: true # 生成 rss.xml
CLI 命令
# 查看版本
apistatic -v
apistatic --version
# 查看帮助
apistatic -h
apistatic --help
# 初始化配置文件
apistatic init
# 增量构建(默认)
apistatic build
# 全量重建,忽略缓存
apistatic build --full
# 指定配置文件路径
apistatic build -c ./custom-config.yaml
# 清空构建缓存与 dist 目录
apistatic clean
自定义模板教程
目录结构
每套主题放在 templates/<主题名>/ 目录下:
templates/
└── default/ # 默认主题
├── base.html # 公共布局(header / footer)
├── index.html # 首页
├── article.html # 文章详情页
├── list.html # 文章列表页(分类 / 标签)
├── archive.html # 归档页
├── page.html # 单页面
├── 404.html # 404 页面
└── sidebar.html # 侧边栏(被其他模板 include)
切换主题
- 复制
templates/default/为templates/my-theme/ - 修改
config.yaml中build.template: "my-theme" - 编辑模板文件,重新构建
模板变量
所有页面均可访问的全局变量:
| 变量 | 说明 |
|---|---|
site |
站点配置(title / description / url / logo 等) |
categories |
所有文章分类(含 articleCount) |
tags |
标签云数据(含 name / number) |
banners |
Banner 轮播图列表 |
links |
友情链接列表 |
recentArticles |
最新 5 篇文章(侧边栏用) |
notices |
系统公告列表 |
pages |
自定义单页面列表(导航栏) |
year |
当前年份(页脚版权年份) |
文章详情页额外变量:
| 变量 | 说明 |
|---|---|
article |
文章对象(id / title / content / pic / dateAdd / tags 等) |
comments |
评论列表 |
prevNext |
{ pre, next } 上一篇 / 下一篇 |
内置过滤器
{# 日期格式化 yyyy-MM-dd #}
{{ article.dateAdd | date }}
{# 中文日期 yyyy年M月d日 #}
{{ article.dateAdd | dateCn }}
{# 截取摘要(默认 150 字符) #}
{{ article.content | excerpt(120) }}
{# 自动渲染 Markdown 或 HTML #}
{{ article.content | renderContent | safe }}
二次开发指南
项目结构
apistatic/
├── bin/apistatic.js # CLI 入口(commander)
├── src/
│ ├── cli/ # init / build / clean 命令实现
│ ├── config/ # 配置加载与校验
│ ├── api-fetcher/ # api工厂接口封装(分页拉取、重试)
│ ├── data-cache/ # 增量构建缓存(JSON 快照 + hash 对比)
│ ├── renderer/ # Nunjucks 渲染引擎封装
│ ├── site-generator/ # 全流程构建调度器
│ ├── seo/ # sitemap / robots / RSS 生成
│ ├── asset-handler/ # 图片下载与路径替换
│ └── utils/ # logger / file / date / content 工具
├── templates/default/ # 默认博客主题(Nunjucks)
├── public/ # 全局静态资源(css / js)
├── dist/ # 构建产物(部署此目录)
└── cache/ # 增量构建缓存(JSON)
接口说明
ApiFetcher 封装了 api工厂三个服务域的接口:
| 服务 | 基础域名 | 用途 |
|---|---|---|
| API | api.it120.cc/{subDomain} |
Banner、公告、友链等 |
| Common | common.apifm.com/{subDomain} |
分类、配置、评论、标签等 |
| CMS | cms.apifm.com/{merchantId} |
文章列表、文章详情 |
扩展新接口只需在 src/api-fetcher/index.js 中添加方法:
// 示例:拉取广告位数据
async fetchAdPositions(keys) {
const res = await this.commonGet('/site/adPosition/batch', { keys });
if (!res || res.code !== 0) return [];
return res.data || [];
}
构建流程扩展点
src/site-generator/index.js 的 build() 方法即为完整流程,每个步骤均为独立方法,可按需重写:
build()
├── _fetchAllData() // 数据拉取
├── _buildGlobalContext() // 全局上下文组装
├── _renderHome() // 首页 + 列表分页
├── _renderCategoryPages() // 分类页
├── _renderTagPages() // 标签页
├── _renderArchive() // 归档页
├── _renderArticle() // 文章详情(含图片本地化)
└── seoGen.generate*() // SEO 文件
常见问题 FAQ
Q: 执行 apistatic build 提示"配置文件不存在"?
先执行 apistatic init 生成 config.yaml,编辑后再执行构建。
Q: 接口返回 code: 700 暂无数据,没有内容?
检查 api.subDomain 是否填写正确。可先在「api工厂」后台发布一篇测试文章,或使用数据克隆功能导入商户 180 的测试数据。
Q: 图片没有下载到本地?
确认 assets.downloadImages: true,且网络可以访问远程图片地址。构建日志中若有 ⚠ 图片下载失败 提示,说明该图片地址不可访问,会保留原始远程 URL。
Q: 如何部署到 GitHub Pages?
- 将
dist/目录内容推送到 GitHub 仓库的gh-pages分支 - 或配置 GitHub Actions,在每次 push 时自动执行
apistatic build并部署dist/
# .github/workflows/deploy.yml 示例
name: Build & Deploy
on:
push:
branches: [main]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: '20'
- run: npm install
- run: node bin/apistatic.js build --full
- uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./dist
Q: 如何部署到阿里云 / 腾讯云 OSS?
构建完成后,将 dist/ 目录整体同步到对应 OSS Bucket,配置静态网站托管即可。推荐使用 ossutil 或对应云厂商 CLI 工具。
Q: 增量构建没有生效,每次都是全量?
查看 cache/snapshot.json 是否存在。首次构建或执行 apistatic clean 后,缓存会被清空,下次构建自动变为全量构建。后续构建才会走增量逻辑。
Q: 文章内容乱码或格式异常?
api工厂文章内容支持 Markdown 和 HTML 两种格式,Apistatic 会自动识别。如仍有异常,可检查后台文章内容是否包含特殊字符,或在模板中使用 | safe 过滤器输出原始 HTML。
Q: 自定义主题模板找不到变量?
在开发主题时,可临时在模板中加入 {{ dump() }} 查看所有可用变量(Nunjucks 调试用)。详细变量列表参见模板变量章节。
开源协议
本项目使用 木兰宽松许可证 MulanPSL-2.0 开源。
Copyright (c) 2024 Apistatic Contributors
依据木兰宽松许可证,第2版("本许可证")获得许可;
除非符合本许可证,否则您不得使用本文件。
您可以在以下网址获取本许可证的副本:
http://license.coscl.org.cn/MulanPSL2