基于 Astro + React + TailwindCSS 的静态图库项目。
当前实现目标:
- 静态构建输出,构建后直接部署
dist/ - 本地文件夹导入图片,自动生成缩略图和元数据
- Astro
ClientRouter带来的无整页刷新切页体验 - Pagefind 静态搜索
- 图片详情页展示文件信息与 EXIF 信息
- 列表 / 平铺双视图
- 大量图片场景下的前端虚拟滚动
项目现在只使用 本地图片工作流,不再使用远程图片或手写 gallery.entries.json。
图片来源目录:
public/gallery/你可以直接在这里创建子文件夹,例如:
public/gallery/DCIM/
public/gallery/壁纸/
public/gallery/memes/reaction/构建时会递归扫描整个 public/gallery/。
构建脚本会自动生成:
- 静态页面:
dist/ - Pagefind 索引:
dist/pagefind/ - 缩略图:
public/generated/thumbs/ - 可选的净化后图片:
public/generated/images/ - 元数据:
src/data/gallery.generated.json
安装依赖:
pnpm install开发:
pnpm dev构建:
pnpm build预览:
pnpm preview类型检查:
pnpm check执行 pnpm build 时,流程如下:
- 递归扫描
public/gallery/ - 读取图片尺寸、时间、EXIF
- 按需生成 / 更新缩略图
- 按配置决定是否清理 EXIF 字段
- 按配置决定是否输出净化后的可访问大图
- 生成
src/data/gallery.generated.json - Astro 生成静态详情页和主页
- 对
dist/运行 Pagefind
详情页不是随机路径。
当前规则是:
/image/相对目录/文件名去扩展名-shortHash/例如:
public/gallery/DCIM/IMG_20250118_225208.jpg会生成:
/image/DCIM/img-20250118-225208-25938a/说明:
- 路径中的目录部分来自图片在
public/gallery/下的相对目录 - 文件名会先转成 URL 友好的 slug
- 末尾固定追加基于相对路径生成的短 hash
- 只要文件路径不变,详情页 URL 就保持稳定
- 如果你直接替换同路径图片文件,详情页地址不会变
根目录提供配置文件:
gallery.config.mjs当前配置示例:
export default {
privacy: {
redactExif: {
gps: false,
device: false,
},
sanitizeImageOutput: false,
},
};含义:
privacy.redactExif.gps生成元数据时移除 GPS 字段,页面也不会显示 GPS 信息privacy.redactExif.device生成元数据时移除设备相关字段,例如Make / Model / LensModelprivacy.sanitizeImageOutput开启后,前台访问的原图会改为构建时重新输出的净化版图片,而不是直接暴露public/gallery/中的原文件
区别:
- 只开
redactExif:只是页面和生成 JSON 不显示这些字段,原图片文件本身的元数据仍可能存在 - 开
sanitizeImageOutput:会生成新的可访问图片文件,用于降低原图元数据直接暴露的风险
搜索使用 Pagefind。
构建后会在:
dist/pagefind/生成索引。
首页搜索框优先使用 Pagefind;如果运行环境无法正常加载 Pagefind,也会退回到前端本地数据搜索。
picbed/
├─ public/
│ ├─ gallery/ # 本地图片源目录
│ └─ generated/
│ ├─ thumbs/ # 构建生成的缩略图
│ └─ images/ # 可选:净化后的图片输出
├─ scripts/
│ └─ prepare-gallery.mjs # 扫描图片并生成元数据
├─ src/
│ ├─ components/
│ ├─ data/
│ │ ├─ gallery.ts
│ │ └─ gallery.generated.json
│ ├─ layouts/
│ └─ pages/
│ ├─ index.astro
│ └─ image/[...slug].astro
├─ gallery.config.mjs
└─ package.json构建输出目录:
dist/这是一个纯静态站点,部署时只需要上传 dist/。
安装 pnpm(如果需要):
npm install -g pnpm安装项目依赖:
pnpm install如果需要部署到 Cloudflare Workers(静态),登录 Cloudflare:
pnpm wrangler login确保图片已经放进:
public/gallery/然后执行:
pnpm build直接部署本地构建产物:
pnpm wrangler deploy如果你不想把原图上传到 GitHub,这就是推荐流程:
git clone https://github.com/CLN-Grated/pico-gallerynpm install -g pnpmpnpm install- 把图片放进
public/gallery/ pnpm buildpnpm wrangler loginpnpm wrangler deploy
public/gallery/默认在.gitignore中,不会提交到仓库public/generated/和src/data/gallery.generated.json也是构建产物,不建议提交- 如果你开启了
sanitizeImageOutput: true,公开站点访问到的是净化了位置信息相机型号等信息后输出的图片,而不是原始图片