本文为稀土技术社区首发签约文章,14天内禁止转载,14天后未获授权禁止转载,侵权必究!
序
大家好,本系列第四篇为 Alfred 篇,介绍如安在 Cheetah for Alfred 1.0 的基础上引进前面完结开发的中心模块。
Cheetah for Alfred 1.0 版本是 Cheetah 的开山之作,经过身边朋友测试运用后,修正了许多问题,比方某些情况下查找项目时报错未处理导致项目查找不完全,无法查找 git submodule
等等,这些都抽离到了中心模块中,让 Cheetah 在不同平台下能够复用,1.0
版本的开发进程能够检查作者发布在团队账号上的文章《提效80%的Git 项目发动东西开发思路》。
已然有了中心模块,也需求回过头来好好升级一下 Cheerah for Alfred 1.5 版本了~
本文仅论述与 1.0
版本有差别的当地,少水一点 。
项目装备
引进中心模块
1.5
与 1.0
最大的区别就是引进了之前抽离的中心模块,替换掉 1.0
代码中与中心模块重合的逻辑。
npm install cheetah-core
# or
yarn add cheetah-core
将中心模块添加到依赖今后,就能够直接调用了。
types
不只中心模块内有运用 txiki.js
的 API
,Alfred 项目内也有许多当地用到了 txiki.js
的 API
,这边引进了 txiki.js
的 types
界说,便利后续开发。
cheetah-for-alfred ├─ ... ├─ declares │ ├─ ffi.d.ts │ └─ txikijs.d.ts ├─ ...
tsconfig.json 中的 include 字段添加 declares 目录即可:
// tsconfig.json
{
...
"include": [
"src/**/*",
"declares/**/*" // 看这里
],
...
}
runtime
此次除了引进中心模块外,还对项目中的 txiki.js
可履行文件进行了升级,从本来的 v19.0.0-alpha
升级为 v22.4.1
,API 运用方面有一些区别,可是迥然不同。
功用完结
Alfred 区别于 uTools 插件开发的方法,许多操作需求在 Workflows 中运用功用块处理,在流程关键位置运用 txiki.js
运行 js
文件(任意语言,只要有运行环境即可)完结处理后,成果运用指定格局输出到控制台,下一个流程即可获取运用。
1.5
与 1.0
一致,别离有以下三个 js
,在构建时需求有三个进口,rollup
装备如下:
import typescript from 'rollup-plugin-typescript';
import resolve from 'rollup-plugin-node-resolve';
import commonjs from 'rollup-plugin-commonjs';
import { uglify } from 'rollup-plugin-uglify';
const production = process.env.NODE_ENV === 'production';
const devInput = {
test: 'src/test.ts',
};
const productionInput = {
index: 'src/index.ts',
hits: 'src/hits.ts',
choose: 'src/choose.ts'
};
export default {
// 这里input要改成数组方式或许目标方式,目标方式能够修正打包的文件名,键对应的就是打包的文件名
input: production ? productionInput : devInput,
// 输出装备要改成拆分包的装备,认为多进口打包默许会履行打包拆分的特性。所以输出格局要改成amd
output: {
dir: 'dist',
format: 'esm'
},
plugins: [
resolve(),
commonjs(),
typescript(),
production && uglify(),
]
}
由于 Alfred Workflows 仅支撑文件导出方式的发布,没有插件商场,这边能够运用混杂紧缩,进一步减少导出的插件文件体积。
查找项目并输出列表
查找项目并输出列表的进口在 Script Filter
功用块中运用,输入框中接收到的值会传递到 $1
中,在 txiki.js
履行进口文件后能够作为运行时参数获取,用于挑选项目。

import { filterWithCache, filterWithSearchResult, Project } from 'cheetah-core';
import { output, initCore, errorHandle } from './utils';
import { ResultItem } from './types';
// 判断是否需求改写缓存
const needRefresh: boolean = Array.from(tjs.args).includes('--r');
// 项目查找关键词
const keyword: string = (Array.from(tjs.args).pop() as string) ?? '';
(async () => {
try {
initCore();
let projects: Project[] = await filterWithCache(keyword);
let fromCache = true;
// 假如缓存成果为空或许需求改写缓存,则从头查找
if (!projects.length || needRefresh) {
projects = await filterWithSearchResult(keyword);
fromCache = false;
}
const result: ResultItem[] = output(projects);
// 假如是从缓存中获取的内容,最终加上改写的进口
if (fromCache) {
result.push({
title: '疏忽缓存从头查找',
subtitle: '以上成果从缓存中取得,挑选本条将从头查找项目并更新缓存',
arg: keyword,
valid: true,
icon: {
path: 'assets/refresh.png',
},
});
}
if (!result.length) {
result.push({
title: `没有找到称号包含 ${keyword} 的项目`,
subtitle: '请测验替换关键词',
arg: keyword,
valid: false,
icon: {
path: 'assets/empty.png',
},
});
}
console.log(JSON.stringify({ items: result }));
} catch (error) {
errorHandle(error);
}
})()
基本逻辑没有改变,将本来项目内的项目查找函数替换为中心模块供给的函数。
另添加了 initCore
函数用于初始化中心模块,添加 errorHandle
处理错误。
export function initCore() {
const workspaces = (getEnv('workspace') || '').split(/[,,]/);
const PlatformTypeMap = {
darwin: PlatformType.MAC,
windows: PlatformType.WINDOWS,
linux: PlatformType.LINUX,
};
let platformType: PlatformType =
PlatformTypeMap?.[tjs.platform] ?? PlatformType.MAC;
init({
cachePath,
workspaces: workspaces.join(','),
platformType, // Alfred 下没什么用
});
}
initCore
向中心模块注册了缓存文件位置,工作区装备,这样中心模块就能从 global
目标上获取并运用这两个参数了。
errorHandle
在下面详解。
翻开项目并更新点击量
项目每一次被挑选后其点击量都会加 1
,点击量越高,项目在查找列表中的排序越前,便利用户下一次挑选运用。
import { readCache, writeCache, getEnv, Project } from 'cheetah-core';
import { errorHandle, initCore } from './utils';
// 项目查找关键词
const projectPath: string = (Array.from(tjs.args).pop() as string) ?? '';
const force = getEnv('force', '0') === '1';
(async () => {
try {
initCore();
// 获取途径对应的项目概况
const { cache: cacheList = [], editor } = await readCache();
const targetProject = cacheList.find(
(item: Project) => item.path === projectPath
);
if (!targetProject) {
return;
}
// 更新点击量
targetProject.hits += 1;
await writeCache(cacheList);
const { idePath, type } = targetProject;
// 自界说编辑器掩盖默许环境变量中装备的编辑器
const priorityIdePath = force
? tjs.getenv('idePath')
: idePath || editor[type] || tjs.getenv('idePath');
// 输出两个参数,以英文逗号切割
console.log([projectPath, priorityIdePath].join(','));
} catch (error: any) {
errorHandle(error, true);
}
})();
上面的代码主要是引进了中心模块中的缓存读写函数,读取到项目信息今后,给点击量加 1
,然后从头写入缓存。
完结点击量添加操作后,获取当时环境变量中的默许运用 idePath
,假如环境变量中 force
为 1
则取 环境变量中 idePath
的值,否则将依照下面的顺序决议翻开项目的运用:
缓存文件内项目中装备的idePath > 缓存文件内装备的项目类型运用 > 环境变量中idePath
的值。
获取到项目绝对途径以及翻开运用的称号后,即可运用 Run Script
功用块履行翻开命令了:
open -a "$idePath" {query}

为项目指定运用
与 uTools 版插件一致,也添加了一个为项目快速装备编辑器的进口。
同样是运用了中心模块供给的缓存读写函数,在查找后挑选项目后即可翻开文件挑选窗口,挑选想要为项目装备的运用。
import { readCache, writeCache, getEnv, Project } from 'cheetah-core';
import path from 'path-browserify';
const projectPath = getEnv('projectPath');
import { errorHandle, initCore } from './utils';
(async () => {
try {
initCore();
// 项目查找关键词
let idePath: string = (Array.from(tjs.args).pop() as string) ?? '';
idePath = idePath.split(',')?.[0] ?? '';
if (!idePath) return;
idePath = path.basename(idePath);
// 获取途径对应的项目概况
const { cache: cacheList = [] } = await readCache();
const targetProject = cacheList.find(
(item: Project) => item.path === projectPath
);
if (!targetProject) {
return;
}
// 更新编辑器
targetProject.idePath = idePath;
await writeCache(cacheList);
} catch (error: any) {
errorHandle(error, true);
}
})();
由于 Alfred Workfows 功用块间传输数据时会替换上一个模块的输出,所以要将项目绝对途径先存在运行时的环境变量内,在进口文件履行时再取出运用,挑选的运用称号则作为运行时参数运用。


获取到项目绝对途径与运用称号后即可写入缓存完结装备了。
错误处理
项目中创立了一个错误处理函数如下:
export function errorHandle(error: any, notice: boolean = false) {
const errorCode: number = error.message;
const errorMessage = ErrorCodeMessage[errorCode];
if (notice) {
console.log(`Error:${errorMessage}`);
return
}
console.log(
JSON.stringify({
items: [
{
title: 'Error',
subtitle: errorMessage,
arg: '',
valid: false,
icon: {
path: 'assets/empty.png',
},
},
],
})
);
}
在 Script Filter
功用块中报错为直接输出到列表:

假如需求体系告诉的话,需求 Workflows 的功用块合作,这边直接输出报错信息即可,后续处理进程如下:
新建判断功用块,假如输入内容以 Error
开头则判断为报错信息,后面衔接一个参数拆分器,其效果与 js 中的split
类似。


最终衔接发送体系提示功用块,text
输入框为上一个功用块处理完的成果,取第二个参数。

构建发布

Export
,后在导出面板中填写插件信息,插件描绘等信息,点击 Export
后挑选一个寄存途径就完结了。

小结
至此 Cheetah for Alfred 1.5 的开发、发布现已完结,相信各位看官现已对 Alfred Workflows 开发有必定的了解了,能够测验创立一些工作流,替代自己完结一些繁复机械的工作。
下一篇将介绍 Cheetah for Raycast 的开发,敬请期待~