用 ChatGPT 快速解决编码问题
演示如何利用 ChatGPT 诊断和修复代码问题,涵盖包检查等实际场景。程序员可立即应用。
演示如何利用 ChatGPT 诊断和修复代码问题,涵盖包检查等实际场景。程序员可立即应用。
简单来说,我需要在运行时检查一个 Node 包是否已安装。原因是我正在基于 Prisma 构建一个新工具包 ZenStack,它提供了强大的访问控制层和 API 生成功能。由于 ZenStack 是建立在 Prisma 之上的,当运行 ZenStack 提供的 CLI 时,必须检查 Prisma 是否已经安装。否则,它会提示用户先安装 Prisma。
让我们直接问 ChatGPT:
很好!答案看起来很有说服力。问题解决了!
它确实有效,但它带来了一个副作用。在我的 CLI 项目中,我使用 async-exit-hook 来处理未捕获的错误,如下所示:
// You can hook uncaught errors with uncaughtExceptionHandler(), consequently adding
// async support to uncaught errors (normally, uncaught errors result in a synchronous exit).
exitHook.uncaughtExceptionHandler(err => {
console.error(err);
});
在 require('prisma') 成功执行后,这意味着 Prisma 已安装,如果之后在其他代码中抛出任何未捕获的异常,uncaughtExceptionHandler 将永远不会被触发。但是如果它需要任何其他现有模块,如 require('uuid'),那么 uncaughtExceptionHandler 仍然会像以前一样被触发。
虽然我还没有找到真实原因,但从上面的情况来看,似乎 Prisma 被导入时会执行某些代码。我不确定 Prisma 是否提供了任何标志来控制它;即使提供了,这对我来说仍然不像一个干净的解决方案,因为这就像打开了潘多拉的魔盒。你不知道会执行什么。
避免副作用的最直接方法是使用单独的进程。那么,如果这项工作分配给你,你会怎么做?我会使用 npm 命令。所以让我们再次请教无所不知的 ChatGPT:
这对我来说看起来是一个干净的解决方案。
作为好的开发者,我们应该总是尝试进一步思考。如果 npm 命令没有安装或已损坏怎么办?如果我们知道 npm 如何找到模块,我们可以自己做。
由于 npm 命令显然不会为包执行任何代码,它确实找到了名称和版本,如答案所示:
它将显示所有已安装包的名称和版本
那么,它从哪里获取版本信息呢?当然,从 package.json 文件。实际上,您可以通过在 node_modules 下创建 dummy-package 文件夹,然后创建具有以下内容的 package.json 文件来轻松验证:
{
"name": "dummy-package",
"version": "9.9.9"
}
然后,运行 npm list --depth=0 dummy-package 后,你可以看到包信息:
helloworld@1.0.0 /Users/jiasheng/branch/helloworld
└── dummy-package@9.9.9 extraneous
因此,与其像原始解决方案那样导入模块,我们可以改为导入 package.json 文件,如下所示:
const prisma:any = require('prisma/package.json')
它不仅消除了副作用,而且你还可以获得关于该包的更多信息,如版本等。
无论如何,你可以看到 ChatGPT 确实可以帮助我们很多,甚至为我们编写代码,但真正深入思考和解决问题的是我们自己。谈到 AI 会替代开发者的想法,我认为 Google 应该为此担心,而不是我们。😉
Anthony 留下了一条评论,提出了使用 ChatGPT 的一个"副作用":"虽然 ChatGPT 帮助你解决了问题,但你仍然没有真正理解发生了什么",我非常同意。因此,我稍微调查了一下 Prisma 的源代码。事实证明,ChatGPT 给出的第一个解决方案的副作用是,当 Prisma 被导入时,它在下面这一行注册了 unhandledRejection 事件处理器:
https://github.com/prisma/prisma/blob/main/packages/cli/src/bin.ts#L57
process.on('unhandledRejection', (e) => {
debug(e)
})
之后抛出的异常在 Promise 处理器中,所以它被这个事件处理器拦截了。因此,另一种解决方法是也使用 exitHook 注册 unhandledRejection 事件处理器,如下所示:
// You can hook unhandled rejections with unhandledRejectionHandler()
exitHook.unhandledRejectionHandler(err => {
console.error(err);
});
但我仍然坚持使用导入 package.json 的解决方案,因为它完全没有副作用。😁
ZenStack 是我们的开源 TypeScript 工具包,用于更快、更智能、更愉快地构建高质量、可扩展的应用。它在 Prisma 之上的单个声明式 schema 中集中了数据模型、访问策略和验证规则,非常适合 AI 增强开发。现在开始将 ZenStack 集成到你现有的堆栈中!
如需进一步操作,您可以考虑屏蔽此人和/或举报滥用