2025:我发布了 3 个 OSS 项目 — “这其实没问题”

发布: (2025年12月31日 GMT+8 14:08)
9 min read
原文: Dev.to

I’m ready to translate the article for you, but I don’t have the text of the post itself. Could you please paste the content you’d like translated (excluding the source line you already provided)? Once I have the text, I’ll translate it into Simplified Chinese while preserving all formatting, markdown, and technical terms.

大家好!

我是一名前端工程师,@nyaomaru

最近为了减肥,我背着 10 kg 以上的背包散步,感觉像《龙珠》里龟仙人的修行 🐢。
又一年在不知不觉中飞逝……
已经是年末了。

年末我们有 大扫除、购物和反思

在日语里,十二月叫 “师走(Shiwasu)”,意为“连老师都忙得要跑”。
而我已经跑得像一块彻底磨损的破布。

总之,让我们在今年之内把今年的烂摊子 清理 干净,并顺便整理一下思路 🧹。
所以,我想从我发布的 OSS 项目角度回顾 2025

注意: 这里没有病毒式成功的案例。

🎯 我在 2025 年发布的 OSS 项目

今年我发布了以下三个 OSS 项目:

项目截图仓库
is-kitis‑kit screenshot
changelog-botchangelog‑bot screenshot
dividerdivider screenshot

我会继续维护并发布它们的更新。

🤔 我为什么要构建它们?

简而言之:因为我自己需要

项目动机
is-kit“一定有更简洁的方式来编写用户自定义类型守卫……”
changelog-bot“每次都要写 CHANGELOG.md 实在太烦人了……”
divider“我只想更干净地分割字符串……”

每个项目都源于一点小小的烦恼。我问自己,“我该如何消除这种不适感?”,于是开始动手构建。

当然,看到别人使用你的 OSS 很棒,但我的核心关注点始终是:它能否很好地解决我自己的问题?

下面简要回顾每个项目。

Source:

is-kit

如果你使用 TypeScript,可能经常会编写用户自定义的类型守卫。

使用 is-kit 之前

type User = {
  id: string;
  age: number;
  role: 'admin' | 'guest' | 'trial';
};

function isUser(value: unknown): value is User {
  if (typeof value !== 'object' || value === null) return false;

  const record = value as Record;
  return (
    typeof record.id === 'string' &&
    typeof record.age === 'number' &&
    (record.role === 'admin' ||
      record.role === 'guest' ||
      record.role === 'trial')
  );
}

我一直在想:“能不能更简单点?”

于是 LEGO 块 的想法浮现出来:把小的逻辑片段组合起来,构建复杂的守卫。

使用 is-kit 之后

import { struct, isString, isNumber, oneOfValues } from 'is-kit';

const isUser = struct({
  id: isString,
  age: isNumber,
  role: oneOfValues('admin', 'guest', 'trial'),
});

更具声明式、更易读,并且仍然保持类型安全——听起来不错,对吧?

你还可以进一步组合守卫:

import { and, narrowKeyTo, predicateToRefine } from 'is-kit';

type AdminUser = Readonly & { role: 'admin' };

const byRole = narrowKeyTo(isUser, 'role');
const isAdminUser = byRole('admin');

const isAdultAdmin = and(
  isAdminUser,
  predicateToRefine((user: AdminUser) => user.age >= 18)
);

is-kit 的亮点

  • 很多朋友查看了项目并给了星标——非常感谢 🙏🙏🙏
  • 发现了 tsd,一个用于测试 TypeScript 类型定义的库,使用起来真的很有趣。
  • API 保持相当简洁,总体上我对它的实现很满意。

计划中的改进

  • 更多原始类型的预设
  • 更多组合子
  • struct 的进一步增强

如果你喜欢它,欢迎点个 ⭐️!

目标从来不是魔法——而是可组合性和可读性。

changelog-bot

当你发布一个 OSS 项目时,通常会编写发行说明并更新 CHANGELOG.md
但… 这有点麻烦,对吧?对我来说尤其如此 🤮

有一些工具可以根据 Conventional Commits 生成 changelog,但我在想:

“AI 能否根据内容对更改进行分类?”

这个问题催生了 changelog-bot

你可以通过 CLI 使用 OpenAI 或 Anthropic 的 API 密钥来运行它(AI 是可选的)。

(此处省略了进一步的细节——原文继续提供使用示例、实现效果以及未来计划。)

结束语

2025 年是我个人 OSS 工具箱的丰收之年。
即使没有病毒式的成功,每个项目都为我解决了真实的痛点,社区的反馈也一直激励着我。

2026 更加整洁、有序——无论是代码还是生活! 🎉

祝清理愉快,编码顺利!

CI‑驱动的变更日志更新

它主要设计用于在 CI 中运行。

一旦发布了新版本,您的 CHANGELOG.md 可以自动更新。

name: Update Changelog

on:
  release:
    types: [published]

jobs:
  changelog:
    runs-on: ubuntu-latest
    permissions:
      contents: write
      pull-requests: write
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - uses: nyaomaru/changelog-bot@v0
        with:
          changelog-path: CHANGELOG.md
          base-branch: main
          provider: openai
          release-tag: ${{ github.event.release.tag_name }}
          release-name: ${{ github.event.release.tag_name }}
        env:
          OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

如果需要,也可以通过 CLI 在本地运行。详细信息请参见 README

使用 changelog‑bot 的良好体验

  • 完全消除了在项目中手动维护 CHANGELOG.md 的工作量。
  • 发布变得更加轻松 🚀
  • 我个人很享受设计预处理逻辑——在将数据传递给 AI 之前提取并打分特征的过程。

当然,仍有改进空间,欢迎贡献代码!

需要说明的一点:
编写变更日志变得更容易了。但… 生活本身并没有神奇地变得更轻松
这一点仍在观察中。

GitHub – changelog‑bot

divider – 更简洁的字符串切片方式

有时你会一次又一次地使用 substring 来切片字符串,代码会变得很乱。
我想要一种更简洁的方式,于是构建了 divider,它让你可以一次性使用索引来分割字符串。

import { divider } from '@nyaomaru/divider';

const [a, b, c] = divider(text, 3, 6);

我从 divider 中学到的东西

  • 有一位优秀的工程师参与贡献,我由衷感激 🙏
  • 我学会了开源项目的基本规范:CODE_OF_CONDUCT.mdCONTRIBUTING.mdCHANGELOG.mdDEVELOPER.md 等等。

然而,项目也有明显的不足:我无法展示出相较于 string.split() 的显著优势。
这也体现在星标数量上,老实说,这是一次设计失误。

简而言之,这个项目是一次 “有用的失败”。
尽管如此,它仍然是一次宝贵的学习经历,我很高兴自己完成了它。

GitHub – divider

✨ 2026 年目标

2025 年亮点

  • 发布了 OSS 项目
  • 开始撰写技术文章
  • 搬到荷兰 🇳🇱

这是充满新挑战的一年。

展望 2026 年

  • 发布与 DSA 相关的 OSS 应用
  • 发布一个小型游戏项目

但最重要的是,我的主要目标很简单:

不要倦怠。继续前进。 🏃‍♂️

这适用于 OSS、系统以及生活本身。

感谢阅读,祝你来年顺利。
2026 年见 🐈

Back to Blog

相关文章

阅读更多 »

React 编码挑战:卡片翻转游戏

React 卡片翻转游戏 – 代码 tsx import './styles.css'; import React, { useState, useEffect } from 'react'; const values = 1, 2, 3, 4, 5; type Card = { id: numb...