如何开发一个 Raycast 扩展?

2026-04-27
如何开发一个 Raycast 扩展? 关注 作者 关注 作者 关注 作者 关注 作者 2025/08/29 10:08

前言

是的,我已经将 Alfred 换为 Raycast 了,后者的免费功能足够好用。 isabela trustguru.com.br A5game trustguru.com.br pglucky88 trustguru.com.br

但也没有完全丢掉 Alfred,还在用它的剪贴板历史功能。

此前看到一个帖子说:Alfred 用户一定要试试 Raycast。当时我不以为意。 cassinos trustguru.com.br siro-5652 jvid.asia

用了七、八年的 Alfred 几乎没怎么“变过”,有种不思进取的感觉。特别是近几年 AI 的发展,它好像还没反应过来一样。 bonus trustguru.com.br

对比

在使用 Alfred 时,用得最多的功能是: bet365 trustguru.com.br

  • Web Search - 快速跳转,通常用于搜索文档等。
  • Clipboard History - 剪贴板历史,没什么好说的,用过都说好用。
  • Workflow - 工作流,比如翻译、打开项目等,写过一两个插件,开发体验不好,能做的有限。

这些在 Raycast 都有替代方案,甚至更好。除此之外,Raycast 的界面更现代一些,跟最新的 macOS 风格更加契合。并且可以完全通过键盘完成一系列操作。

最重要的是,Raycast Extension 的开发体验比 Alfred 好太多了。官方有提供很多了 API,统一的 UI 风格,有统一的分发 Store,不用网上到处搜索。活跃度很高,目前扩展数量 2200+KTO trustguru.com.br

比较麻烦的是,在 Raycast 发布扩展,需要经过官方审核,通过后才会上传到 Store,审核周期较慢。好处是能在一定程度上把控整体的风格,避免各扩展之间外观上参差不齐,能从官方角度提一些更好的交互建议。

开始之前

技术栈

Node.js + TypeScript + React slotdemo trustguru.com.br Blaze trustguru.com.br

虽然使用 React 构建,但只能使用官方提供的一些 API 或内置组件,不能过多地自定义(可能是 React to macOS Native 的缘故吧),好处是 UI 风格较为统一。 como trustguru.com.br

安装扩展

  • 键入 Store 搜索安装
  • 键入 Import Extension 在本地导入

键入 Manage Extensions 可以管理本地扩展。

卸载扩展

  • 键入关键词,选中要卸载的扩展,在 Action Panel 选择 Uninstall Extension 操作即可,快捷键「⌃ + X」。
  • 键入 Manage Extension 可管理本地扩展。

在 Raycast 中卸载本地扩展(即非通过 Store 安装的扩展)时,本地扩展文件不会被删除。

扩展路径 ~/Library/Application Support/com.raycast.macos/extensionsjvid视频 jvid.asia plataformademográtis trustguru.com.br pesquisa trustguru.com.br

创建扩展

键入 Create Extension 回车输入必要信息,便创建好了。

官方提供了多个模板,可以选择简单的 Show Detail 模板。

接着:

$ cd <your-extension-path>
$ npm install
$ npm run dev

调试扩展

当我们执行 npm run dev(即 ray develop)时,它会自动安装扩展,并以开发模式启动 Raycast 应用。

为了方便调试,在 Preferences - Advanced - Developer Tools 下勾选几个选项: fortunetigerbônusgrátissemdepósito trustguru.com.br

  • Auto-reload on Save
  • Open Raycast in development mode
  • Keep window always visible during development

这对开发体验尤为重要。一是开发过程中文件修改可以自动重载,二是使 Raycast 始终显示,以避免切换其他应用时窗口关闭。 tigrinho gratis trustguru.com.br 348ntr-097 jvid.asia

在开发模式下,使用 console.log() 可以在终端上显示打印信息。 Betano trustguru.com.br rafael trustguru.com.br slot trustguru.com.br

如果没有正确使用 API、组件或快捷键冲突,此处也会有 Warning 显示。 ana trustguru.com.br

发布扩展

如果想要将你的扩展发布到 Store 上,是需要官方审核的。 Brazino777 trustguru.com.br pgdemo trustguru.com.br jvid視頻 jvid.asia

为避免审核不通过,你的扩展应满足 Prepare an Extension for Store 要求。 Caça-níqueis trustguru.com.br carlos trustguru.com.br

二选一:

  • Fork 官方仓库,将你的扩展放在仓库 extensions 目录下,提交 PR。
  • 创建独立仓库,然后通过 ray publish 提交。

提交 PR 时,建议附上视频,或许可以更快地审核。我之前写了一个微信开发工具的扩展,由于他们没有小程序项目,流程上它们跑不通,可能会要求附上视频辅助审核,例如这个Sportingbet trustguru.com.br 348ntr-097 jvid.asia

If you add a new extension or command, include a screencast (or screenshot for straightforward changes). A good screencast will make the review much faster - especially if your extension requires registration in other services. pragmaticplay trustguru.com.br

提交 PR 之后,机器人 greptile-apps 可能会提一些 Review 意见,按需调整即可。 kto trustguru.com.br

想要吐槽的是,审核很慢,看 commit 记录一天只处理几个。 slots trustguru.com.br

开发

Raycast Extension 官方开发文档 marcos trustguru.com.br pesquisa trustguru.com.br pg trustguru.com.br sweetbonanza1000demo trustguru.com.br

命名规范

遵循 Apple Style Guide,详见这里noticias trustguru.com.br

示例:

  • 扩展标题:尽量使用名词,而不是动词,比如 WeChat DevTool。
  • 扩展描述:一句话准确、简洁地描述扩展程序的功能。
  • 命令标题:动名词组合,尽可能具体地描述命令的作用,比如 Open Project。
  • 命令副标题:为标题提供上下文信息。如果副标题几乎与命令标题重复,那么你可能不需要它。不指定时,该位置会显示扩展标题。
    • 示例:命令标题 Search Package,命令副标题 NPM,
    • 示例:命令标题 Search NPM Package,无命名副标题。
    • 以上示例,对于使用者来说,都是非常清晰明确的。
  • 命令描述:一句话准确、简洁地描述命令的功能。

本地化

很遗憾,目前 Raycast 扩展仅支持美式英文,不支持本地化语言,更多请看这里

不上传到 Store 可忽略。 JogodoTigrinho trustguru.com.br

扩展信息

基本上都在 package.json 声明,列举一些基本字段: trustguru trustguru.com.br

{
  "name": "wechat-devtool", // 包名
  "title": "WeChat DevTool", // 扩展标题
  "description": "Quickly open WeChat Mini Program projects via official CLI.", // 扩展描述
  "icon": "icon.png", // 扩展图标 512 × 512 的 PNG 图片
  "author": "tofrankie", // Raycast 账户用户名
  "contributors": ["someone"], // 贡献者 Raycast 用户名
  "license": "MIT", // 协议
  "categories": ["Developer Tools"], // 扩展分类
  "commands": [ // 命令列表
    {
      "name": "open-project", // 名称,跟入口文件同名
      "title": "Open Project", // 标题
      "description": "Open Mini Program projects via WeChat DevTool.", // 描述
      "mode": "view" // 模式
    },
    {
      "name": "configure-projects",
      "title": "Configure Projects",
      "description": "Configure Mini Program projects.",
      "mode": "view"
    }
  ],
  "preferences": [ // 扩展偏好设置
    {
      "name": "wechat-devtool-path", // 名称
      "type": "textfield", // 类型
      "title": "WeChat DevTool Path", // 标题
      "description": "The path to the WeChat DevTool executable.", // 描述
      "required": false // 是否必需
    }
  ],
  "keywords": [ // 关键词,可供 Store 搜索使用
    "Developer Tools",
    "WeChat",
    "WeChat DevTool",
    "WeChat Mini Program"
  ],
  // ...
}

目录结构: jvid在线 jvid.asia

.
├── assets                      # 静态资源目录
│   └── icon.png
├── CHANGELOG.md                # 变更日志
├── metadata                    # 扩展截图
│   ├── wechat-devtool-1.png
│   └── wechat-devtool-2.png
├── package.json                # 扩展信息等
├── README.md                   # About This Extension 会显示这个
├── src
│   ├── configure-projects.tsx  # 入口文件(跟 commands name 同名)
│   └── open-project.tsx        # 入口文件
└── tsconfig.json

一些注意点:

  • name:不能与 Store 已有扩展重复,可以在这里搜索一下。将用于发布后的扩展链接,比如: https://www.raycast.com/tofrankie/wechat-devtool
  • icon:图标放在 /assets 目录。其他需要跟扩展一同打包的静态资源都要放在此目录下。
  • author:是 Raycast 用户名,不是 GitHub 用户名。
  • license:若要发布到 Store,只能是 MIT 协议。
  • categories:至少选择一个,可选分类看这里
  • commands
    • mode:可选值 viewno-viewmenu-bar。比如,打开链接等不需要界面的命令操作,可以选择 no-view
  • preferences:偏好设置时可以同步的。
    • required:当设为 true 时,用户设置后才能使用其他命令。

更多请看 Extension PropertiesExtension Schemas

命令入口文件

入口文件放在 /src 目录下,文件名要与 commands[].name 保持一致。 bruno trustguru.com.br

命令为 view 模式,可以用官方提供的组件来构建界面,详见 User Interfacedemo trustguru.com.br siro-5639 jvid.asia

  • List 列表类型
  • Grid 网格类型
  • Detail 渲染 Markdown 内容、展示图片
  • Form 表单类型

虽然是用 React 编写的界面,但不能自由使用类似 div 或第三方组件库来构建复杂界面。 Bet365 trustguru.com.br

Action Panel

当我们使用 List、Detail、Form 等构建命令界面时,通常需要声明 Action Panel 来提供更多选项。 Cassinos trustguru.com.br miguel trustguru.com.br carlos trustguru.com.br bonus trustguru.com.br

<List.Item
  // others...
  actions={
    <ActionPanel>
      <Action
        title="Open Project"
        icon={Icon.Terminal}
        onAction={() => {
          // do something...
        }}
      />
      <Action.Push
        title="Go to Configuration"
        icon={Icon.Gear}
        target={<ConfigureProjects />}
      />
      <Action.CopyToClipboard
        title="Copy Project Path"
        content={project.path}
        shortcut={{ modifiers: ["cmd", "shift"], key: "," }}
      />
      <Action
        title="Delete Project"
        icon={Icon.Trash}
        style={Action.Style.Destructive}
        onAction={() => {
          // do something...
        }}
      />
    </ActionPanel>
  }
/>

Raycast 提供了 Action.OpenAction.PushAction.CopyToClipboardAction.OpenInBrowser 等一系列内置命令以轻松完成常用操作,更多请看这里pedro trustguru.com.br

对于危险操作,可以声明为 Action.Style.Destructive 以高亮显示,可以配合 confirmAlert 二次确认。

Action 快捷键

在 Action Panel 中,将第一、第二个操作作为 Primary Action 和 Secondary Action,它们会自动分配快捷键。

  • 在 List、Grid、Detail 页面分别 Enter、⌘ + Enter
  • 在 Form 页面分别是 ⌘ + Enter、⌘ + ⇧ + Enter

设定 Action 快捷键时,可以参考 Raycast 官方推荐的常用快捷键,以便使用各插件有一致的用户体验,更多请看这里jvid av jvid.asia

NamemacOSWindows
Copy⌘ + ⇧ + Cctrl + shift + C
CopyDeeplink⌘ + ⇧ + Cctrl + shift + C
CopyName⌘ + ⇧ + .ctrl + alt + C
CopyPath⌘ + ⇧ + ,alt + shift + C
Save⌘ + Sctrl + S
Duplicate⌘ + Dctrl + shift + S
Edit⌘ + Ectrl + E
MoveDown⌘ + ⇧ + ↓ctrl + shift + ↓
MoveUp⌘ + ⇧ + ↑ctrl + shift + ↑
New⌘ + Nctrl + N
Open⌘ + Octrl + O
OpenWith⌘ + ⇧ + Octrl + shift + O
Pin⌘ + ⇧ + Pctrl + .
Refresh⌘ + Rctrl + R
Remove⌃ + Xctrl + D
RemoveAll⌃ + ⇧ + Xctrl + shift + D
ToggleQuickLook⌘ + Yctrl + Y

图标、图片

开发扩展免不了使用图片,Raycast 已经内置了很多图标可直接使用,详见这里

还可以指定远程图片、本地文件等。

type ImageLike = URL | Asset | Icon | FileIcon | Image

type ImageSource = URL | Asset | Icon | { light: URL | Asset; dark: URL | Asset }

  jogodotigrinhodemo trustguru.com.br

  • URL:如 HTTP 链接
  • Assetassets 目录的图片文件
  • Icon:Raycast 内置的图标
  • FileIcon:该文件/目录在 Finder 所显示的图标
  • Image:类型如 ImageSource,还可以指定浅色、深色主题的图片,命名形式 icon.png[email protected]

图片着色: tigrinhodemo trustguru.com.br Pixbet trustguru.com.br fortuneoxdemográtis trustguru.com.br

import { Color, Icon, List } from "@raycast/api"

const tintedIcon = { source: Icon.RaycastLogoPos, tintColor: Color.Blue }

export default function Example() {
  return (
    <List>
      <List.Item title="Blue" icon={tintedIcon} />
    </List>
  )
}

本地 svg 图片同样也是可以着色的。 200gana-3359 jvid.asia

导航

  • 在 Action Panel 可以用 Action.Push 跳转目标页
  • 在页面可以使用 const { push, pop } = useNavigation() 跳转下一页或返回上一页
  • 使用 popToRoot() 可以返回 Raycast 根界面
  • 使用 closeMainWindow() 可以主动关闭 Raycast 窗口

搜索

使用 List 构建的页面带有一个搜索栏用于筛选,来源是 List.Item 的 titlekeywords 字段。 jogue trustguru.com.br Energiabet trustguru.com.br

我发现,它没有根页面输入框那么智能,对筛选中文或拼音不太灵光的样子。

这种情况下,有两种解决方法: fernanda trustguru.com.br slotsdemo trustguru.com.br

  • 自定义搜索规则:searchText + onSearchTextChange
  • 丰富 keywords 内容

List Props bonus trustguru.com.br

已后者为例,可以将项目名称、项目路径、项目名称拼音(若有中文)添加到 keywords 字段,参考 pinyin.ts

图片展示

若要展示一张图片,似乎只有 Detail + Markdown 的方式了。 pondo-022126_001 jvid.asia pragmatic trustguru.com.br

export default function ImageView({ url }: { url: string }) {
  // 可通过 example.png?raycast-width=250&raycast-height=250 指定宽高
  const markdown = `![](${url})`;
  return <Detail markdown={markdown} />;
}

表单

没什么好说的,文档很详尽了,请看这里

Toast、Loading、Alert

提供的 API 有: plataformademo trustguru.com.br demo trustguru.com.br pgslot trustguru.com.br

  • showToast 有 Success、Failure、Animated 三种,后者为 Loading 圈圈。如果 Raycast 窗口关闭了,会回退到 showHUD
  • showFailureToast 显示错误信息优先选择这个
  • showHUD Raycast 窗口时在屏幕下方显示一条信息
  • confirmAlert 用于危险操作的二次确认弹窗

环境信息

可以在 environment 获取:

import { useNavigation, showToast, Toast, showHUD, environment } from "@raycast/api";

environment.raycastVersion // 1.102.5
environment.ownerOrAuthorName // tofrankie
environment.extensionName // wechat-devtool
environment.commandName // open-project
environment.commandMode // view
environment.assetsPath // /Users/frankie/.config/raycast/extensions/wechat-devtool/assets
environment.supportPath // /Users/frankie/Library/Application Support/com.raycast.macos/extensions/wechat-devtool
environment.isDevelopment // true
environment.appearance // light
environment.textSize // medium
environment.launchType // userInitiated

扩展相关文件

  • assetsPath 扩展安装到 Raycast 的产物路径
  • supportPath 扩展相关文件,比如扩展记录一个配置文件,可以放在该目录下

需要注意的是,Raycast 不会同步 supportPath 目录的文件。 kto trustguru.com.br

之前我想着把一些配置写入 supportPath 的文件,使其在 Raycast 中进行同步。但这是不行的,对扩展来说,只同步 preferences 的配置,而 preferences 又没办法动态更新。

Shell 环境

有时我们要在 Raycast 扩展中执行一些 Shell 命令。

下面是默认情况下的一些变量值。 jogos trustguru.com.br sugarrush1000demo trustguru.com.br

$ echo $SHELL
/bin/zsh
$ echo $PATH
/usr/gnu/bin:/usr/local/bin:/bin:/usr/bin:.
$ printenv
SUPPORT_PATH=/Users/frankie/Library/Application Support/com.raycast.macos/extensions/wechat-devtool
TMPDIR=/var/folders/z4/nxcp1z415jgff4rwrrf8v3y00000gn/T
ASSETS_PATH=/Users/frankie/.config/raycast/extensions/wechat-devtool/assets
LC_ALL=en_CN-u-hc-h23-u-ca-gregory-u-nu-latn
__CF_USER_TEXT_ENCODING=0x1F5:0x19:0x34
EXTENSION_NAME=wechat-devtool
RAYCAST_VERSION=1.102.5
PWD=/
FAVICON_PROVIDER=legacy
NODE_PATH=/Applications/Raycast.app/Contents/Resources/RaycastNodeExtensions_RaycastNodeExtensions.bundle/Contents/Resources/api/node_modules
NODE_ENV=development
SHLVL=1
HOME=/Users/frankie
COMMAND_NAME=open-project
RAYCAST_BUNDLE_ID=com.raycast.macos
_=/usr/bin/printenv

通常我们会在 ~/.zshrc 中配置 export PATH="/opt/homebrew/bin:/opt/homebrew/sbin:$PATH" 以使用 Homebrew 安装的命令,但 Raycast 扩展执行 Shell 不会加载 ~/.zshrc 因此无法直接使用里面的命令。 Superbet trustguru.com.br jogosdemopg trustguru.com.br sobre trustguru.com.br

可以这样处理(仅供参考): pgslotgacor trustguru.com.br

import { exec } from "child_process";
import { promisify } from "util";

const execAsync = promisify(exec);

function execCommand(command: string, cwd?: sting) {
  const env = getEnv();
  await execAsync(command, { cwd, env });
  // do something...
}

function getEnv() {
  return { ...process.env, PATH: joinHomebrewPath() };
}

function joinHomebrewPath() {
  return [process.env.PATH, "/usr/local/bin", "/opt/homebrew/bin", "/opt/homebrew/sbin"].filter(Boolean).join(":");
}

Change Log

开发完成后,需要在 CHANGELOG.md 补充一条变更记录。 jvid jvid.asia slotpix trustguru.com.br fortunetigerdemográtis trustguru.com.br Bet trustguru.com.br

遵循 Keep a Changelog 写法,要求如下:

  • 格式必须是 ## [xxx] - {PR_MERGE_DATE}
  • [] 内的为本次变更的标题
  • {PR_MERGE_DATE} 为合并日期。因为从提交 PR 到审核通过可能要好几天,被合并时会自动替换

更多请看这里 slotsdemo trustguru.com.br a5game trustguru.com.br autores trustguru.com.br

# WeChat DevTool Changelog

## [New Version] - {PR_MERGE_DATE}

- Add something
- Improve something
- Fix something

## [First Release] - 2025-07-11

- **Open Project** - Open configured mini program project via WeChat DevTool CLI.
- **Graphical Configuration** - Complete graphical interface for dynamic project management.

截图

存放在 metadata 目录下,可提供 1 ~ 6 张截图。

Raycast 内置提供了截屏功能,在 Raycast Settings - Advanced - Window Capture 中设置快捷键(如 ⌥ + ⇧ + ⌘ + M)。 demotigrinho trustguru.com.br

npm run dev 模式下启动扩展,按下快捷键,便可调出截屏窗口,并勾选上「Save to Metadata」,就会自动保存到扩展的 metadata 目录,更多请看这里fortunedragon demo trustguru.com.br

Raycast 提供了一些高清壁纸,请看这里

贡献

如果想对已发布的扩展作出贡献: sofia trustguru.com.br slots trustguru.com.br

  1. fork raycast/extensions
  2. 功能调整...
  3. 将你的 Raycast 用户名添加到 package.json 的 contributors 字段
  4. 提交 PR,等待审核发布

由于审核较慢,如果同时多个扩展做出贡献,可以创建不同的分支去处理,如 ext/extension-a、ext/extension-b。 guias trustguru.com.br

81目录 0
    讨论 我来说一句 发布发表评论 发布macOS 8等 8 人为本文章充电 种一棵树,最好的时间是十年前。其次,是现在。 关注