原文地址: https://evertpot.com/node-changelog-cli-tool/
作者: Evert Pot
发布时间:2023-02-13
只使用 Node.js 的标准库,不安装任何外部依赖,写一个命令行工具。
前言
作者是多个开源项目的维护者,长久以来都是手动维护项目的变更日志(changelog
)。
下面是项目 a12n-server 的变更日志示例:
0.22.0 (2022-09-27)
-------------------
Warning note for upgraders. This release has a database migration on the
`oauth2_tokens` table. For most users this is the largest table, some
downtime may be expected while the server runs its migrations.
* #425: Using a `client_secret` is now supported with `authorization_code`,
and it's read from either the request body or HTTP Basic Authorization
header.
* The service now keeps track when issuing access tokens, whether those tokens
have used a `client_secret` or not, which `grant_type` was used to issue them
and what scopes were requested. This work is done to better support OAuth2
scopes in the future, and eventually OpenID Connect.
* Fixed broken 'principal uri' in introspection endpoint response.
* OAuth2 service is almost entirely rewritten.
* The number of tokens issued is now displayed on the home page.
* Large numbers are now abbreviated with `K` and `M`.
* #426: Updated to Curveball 0.20.
* #427: Typescript types for the database schema are now auto-generated with
`mysql-types-generator`.
内容使用markdown
编写的。你可能会想:Git不是有 commit
日志吗?为什么要费力手写这个呢?
原因是它们的受众不一样。我希望让用户关注到相对重要的变更事项,并同时注意到变化对用户带来的影响。
我觉得写一个命令行工具来做这些事会更方便,维护多个项目(如此多的变更)也更容易一些。所以,我就做了 changelog-tool!如果你想知道这背后涉及了哪些技术选择,请接着往下阅读。
目标&特色
工具已支持的功能:
- 重新格式化日志(有点像美化)(
changelog format
); - 通过命令行添加一行日志(
changelog add --minor -m "New feature"
); - 自动设置发布日期(
changelog release
); - 将特定版本的日志导入标准输出,以便其他工具可以使用(例如与GitHub发布集成)。
我还有一些非功能性的需求:
- 使用最新的
Node.js
特性; - 使用最新的
JavaScript
标准和特性(ESM); - 避免非必要的外部依赖;
- 低维护成本。
想立即找到这个工具吗?它是开源的,你只需访问 Github。
原理解析
ESM & Typescript ESM
ESM
模块现在使用起来已经非常丝滑了。这是习惯上的一个小改变,但我一般建议是将文件保存为 .mjs
来使用 ESM
。
下面是 parse.mjs
的前几行代码:
import { readFile } from 'node:fs/promises'
import { Changelog, VersionLog } from './changelog.mjs'
/**
* @param {string} filename
* @returns {Promise<Changelog>}
*/
export async function parseFile(filename) {
return parse(
await readFile(filename, 'utf-8')
)
}
CommonJS -> ESM 的过渡并非没有痛苦,但对于像这样的新项目来说,它是非常理想的选择。(顶层 await