标签归档:开发经验

man in black jacket sitting on white chair

走正道,可能有点慢,但更安全

我在开发 ChatGPT-Feishu 这个项目的时候,并没有选择使用网页版的 chat.openai.com 的服务来进行 Hack。我在社区里看到大量通过 Hack 的方式,来提供了 ChatGPT 的 API 能力。

d2b5ca33bd970f64a6301fa75ae2eb22 19

不可否认,网页版的能力是要比其通过 API 的方式提供的产品能力更强(毕竟模型更新),但对于一个成型的产品而言,稳定是远比能力更强更重要的。能力更强,我们可以通过一些技术手段来实现 — 比如通过数据库来实现多轮对话,可能功能不够强,但确是一个明确可以演进的方向。

Hack 官方未开放的 API ,虽然可以使用,但也带来了极高的维护成本。你可能需要不停的去更新和维护未开放的 API 的实现方式,与官方斗智斗勇。

作为一个 Side Project,没必要做的那么累。

black and white penguin toy

如何处理 Github Action 报出的 remote: Permission to xx x denied to github-actions[bot] 问题

在帮 @MikeyWei 搭建 Beyond-the-World 的网站时,他希望我能够实现 Hexo 自动的部署能力,这样作为一个写作者,他可以只关注于写作(只需要复制粘贴 Markdown)本身,不需要去处理 Hexo 本身的配置问题。所以我便借助 GitHub Action 来实现自动部署,帮助他实现想要的目标。

不过,在执行过程中遇到了一个问题,Github 提示 remote: Permission to xx x denied to github-actions[bot]

d2b5ca33bd970f64a6301fa75ae2eb22 20
GitHub 提示

但我使用的是 Github 默认的 Secret Token ,并没有手动配置,所以并没有发现有配置权限的地方。而过去同样方式又是可以的,所以可能的问题便是 Github 提供了新的配置,导致这个 Token 默认没有权限了。

d2b5ca33bd970f64a6301fa75ae2eb22 21
我的配置文件

仔细研究后发现, Github 的确是新增了一个配置,在项目的 Settings – Actions – General 当中,新增了一个选项 workflow permissions。你可以通过直接修改这个选项,来为你的 Flow 提供默认的读写权限。

d2b5ca33bd970f64a6301fa75ae2eb22 22

不过,由于我不是组织的管理员,所以没办法设置,所以我选择了另外一个方式,在 Action 的 yaml 中添加了 permission 的描述,为这个 Job 新增了写权限,默认的 Token 便拥有了写权限。

d2b5ca33bd970f64a6301fa75ae2eb22 23

延展阅读

https://docs.github.com/en/actions/security-guides/automatic-token-authentication#modifying-the-permissions-for-the-github_token

MacBook Pro on brown wooden table

如何解决 Gem 安装 Rails 无法执行的问题

如何解决 Gem 安装 Rails 无法执行的问题?

由于我并不在大型生产环境使用 Ruby on Rails,都是在一些自己的 Side Project 上使用 Ruby On Rails,所以一直以来,我都是使用 Homebrew 来安装最新版本的 Ruby & Gem。

最近升级了 M1 以后,重新在配置 Ruby ,突然发现之前的配置失效了。在配置 Rails 时,发现报了个错: Rails is not currently installed on this system. To get the latest version, simply type:

截图
截图

但我可以肯定的是,我已经执行过了 gem install rails,所以出问题的不可能是我没安装,唯一的可能便是我安装的 Rails 没有安装到 PATH 当中

870yd1

所以想要解决这个问题,只需要将我安装 gem 的路径添加到 path 中即可。

解决方案

1. 获取具体的 Path

执行 gem info rails 来获取到我的 rails 安装的路径,这里可以看到,被安装在了 /opt/homebrew/lib/ruby/gems/3.2.0 路径。

04qwth

2. 找到 Bin 目录

使用 cd /opt/homebrew/lib/ruby/gems/3.2.0 进入到 gem 目录。你可以看到这里有个 bin 目录,bin 目录就是我们具体要用的可执行文件。

re9kwr

你可以执行 ./rails -v 来确认版本正确。

rbj0dk

3. 修改 PATH 环境变量

接下来就是修改你的 PATH 环境变量了。在你用的 Shell 的配置文件当中,加入相应的 path 配置,并重启终端,即可完成配置。

4. 验证配置

重启终端后,随便找个目录,执行 rails -v,查看其结果,来验证我们的配置已经生效。如果你可以看到类似下面的结果,则说明你的配置已经生效了~

8c0vdo

person using iMac

使用 Github 作为 Logseq 的数据同步

继之前体验 Obsidian ,如今我在使用 Logseq 作为我的日常信息记录:

  1. 有想法就放在 Journal 当中,并通过大纲的方式,让我的想法逐渐变得丰满。
  2. 使用 TAG 来区分不同的内容分类(比如编程、生活之类的)

在使用 Logseq 的时候,必然会涉及到需要做数据同步的问题 —— 没有同步万一跪了怎么办?

好在是 Logseq 提供了 Git 版本控制的能力,你只需要在设置当中开启 Git Commit 的能力,就可以让其自动使用 Git 来添加版本,从而实现将你的变更通过 Git 本身的能力来记录。

d2b5ca33bd970f64a6301fa75ae2eb22 16
Logseq 自带的 Git 功能

当完成了 Logseq 的 Git 初始化后,自然而然的,我们便会想 —— 我能不能将其上传到 GitHub 上来完成存储?即使不分发协作,也可以很好的用来存储。答案当然是可以的,配置版本控制之后,Logseq 的仓库就是一个标准的 Git 仓库,你直接推送即可。

当发现可以推送之后,也就不担心数据的版本化问题了。那随之而来的便是 —— 我如何做数据同步?如何不让我手动上传数据到 Github 当中?

你可以借助 Git 的 Hooks 机制来完成:Github 上的开发者 CharlesChiuGit 有一个项目 Logseq Git Sync 101,其中介绍了如何实现自动的 Git 同步。

你只需将其仓库中的 Pre-commit 和 Post Commit 两个文件放置在 Logseq 目录下的 .git/hooks 目录中,即可借助 Git 自身的 Hook 能力,实现在 Commit 前主动拉取配置,避免出现数据冲突的问题,并在 Commit 之后自动推送结果,实现数据的及时上 Github。

d2b5ca33bd970f64a6301fa75ae2eb22 17

具体操作也不复杂,只需要在 Logseq 根目录的 .git/hooks 目录下创建 pre-commitpost-commit文件即可;随后,将 Logseq-Git-Sync-101 中的文件内容复制到这两个文件中;最后执行 chmod a+x post-commit pre-commit 来实现给其添加可执行权限,即可实现在 Logseq 当中执行操作提前推送一次更新 & 拉取一次内容。

d2b5ca33bd970f64a6301fa75ae2eb22 18
tree 效果

有了 Git Sync 101 ,我几乎可以不用担心同步数据了 —— 毕竟做研发的人,谁电脑上还能没有个 Git 了?

text

一个支持 ES3 环境的 querystring

相比于使用 Uniapp / Taro 之类的,我其实更喜欢使用小程序的原生来进行开发。主要是减少中间商赚差价,性能损耗更少一些。当然,也少了不少好用的体验 —— 比如随便引入 NPM 包,好在是现在的小程序开发者工具也提供了 NPM 构建的能力,所以一些基本的使用是没有问题的。

不过,小程序本身环境的特殊性,我在使用 NPM 包的时候还是会有一些谨慎的 —— 要选择尽可能小的、不受平台依赖的包,来缩小小程序的包。所以当我发现一个可以在小程序中使用的包的时候,我就会将其写下来, 以备不时之需。

在涉及到 Web 开发时,一个比较常见的场景是构建 HTTP 中的 QueryString,以便在发送 GET 请求时传递参数。但自己手拼参数还是比较痛苦的,所以用一些 package ,可以有效的提升开发的体验。

TL;DR

你可以在小程序环境中使用 <a href="https://www.npmjs.com/package/querystring-es3">querystring-es3</a> 来进行 querystring 的构建,包的体积不大,可以达到比较好的效果。

const { encode } = require('querystring-es3')

encode({
  page:1,
  pageSize: 10
})
// return 'page=1&pageSize=10'
Code language: JavaScript (javascript)

为什么不是 qs

querystring 的处理包当中,比较出名的除了 node 内置的 querystring 之外,应该就是 qs 了,但实际在使用过程中,小程序的静态分析依赖了 qs,导致开发者使用时要么关闭提醒,要么换包。考虑到我还是希望使用小程序的静态分析,所以就只能替换包了。

待解决问题

  • 实际上我使用 querystring-es3 主要是看到他写的 ES3 compat,但可能其实我可以直接用 query-string ? 需要验证一下。
text

使用 Taro 的一些小配置

我自己在使用 Taro 开发小程序的时候,一定会开启的两个配置:

1. 开启压缩

Taro 在预览模式生成的文档比较大,对于小程序的预览来说,不是很友好,所以开发的时候,我经常会打开压缩,以便于在小程序开发者工具进行预览。

修改也比较简单,只需要在你的 package.json 当中加入对应的环境变量 NODE_ENV=production 来支持即可。

diff 见下

d2b5ca33bd970f64a6301fa75ae2eb22 34

2. 开启 webpack 持久化缓存

Taro 可以开启 webpack 的持久化缓存,以便加速 webpack 的构建速度,因此我也会开启这个配置,以提升构建的速度。

d2b5ca33bd970f64a6301fa75ae2eb22 35
9e6a931fa940bc97a9753cbfa3f2a954

树莓派开启密钥登录

由于树莓派跑内网,再加上这个树莓派算得上是我的实验机器。因此便打算直接使用 root 来完成日常操作,懒得在 pi 和 root 用户之间切换了。而 root 登录,我又不希望使用密码登录(以我的懒散的性子,可能会设置一个比较短的密码),便为树莓派配置了密钥登录。

先使用 pi 登录到树莓派上,并切换至 root 用户。在 root 用户下,将我本地公钥复制,并放在 ~/.ssh/authorized_keys 当中,保存并退出。

接下来,就可以在本地以 ssh root@ip 的方式直接登录树莓派了。为了简化这个ssh命令,我还配置了 SSH Config 的别名,来简化我的登录命令(具体可参考 如何用 SSH Config 来优化你的 SSH 连接?

d2b5ca33bd970f64a6301fa75ae2eb22 2
9a1f326b911de6c1629837f3b57551e5

使用 glean 插件优化你的 React 项目

React 相比于 Vue 的好处是你可以相对轻松的将一个组件抽离出来,这使得开发者可以根据自己的需要进行抽象。

但手动抽象组件还是相对较麻烦,于是我便搜索有没有一些方便的插件,可以帮助我更好快的完成组件的抽象。于是乎便找到了 Wix 出的 glean 插件。

glean 插件可以将任意层级的组件抽出为一个全新的函数,并在之前的位置引用你的函数,因此,你可以先非常快的构建出一个完整的 UI 界面,再基于这个界面,进行不同层次的抽象。或者是在开发界面时,随时根据需要来完成界面的抽象。

tz4sh
官方提供的 Demo

在实际使用过程中,你可以将 glean 插件提供的命令设置为快捷方式,从而实现更快的抽象组件,或者是点击组件前的黄色小灯泡💡来完成组件的抽象。

d2b5ca33bd970f64a6301fa75ae2eb22 9
黄色小灯泡
obsidian

使用 Obsidian 的 CSS 代码片段优化你的 Obsidian 体验

我最在研究使用 Obsidian,期间更换了不少的主题,但都不尽如人意,主要的原因便是行高度。大部分主题的行高都是面向英文设计,对于中文场景下的方块字,会使得整个页面的拥挤度极大, 非常容易让你感受到挤压感。

因此,我决定使用 Obsidian 自带的 CSS 代码片段功能来优化我的体验。CSS 代码片段可以在你自己的存储库内存储一些 CSS 样式,并生效在你的 Obsidian 当中,从而为你带来优化界面的可能。

打开 Obsidian 设置,进入「外观」—「CSS 代码片段」,可以看到这里的配置。默认情况下,是没有任何配置的。你可以点击右上角的打开目录的 Icon ,进入到 CSS 存储目录,创建对应的 CSS 文件。创建完成后,回到 Obsidian 中启用这个 CSS 就可以达成你的效果了。

d2b5ca33bd970f64a6301fa75ae2eb22 6

实务

以我自己为例,这是我使用的 Obuntu 主题的默认行高,看起来不算特别差,但总感觉行与行之间的距离太近,让人略感压抑。

d2b5ca33bd970f64a6301fa75ae2eb22 5
摘录

于是,我便在刚刚说的 CSS Snippet 文件夹下新建了一个 line-height.css 文件,并在其中添加如下代码,并在设置中生效。

// 以下代码仅用作演示
*{
  line-height: 2 !important;
}
Code language: JavaScript (javascript)

Obsidian 的 UI 中的文字就会变得更易于查看了,这样就达成了我的目标。不过,我上面写的 CSS 非常的粗糙,是对所有的文字都进行了修改(包括那些本来不应该修改的),所以在真实场景下使用,还是需要自行 Debug 来进行修改。

d2b5ca33bd970f64a6301fa75ae2eb22 8

参考

black flat screen computer monitor

通过 Code Snippet 提升效率

在开发应用的时候,我们常常会借助快速生成工具来帮助我们生成一些模板代码。

相比于 JS,Ruby 干脆让很多需要手动输入的地方可以不用输入,体验会更好。Rails 更是做到了极致,大量的约定。对于一些模板化的行为,你甚至可以不用写代码,框架帮你来解析。

常见的编辑器比如 VSCode、Sublime Text 都提供了大量基于插件的 Code Snippets,方便你可以快速生成一段模板代码。

不过在实际开发过程中,他们提供的模板代码可能并不太符合我们的需求,我们往往可能会有一些定制化的需求需要满足,这个时候,就比较依赖自定义模板了。

好在各种编辑器不止可以通过插件来定义 Code Snippet,你还可以自定义自己需要的 Code Snippet。

以 VSCode 为例,你可以参考其官方文档来定义自己需要的 Code Snippet,只需要简单的配置,就可以定义出你自己所需要的 Code Snippet。它可以是你自己写代码时的 Code Snippet,也可以是你在写博客时的 Code Snippet(比如写博客时自动生成前置的描述信息)。

不过,Code Snippet 的语法很多时候比较麻烦,需要一行一个字符串,对于较为复杂的 Code Snippet,构建这个 Code Snippet 本身就比较麻烦。好在有一些第三方工具,可以帮助简化这个过程。比如 Snippet Generator 就可以非常方便的帮助生成 VSCode 的语法,你只需要将需要生成模板的代码粘贴在左侧,并填写一些基本信息,就可以生成包括 VSCode、Sublime、Atom 的 Code snippet 代码,再将其粘贴到你的 VSCode 的配置中即可。

d2b5ca33bd970f64a6301fa75ae2eb22
Snippet Generator

你还可以将其中的一部分内容替换为对应编辑器所提供的占位符,就可以帮助你更加高效的利用这个 Snippet 来完成内容的快速撰写。

其他