已发布 上游基线 bf46254 原文 ↗ 在 GitHub 编辑

开发者工具

借助 Effect Language Service 与官方的 VS Code/Cursor 扩展,获得高级诊断、重构和智能代码补全,全面提升你的 Effect 开发体验。

Effect 提供了一系列强大的开发工具,用来提升你的编码体验,帮助你编写更安全、更易维护的代码。这些工具会直接集成到你的编辑器中,提供实时反馈、智能重构以及有用的诊断信息。

Effect LSP

Effect LSP 用 Effect 专属功能扩展了你的编辑器。它会分析你的 Effect 代码,并通过诊断、快速信息、代码补全和自动重构来提供智能辅助。

它可以在支持标准 TypeScript LSP 的编辑器中工作,例如 Code、Cursor、Zed、NVim 等。

安装

要在你的项目中安装 Effect Language Service:

    1. 将包安装为开发依赖:

      对于 monorepo,我们建议在根目录层级安装该语言服务。对于单包项目,请在包目录中安装。

      npm
      npm install @effect/language-service --save-dev
      pnpm
      pnpm add -D @effect/language-service
      Yarn
      yarn add --dev @effect/language-service
      Bun
      bun add --dev @effect/language-service
    2. 将插件添加到你的 tsconfig.json

      {
        "compilerOptions": {
          "plugins": [
            {
              "name": "@effect/language-service"
            }
          ]
        }
      }
    3. 确保你的编辑器使用工作区的 TypeScript 版本:

      这一步对语言服务能否正常工作至关重要。插件必须运行在你项目所安装的 TypeScript 版本上,而不是编辑器内置的版本。

      提示

      在 VS Code 或 Cursor 中,你可以打开一个 TypeScript 文件,点击状态栏中的 TypeScript 版本号,然后选择 “Use Workspace Version”,即可选用工作区的 TypeScript 版本。

    4. 现在你可以开始上手了!

      在你的项目中新建一个 file.ts 并写入以下代码,应该会出现一条错误诊断,提示 Effect 必须被 yield 或赋值给变量:

      import { Effect } from "effect"
      
      Effect.log("Hello world!")
      // ^- should be run or assigned to a variable!

功能特性

Effect Language Service 提供了一整套完善的功能,用来提升你的开发工作流:

智能快速信息

将鼠标悬停在 Effect 值上,即可查看扩展的类型信息和详细的洞察:

  • Effect 类型:查看 Effect 值的完整类型信息
  • Generator 参数:在 Effect.gen 中悬停在 yield* 上时,查看所 yield 值的详细信息
  • Layer 组合:借助交互式图表可视化 Layer 依赖,展示各个 Layer 是如何组合在一起的
  • Service 依赖:一眼看清服务的需求以及它们之间的依赖关系

实时诊断

在编写代码时及时发现常见错误和潜在问题:

  • 游离的 Effect:检测未被赋值或未 yield 的 Effect 值,避免出现静默 bug
  • Layer 问题:在运行前捕获 Layer 需求泄漏和作用域违规
  • 不必要的代码:识别多余的 Effect.genpipe() 调用
  • 错误处理:检测在不会失败的 Effect 上误用 catch 函数的情况
  • 版本冲突:检测项目中是否存在多个 Effect 版本

智能补全

借助上下文感知的建议加快编码速度:

  • Generator 样板代码:快速生成 Effect.gen 函数骨架
  • 脚手架:用于 Effect.ServiceData.TaggedError 以及类似结构。
  • Self 参数:为服务声明中的 Self 参数提供自动补全

强大的重构

通过智能自动重构来改造你的代码:

  • Async 转 Effect:使用 genfn 语法将 async 函数转换为 Effect
  • 错误生成:从基于 Promise 的代码生成 tagged error
  • Service 访问器:自动实现服务访问器函数
  • Pipe 转换:将函数调用转换为 pipe 语法
  • Pipe 风格:在不同的 pipe 风格格式之间切换
  • Layer 魔法:自动按正确的依赖关系组合 Layer

配置

Effect LSP 还提供了大量配置选项,例如修改严重级别或禁用某些诊断消息。

要查看完整的选项与功能列表,请访问 LSP 仓库的 README

构建时诊断

LSP 只在编辑会话期间生效,而你可能希望在构建过程中也能捕获诊断信息。

通常这是通过 lint 规则实现的,但由于几乎所有 Effect 诊断都依赖于类型,这就意味着要启用类型感知的 lint,也就是要对项目文件再次进行类型检查。

为了解决这个问题,Effect Language Service 允许你为本地安装的 TypeScript 打补丁,从而在进行类型检查时一并给出诊断信息。

要启用它,请运行以下命令来修改你本地安装的 TypeScript:

effect-language-service patch

要让所有开发者都自动完成这一步,请把它加到你的 package.json 中:

{
  "scripts": {
    "prepare": "effect-language-service patch"
  }
}

这样可以确保语言服务在使用标准 tsc 命令编译时也会运行。

VS Code / Cursor 扩展

注意

编辑器扩展并不包含 Effect LSP! Effect LSP 的安装应当按项目分别进行, 这样可以精细地控制何时加载它、为哪些项目加载, 以及使用由仓库 lockfile 固定下来的版本。

编辑器扩展提供了一些实用工具,帮助你调试 Effect 应用。

目前只支持 Code 以及像 Cursor 这样的 Code 分支。

安装

你可以在编辑器的扩展页面中直接搜索安装该扩展,也可以从 Code MarketplaceOpen VSX Marketplace 安装。

调试器功能

使用 Effect 扩展后,你会在编辑器的 Debug 区域中看到几个新的小节,当你暂停执行时,它们会显示相关信息。

  • Context:允许你查看当前暂停的 Effect Fiber 的上下文。
  • Span Stack:显示引导你进入当前暂停的 Effect 执行的遥测 span 堆栈。
  • Fibers:列出应用中正在运行的所有 Effect Fiber,允许你查看诸如可中断性等信息,并允许请求中断它们。
  • Breakpoints:启用 “pause on defect”,让调试器在某个 Effect Fiber 因 defect 而失败时暂停。

内置 Tracer 与 Metrics

内置的 tracer 与 metrics 视图可以让你无需启动整套遥测服务,就能快速查看应用中的 Effect Span 与 Metric。

要启用它,你需要在项目中安装以下依赖:

npm
npm install @effect/experimental
pnpm
pnpm install @effect/experimental
Yarn
yarn add @effect/experimental
Bun
bun add @effect/experimental

然后你就可以在 Effect 应用中导入并使用 DevTools 模块:

import { DevTools } from "@effect/experimental"
import { NodeRuntime, NodeSocket } from "@effect/platform-node"
import { Effect, Layer } from "effect"

const program = Effect.log("Hello!").pipe(
  Effect.delay(2000),
  Effect.withSpan("Hi", { attributes: { foo: "bar" } }),
  Effect.forever,
)
const DevToolsLive = DevTools.layer()

program.pipe(Effect.provide(DevToolsLive), NodeRuntime.runMain)

如果你的项目中使用了 @effect/opentelemetry,那么务必在你的 tracing layer 之前提供 DevTools layer,这样 tracer 才能被正确地打补丁。

现在同时启动你的编辑器和应用。在 Effect 面板的 clients 区域中,你会看到一个新连接的客户端。

在编辑器底部、终端附近,还会出现一个新的 “Effect Tracer” 标签页,以可视化的方式实时展示你的 span。