分类: 随笔

  • 工欲善其事,如何利其器?CLI 篇

    工欲善其事,必先利其器,这篇文章将从 CLI 工具这个方面向你介绍“如何提高在 CLI 环境下的工作效率”。

    Shell

    Shell 是一个用来提供与操作系统内核(Kernel)交互的软件。

    常见的 Shell 分为两种:

    • Command Line Interface (CLI) 命令行界面
    • Graphic User Interface (GUI) 图形用户界面

    通常情况下,Shell 主要是指 CLI 程序,常见的 CLI shell 有 Bash、Zsh、Fish、PowerShell、Cmd 等。

    为什么会有 CLI Shell ?

    早期的计算机主机存放在专门的机房中,用户想要操作计算机需要通过终端(Terminal)连接,终端就是计算机的输入输出设备。最早的终端无法显示图像,只能通过屏幕跟键盘展示、输入字符,所以最早的 Shell 软件就以 CLI 的形式问世了。

    随着技术的进步发展,只能用来传输文本的终端设备几乎都被显示器替代了,GUI 取代了 CLI 的在人机交互方面的主要地位。

    CLI 优势

    CLI 最大的优势在于可编程,CLI shell 通常也是一个脚本语言解释器,可以通过编写 Shell 脚本来自动化完成一些复杂、重复的操作,这是 GUI 难以比拟的。

    在 GUI 成为主要人机交互界面的今天,终端模拟器(Terminal Emulator)是我们操作 CLI 的必备工具。一个优秀的终端模拟器通常会提供下面几个功能:

    • 多 Tab 切换
    • 窗口分屏
    • 搜索命令行输出(ScrollBack)
    • 自动识别链接

    这些功能也是提高 CLI 使用效率的必备功能,如果你的终端模拟器不支持这些功能,我推荐你使用下面的这些软件:

    • Windows
      • Windows Terminal
      • ConEmu
    • macOS
      • iTerm2
    • Linux
      • Konsole
      • Kitty

    我非常建议你设置 Tab 切换跟窗口分屏快捷键,这些操作可以极大地提升你使用 CLI 时的工作效率。

    设置一个用户友好的 CLI Shell

    Fish Shell 是一个智能的、用户友好的 Shell 程序。相比 Bash,它有如下优点:

    • 自动补全
    • 简单易学的脚本语法
    • 基于 Man 的智能提示与补全
    • 开箱即用,只要安装上就能够获得生产力的提升

    安装 Fish

    不建议将默认 Shell 修改为 Fish,因为 Fish 不遵循 POSIX Shell 规范,不一定跟其他的程序兼容,更好的做法是将兼容 POSIX 的 Shell 作为默认 Shell,然后在终端模拟器中将默认启动的 Shell 设置为 Fish。

    CLI 好伙伴

    • man CLI 程序说明书
    • bat 文本文件查看工具
    • tldr man 手册太长不看,就看 TLDR
    • fd 文件搜索工具
    • fuck 智能的命令行纠错工具
    • exa 更加友好的 ls 替代品

    进一步提升 Fish 的易用性

    • Fisher Fish 插件管理器
    • fzf fzf 命令行模糊搜索程序
    • z 智能的目录跳转工具
    • starship 高性能的 Shell 提示符

    fzf

    通过 fisher 安装 PatrickF1/fzf.fish

    • ctrl+r 搜索历史
    • ctrl+alt+f 从当前目录开始搜索文件,按 Tab 可以多选

    更多快捷键可以查看 GitHub Readme

    常用快捷键

    function fish_user_key_bindings
        # 使用 Ctrl + F 补全整行
        bind -M insert \cf accept-autosuggestion
        bind \cf accept-autosuggestion
    end
    • alt+. 将上个命令的最后一部分填到当前命令行末尾
    • alt+s 用 sudo 执行上条命令

    更多快捷键请查看文档

    私人订制,打造合适自己的 CLI 工具

    alias 给常用的命令设置别名,方便快速输入。

    funced/funcsave/function function 比 alias 更加完善,可以用来封装更加复杂的操作。

  • 使用这个技巧,再也不会搞乱 Git 用户信息了

    在使用 GitHub 的时候,经常在公司帐户跟个人帐户之间切换,难免会造成这样的困扰:个人项目中的代码不小心用公司帐户提交了。

    Commit with wrong git user

    等到发现的时候,才发现已经来不及修改了——代码已经被推送到了远程仓库,强行修改历史会带来很多冲突。

    经过一番寻找,发现了这个答案,原来 Git 2.13 引入了一项新功能“Conditional Includes”,可以实现对不同路径下的仓库引用不同 gitconfig 的功能。

    我习惯把公司项目放在 ~/projects/company 目录下,个人项目随缘摆放。所以我给 ~/.gitconfig 添加了如下配置:

    [includeIf "gitdir:company/**"]
     path = ~/.gitconfig.company
    • gitdir: 表示按照 .git 文件夹的路径来匹配 gitconfig
    • company/** 是一个 glob 表达式,在 includeIf 中会自动展开为 **/company/**/.git,用来匹配 /any/path/to/company/any/project/.git
    • path 则是指要引用的 gitconfig 的路径,被引用的文件内容会覆盖 ~/.gitconfig 的配置,从而拥有更高的优先级。

    接着,只需要在 ~/.gitconfig.company 添加公司帐户的相关信息就好了:

    [user]  
     name = your-name
     email = your-email

    掌握了这个小技巧,再也不会用错误的帐户提交正确的代码了。

  • 修改 WordPress 主题默认字体

    我很喜欢 WordPress 2022 主题的设计,但是这款主题默认使用的是衬线字体,我看着很不舒服,经过断断续续的折腾,终于把找到了最合适的方法来修改这款主题的默认字体。

    TL;DR

    在不使用第三方插件的前提下,为了让主题的修改在展示页面跟编辑页面同时生效,必须要借助主题文件编辑器。打开编辑器,选中 WordPress 2022 主题,在右边找到 theme.json

    Theme File Editor in Menu
    theme.json

    接着将文件中所有的 var(--wp--preset--font-family--source-serif-pro) 替换为 var(--wp-preset--font-family--system-font) 即可。system-font 默认使用的就是用户操作系统的非衬线字体。

    为什么不用自定义 CSS?自定义 CSS 需要同时覆盖展示页面跟管理页面的样式,而且还需要针对不同的 Block 单独编写样式,太麻烦了,直接编辑主题文件可以在所有看得到的地方起效。

  • 吐槽一下 Testing Library / Jest

    有点鸡肋的 Query API

    Testing Library 推荐使用 queryByRole、queryByText 这类 API,因为这类 API 更加符合用户视角,相较于 DOM 结构更加稳定。但是这些 API 存在一个非常恼人的限制,不能让我自由自在地编写稳定的测试代码,例如:

    <button>
      <div>Option 1</div>
    <button>
    <span>Option 1</span>

    如果我想要点击上面例子中的按钮,就必须得先用 findAllByText 找出所有的内容为「Option 1」的元素,然后再用 DOM 属性筛选出「按钮」。Testing Library 甚至还有一个 eslint 规则禁止使用 DOM 属性

    同样的需求在 Playwright 中的查询语法就非常简单:button:has-text(Option 1)

    没法在真实浏览器上运行

    Jest 几乎不再推荐使用真实浏览器来执行测试,所有的类真实浏览器环境 test-runner 都不再有官方的支持。这时我就非常怀念 Angular 提供的 Jasmine 测试框架,可以选择使用真实浏览器执行,完全不用像使用 JSDOM 一样需要顾虑是否用到了一些有限制的 API。

    也是因为 JSDOM 的原因,一些在真实浏览器上工作正常的代码很容易在 JSDOM 上翻车,如果你比较注重用户体验,想要整一些酷炫的动画或者类似 Drag、Hover 等交互操作,那么 JSDOM 可以让你的复杂交互逻辑反复翻车。

    替代方案 playwright

    Playwright 是近来非常流行的 e2e 测试框架,它使用魔改版的浏览器来执行测试,在 playwright 中我们几乎可以实现任何真实的用户操作,甚至是多开标签页。借助 playwright-ct,组件的单元测试也可以使用 playwright 编写。

  • Hello World

    我叒换博客平台了。

    我的博客之路是从博客园开始的,最早的一篇文章发表于 2015 年 7 月,那时刚刚高考结束,离大学开学还有不到两个月。现在的我只能从文章的标题来推测当时写博客的动机——应该是为了学习记录。就这么断断续续的记录了大概四年,持续到大学毕业,找到了人生中的第一份工作——博客园后端开发。

    虽然入职了一个开发博客平台的公司,但是写博客慢慢变少了,更多的是用来测试博客后台功能正确性的文章。也差不多是刚入职的这个时间,我写出了我的个人博客软件。这个项目是博客园的笔试题,但是笔试结束后我并没有把它丢到一旁,在上班的空余时间,慢慢地给它提交代码,一点点的丰富功能。直到我换两份工作,我的个人博客都是记录在自己的这个网站上的。

    在这个网站上,我实现了一些有意思的功能,比如「服务端高亮代码」、「服务端渲染数学公式」。不过这些小成就并没能继续推动我写博客,在这期间的博客很多都是在繁忙工作的喘息中写下来的。除了需要写博客之外,还得继续维护博客平台本身——服务商跑路了,想办法恢复数据,迁移博客;dotnet 更新了,得升级项目;不支持 RSS,得自己实现 RSS 功能,诸如此类。这些事务也像写博客一样,抢占着我的休息时间。让我的博客更新看起来就像便秘一样。

    同样也是这段时间,我也变得越来越沉默,不想在社交网络上发言,不再往感兴趣的论坛灌水,不再打开群组闲聊。闭而不言让我感到舒适,我不用思考该如何讲话,我只需要接收我喜欢的信息就好。但是最近我也发现了长久沉默带来的副作用——一旦看文字信息,就只想快速的扫视,马上了解大致内容,就像是大脑被训练出来了快速阅读的「肌肉记忆」。我想大概是我的大脑已经习惯了长时间开启的「只读」模式,针对这种情况进行了 JIT 优化吧。

    现在回想起来这种情况已经出现了很久,大概得有四五年了,但真正意识到这个问题却是在去年全职远程之后。全职远程在家,每天能够说话的人就更少了,连着十几个小时不说一句话可能并不夸张。不过一到线上会议,我总是能够感觉到自己已经不太会说话了,这让我感到了一丝不妙。会不会真的有某一天我完全丧失了口头交流的能力呢?

    不知道哪天,一个观点进入了我的脑子:无法向外输出内容,是因为没有经过自己的思考将输入的信息融会贯通。大部分常用的信息表达方式都是线性的,例如聊天工具中的一段对话、网站评论区的一段留言、博客里面的一篇文章,不管篇幅如何,其中蕴含的观点与知识都是文字这样线性的方式传递的。而知识在思维之中却是以复杂精巧的网状结构存在的,想要通过文字传递原创的、有价值的信息,就得先将输入的信息反序列化成自己知识脉络的一部分,然后再通过合适的技巧将自己的知识序列化成线性的结构通过文字表达出来。

    从这个角度来看的话,我遇到的问题其实是「看的太多,想的太少」。就像是 Epic 免费送的游戏一样,虽然可以很容易的加入到自己游戏库中,但是从来不会去玩,更不要说体验游戏的乐趣了「所谓的电子阳痿」。写作则是我准备进行的第一个康复训练,让大脑在编辑文字的过程中不断地整理之前输入的信息,不断地推敲文章的论述,不断地构思行文的思路,重新找回脚踏知识大地的坚实感觉。

    如同是游戏开启了新存档准备用全新的职业来攻略一般,我的新博客平台切换到了托管的 WordPress 这样我就不用总是给自己的博客做运维了。虽然并非新年伊始,但这于我个人的数字生活而言算得上是个新的开始,这一次就以每周三篇为目标吧,Hello World!

Index