From 46016b078685c024a513b92151d976e2053483eb Mon Sep 17 00:00:00 2001 From: lanyuanxiaoyao Date: Sat, 28 Mar 2026 12:59:45 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=9E=84=E5=BB=BA=E8=BE=93=E5=87=BA?= =?UTF-8?q?=E6=8C=89=E6=97=A5=E6=9C=9F=E5=91=BD=E5=90=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 添加 dailyVersioning Vite 插件,将构建输出从 index.html 改为 grandclaw-archtype-YYYYMMDD.html 格式 --- openspec/specs/build-output-naming/spec.md | 26 ++++++++++++++++++++++ vite.config.js | 25 ++++++++++++++++++++- 2 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 openspec/specs/build-output-naming/spec.md diff --git a/openspec/specs/build-output-naming/spec.md b/openspec/specs/build-output-naming/spec.md new file mode 100644 index 0000000..88fc9c1 --- /dev/null +++ b/openspec/specs/build-output-naming/spec.md @@ -0,0 +1,26 @@ +### Requirement: 构建输出文件命名 + +系统 SHALL 在执行 `pnpm build` 时,将输出文件命名为 `grandclaw-archtype-YYYYMMDD.html` 格式,其中 YYYYMMDD 为构建当天的本地日期。 + +#### Scenario: 标准构建输出 +- **WHEN** 执行 `pnpm build` 命令 +- **THEN** dist 目录中生成文件名为 `grandclaw-archtype-YYYYMMDD.html` 的单文件 HTML +- **AND** 文件名为当天本地日期(如 2026年3月28日 构建则输出 `grandclaw-archtype-20260328.html`) + +#### Scenario: 同日多次构建 +- **WHEN** 同一天内多次执行 `pnpm build` +- **THEN** 每次构建输出覆盖同一天的文件 +- **AND** dist 目录中只存在一个文件 + +#### Scenario: 跨天构建 +- **WHEN** 不同日期执行 `pnpm build` +- **THEN** 每次构建生成当天日期命名的文件 +- **AND** 历史文件被清空(Vite 默认行为,emptyOutDir: true) + +### Requirement: 零额外依赖 + +构建输出命名功能 SHALL 通过自定义 Vite 插件实现,不引入额外的 npm 依赖。 + +#### Scenario: 依赖检查 +- **WHEN** 查看 package.json 的 dependencies 和 devDependencies +- **THEN** 不存在为文件命名功能新增的依赖项 diff --git a/vite.config.js b/vite.config.js index f5052fd..6a53196 100644 --- a/vite.config.js +++ b/vite.config.js @@ -1,9 +1,32 @@ import { defineConfig } from 'vite' import react from '@vitejs/plugin-react' import { viteSingleFile } from 'vite-plugin-singlefile' +import { renameSync } from 'node:fs' +import { join } from 'node:path' + +function dailyVersioning() { + return { + name: 'daily-versioning', + enforce: 'post', + writeBundle(options, bundle) { + const now = new Date() + const date = now.getFullYear() + + String(now.getMonth() + 1).padStart(2, '0') + + String(now.getDate()).padStart(2, '0') + + const oldPath = join(options.dir || 'dist', 'index.html') + const newName = `grandclaw-archtype-${date}.html` + const newPath = join(options.dir || 'dist', newName) + + if (bundle['index.html']) { + renameSync(oldPath, newPath) + } + } + } +} // https://vite.dev/config/ export default defineConfig({ base: './', - plugins: [react(), viteSingleFile()], + plugins: [react(), viteSingleFile(), dailyVersioning()], })