发布于 2026-01-06 10 阅读
0

代码生成器简洁“黑客”

代码生成器简洁“黑客”

在本周的短文中,我想与大家分享一个巧妙的技巧,用于Plop 代码生成器,以克服“相对路径挑战”。

在软件开发领域,良好的开发者体验(DX)是提升开发速度和效率的关键因素。
拥有良好的开发者体验意味着开发者能够专注于核心任务,而其他一些次要的工作则由自动化工具来处理。Plop
就是这样一款工具我非常喜欢它的简洁性和高效性。


噗通

Plop 通过向开发人员提供一组指导性问题,并使用输入数据填充预定义的模板,帮助生成项目的脚手架文件。

在我之前的文章“创建 React 组件生成器”中,我描述了如何使用 Plop 在现有项目中生成 React 组件,该组件将包含组件文件、组件的 css 文件、Jest 测试、Storybook 故事和 Cypress 测试,只需将组件名称作为输入提供给该工具即可。

这是一个非常强大的工具,可以帮助中大型研发机构节省开发时间,同时保持所有组件的相同标准。

相对路径挑战

这个问题不仅适用于 Plop,也适用于任何文件/代码生成器。具体如下:

假设你有一个 monorepo,并且你想要一个包生成器来创建一个新包,并将其与 monorepo 可能具有的所有通用配置连接起来(你可以在这里这里阅读更多关于此类配置的示例)。

这些共享配置通常允许软件包从项目根目录继承通用配置,并在需要时进行扩展。我想你已经看出问题所在了——

Plop 使用的是 Handlebars 模板(.hbs 文件),它会注册文件的内容,以及一些来自开发者答案的动态数据,但在这里,我们处理的是配置文件路径,而这些路径取决于项目中包目录的位置——我们不希望我们的开发者处理这些,他们也不应该处理这些。

例如,如果我们查看我的 Pedalboard monorepo 下的 components 包,并检查其 TS 配置文件,您会发现它扩展了一个基本配置../../tsconfig.base.json

{
   "extends": "../../tsconfig.base.json",
   "compilerOptions": {
       "module": "CommonJS",
       "outDir": "dist/cjs",
       "declarationDir": "dist/types",
       "jsx": "react"
   },
   "files": ["index.ts"],
   "include": ["src/**/*"]
}
Enter fullscreen mode Exit fullscreen mode

但是,如果我们决定生成器允许我们在嵌套目录中创建软件包(这意味着不仅在“/packages”下,而且在“/packages/my/nested/package”下),那么 Plop 生成器将创建一个硬编码路径,该路径是损坏的。

那么我们该如何解决这个问题呢?我们如何创建一个能够生成相对路径的生成器?

解决方案

首先,我们假设 Plop 生成器会向开发者提出一个问题:“这个包在项目中的位置在哪里?”。
这个问题的答案以文件路径的形式给出,我们假设它会被赋值给 Plop 中名为“targetPath”的变量。

现在,为了计算相对路径,我们将使用 Handlebars Helper,这是一个可重用的代码,我们可以将其用于任何模板中,它将使用我们传递给它的参数执行。

我将把我们的辅助函数命名为“relativePath”,并将其注册到 Plop 中。以下是它的代码:

const path = require('path');

plop.setHelper('relativePath', (from, to)=>{
   const fromPath = `${from}/package`;
   return path.relative(fromPath, to);
});
Enter fullscreen mode Exit fullscreen mode

这个辅助函数接收两个参数:`
from`:用作基础路径的文件路径;`
to`:用于查找相对路径的文件路径。该函数将返回一个字符串,其中包含使用API
解析出的规范化路径 (这里我使用了一个名为“package”的虚拟包名,因为我们需要模拟包的嵌套路径。实际上,包名在这里并不重要。)path.relative

让我们看看如何在 Plop 的车把模板中实际使用它:

{
   "extends": "{{relativePath targetPath ./tsconfig.base.json}}",
   "compilerOptions": {
       "module": "CommonJS",
       "outDir": "dist/cjs",
       "declarationDir": "dist/types",
       "jsx": "react"
   },
   "files": ["index.ts"],
   "include": ["src/**/*"]
}
Enter fullscreen mode Exit fullscreen mode

我们调用 relativePath 函数,并将从开发者那里得到的“targetPath”(还记得吗?)和基本配置路径的位置传递给它。

现在生成的文件将包含根据其在项目树中的位置而定的正确路径。这虽然很简单,但却能帮你省去很多麻烦,比如“为什么我的新包无法解析到我的通用 Babel 配置路径?!”

总结

生成器,尤其是 Plop,是功能强大的工具,无需投入太多资源就能大大简化我们的开发工作。本文介绍了如何进一步增强 Plop 模板的健壮性。
和往常一样,如果您有其他提高文件和代码生成器效率的想法,或者对本文内容有任何疑问,欢迎在下方评论区与我们分享。

嘿!如果你喜欢刚才读到的内容,请关注推特账号@mattibarzeev 🍻

文章来源:https://dev.to/mbarzeev/code-generator-neat-hack-7hd