文章摘要
作者观察到许多CLI工具中重复出现繁琐的验证代码,尽管这些代码并不难写,但几乎每个项目都存在类似的问题。作者认为,这类问题在其他数据类型中早已解决,但CLI工具却仍未得到有效处理。因此,作者决定开发一个库,旨在一次性正确解析CLI输入,避免重复编写验证代码。
文章总结
标题:停止编写CLI验证代码,首次解析即正确
主要内容:
作者在阅读大量开源项目和工作代码时,发现几乎每个CLI工具都包含重复且繁琐的验证代码。这些代码通常用于检查选项之间的依赖关系、互斥选项以及环境特定需求等。尽管这些验证代码并不难写,但它们无处不在,且每个项目都有类似的模式。
作者指出,我们已经在其他类型的数据处理中解决了这个问题,例如通过使用Zod等工具直接解析JSON数据,而不是先解析为松散类型再进行验证。然而,CLI工具仍然采用先解析为属性包,再通过大量条件语句验证的方式,这种方式显得低效且容易出错。
为此,作者开发了一个名为Optique的CLI解析工具。Optique的核心思想是“解析而非验证”,即直接解析为有效的类型,而不是先解析再验证。通过这种方式,TypeScript可以自动推断出配置的类型,并在编译时捕获错误,从而减少运行时验证的需求。
Optique的主要特点:
依赖选项:通过描述选项之间的关系,TypeScript可以自动推断出哪些选项在特定条件下存在或不存在,无需手动编写验证代码。
互斥选项:使用
or()组合器确保用户只能选择一种输出格式,避免手动检查多个布尔值。环境特定需求:通过描述不同环境下的配置,解析器可以立即拒绝无效的配置,TypeScript也会阻止访问不存在的字段。
使用Optique的好处:
- 减少代码量:作者表示,使用Optique后,他删除了大量原本用于验证的代码。
- 重构更轻松:改变CLI参数的定义后,TypeScript会立即显示所有需要修复的地方,减少了重构的难度。
- 增加功能复杂性:由于添加复杂选项关系不再需要编写复杂的验证代码,CLI工具的功能变得更加丰富。
结论:
如果你经常编写CLI工具,并且厌倦了重复的验证代码,Optique可能是一个值得尝试的解决方案。它通过“解析而非验证”的方式,减少了手动验证的需求,并提高了代码的可靠性和可维护性。
相关资源:
作者强调,Optique并不是解决所有CLI问题的终极方案,但它确实让编写验证代码变得不再必要。
评论总结
评论主要围绕解析器(parser)的使用、设计和类型安全展开,观点多样且涉及不同编程语言和工具。以下是主要观点和论据的总结:
解析器的普遍性与重要性
- 有人认为解析器并非仅限于低层应用,程序员应经常编写解析器。
引用:
"Programmers should be writing parsers all the time!"
“程序员应该经常编写解析器!”
- 有人认为解析器并非仅限于低层应用,程序员应经常编写解析器。
命令行参数解析器的设计与实现
- 一些评论者提到使用解析器组合库(parser combinator)和类型生成技术(如TypeScript的元编程)来简化命令行参数解析。
引用:
"I like how it uses Typescript's metaprogramming to generate types from the parser code."
“我喜欢它使用TypeScript的元编程从解析器代码生成类型。”
- 一些评论者提到使用解析器组合库(parser combinator)和类型生成技术(如TypeScript的元编程)来简化命令行参数解析。
类型安全与运行时验证
- 讨论了在TypeScript等语言中,类型注解与运行时验证的关系,以及如何在IO场景中处理类型安全问题。
引用:
"In typescript-likes you can get a totally different structure and run into all sorts of errors."
“在类似TypeScript的语言中,你可能会得到一个完全不同的结构,并遇到各种错误。”
- 讨论了在TypeScript等语言中,类型注解与运行时验证的关系,以及如何在IO场景中处理类型安全问题。
解析与验证的哲学
- 提出了“解析而非验证”的理念,强调通过解析确保数据的合法性,而非事后验证。
引用:
"Parse, don't validate."
“解析,而非验证。”
- 提出了“解析而非验证”的理念,强调通过解析确保数据的合法性,而非事后验证。
现有工具与库的比较
- 评论者提到了多种命令行解析工具,如Python的argparse、TypeScript的Optique、Cliffy和Commander.js,并比较了它们的功能和易用性。
引用:
"It's a genuine pleasure to use, and I use it often."
“它使用起来非常愉快,我经常使用它。”
- 评论者提到了多种命令行解析工具,如Python的argparse、TypeScript的Optique、Cliffy和Commander.js,并比较了它们的功能和易用性。
错误处理与用户体验
- 讨论了如何在解析过程中生成友好的错误信息,以及如何处理用户输入中的多个问题。
引用:
"How do you create good error messages when you do this?"
“你如何在这种情况下生成友好的错误信息?”
- 讨论了如何在解析过程中生成友好的错误信息,以及如何处理用户输入中的多个问题。
设计原则与最佳实践
- 一些评论者提出了命令行参数设计的最佳实践,如避免选项之间的依赖关系,使用参数而非复杂选项等。
引用:
"Every option should be optional."
“每个选项都应该是可选的。”
- 一些评论者提出了命令行参数设计的最佳实践,如避免选项之间的依赖关系,使用参数而非复杂选项等。
总结:评论者普遍认可解析器在编程中的重要性,尤其是在命令行参数解析和类型安全方面。不同语言和工具的设计理念和实现方式各有优劣,但“解析而非验证”的理念得到了广泛支持。同时,错误处理和用户体验也是设计解析器时需要考虑的关键因素。