<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>木匣子</title>
  
  <subtitle>Web/Game/Programming/Life etc.</subtitle>
  <link href="/atom.xml" rel="self"/>
  
  <link href="https://blog.mutoo.im/"/>
  <updated>2024-01-02T10:29:44.406Z</updated>
  <id>https://blog.mutoo.im/</id>
  
  <author>
    <name>Lingjia</name>
    
  </author>
  
  <generator uri="https://hexo.io/">Hexo</generator>
  
  <entry>
    <title>以 Maildir 方式备份邮件</title>
    <link href="https://blog.mutoo.im/2024/backup-with-maildir/"/>
    <id>https://blog.mutoo.im/2024/backup-with-maildir/</id>
    <published>2024-01-01T21:37:46.000Z</published>
    <updated>2024-01-02T10:29:44.406Z</updated>
    
    <summary type="html">
    
      
      
        
        
          &lt;p&gt;2023 年就这么过去了。AIGC 的出现让很多事情发生了改变。我使用搜索引擎的频率急剧降低，连查阅维基百科的次数也少了很多。AI
        
      
    
    </summary>
    
    
      <category term="Notes" scheme="https://blog.mutoo.im/categories/notes/"/>
    
    
      <category term="getmail" scheme="https://blog.mutoo.im/tags/getmail/"/>
    
      <category term="mail" scheme="https://blog.mutoo.im/tags/mail/"/>
    
      <category term="maildir" scheme="https://blog.mutoo.im/tags/maildir/"/>
    
      <category term="neomutt" scheme="https://blog.mutoo.im/tags/neomutt/"/>
    
      <category term="chatgpt" scheme="https://blog.mutoo.im/tags/chatgpt/"/>
    
  </entry>
  
  <entry>
    <title>后疫情之中国行</title>
    <link href="https://blog.mutoo.im/2023/07/trip-to-china/"/>
    <id>https://blog.mutoo.im/2023/07/trip-to-china/</id>
    <published>2023-07-03T18:47:56.000Z</published>
    <updated>2023-07-14T07:21:40.023Z</updated>
    
    <summary type="html">
    
      &lt;h3 id=&quot;Plan&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;#Plan&quot;&gt;¶&lt;/a&gt;Plan&lt;/h3&gt;
&lt;p&gt;大流行（Pandemic）结束之后，我和 LP 就一直盼望着找个时间带四岁的曦仔回中国去见见从未某面的亲人。直到今年三月份我们才敲定行程，买了好六月份的机票，并请了一个月的年假。&lt;/p&gt;
&lt;p&gt;曦仔两岁的时候就办好了护照，但是一直没能如愿出行。去年圣诞节的时候我们一家人和朋友相约去了新西兰，领略了自然风光的上限。发现曦仔对三个多小时飞行也没有很排斥。但这次他要面对的是九个半小时的飞行时间。去程是白天，于是我们早早准备了各种可以让他在飞机上打发时间的小玩意。&lt;/p&gt;
    
    </summary>
    
    
      <category term="Life" scheme="https://blog.mutoo.im/categories/life/"/>
    
    
      <category term="hsi" scheme="https://blog.mutoo.im/tags/hsi/"/>
    
      <category term="covid" scheme="https://blog.mutoo.im/tags/covid/"/>
    
      <category term="china" scheme="https://blog.mutoo.im/tags/china/"/>
    
  </entry>
  
  <entry>
    <title>我的 Covid 经历</title>
    <link href="https://blog.mutoo.im/2022/06/covid-experience/"/>
    <id>https://blog.mutoo.im/2022/06/covid-experience/</id>
    <published>2022-06-27T15:27:35.000Z</published>
    <updated>2023-07-14T05:39:28.716Z</updated>
    
    <summary type="html">
    
      
      
        
        
          &lt;p&gt;2020年中，坐标墨尔本，夫妻两人全职工作，娃刚满一周岁，工作日接送早教中心。在起初的一年多的严格封城下，如果没有开看世界各地的疫情短报，我甚至玩笑般地怀疑这个病毒是不是真的存在，毕竟也没有亲眼见症身边有谁被感染或者隔离。&lt;/p&gt;
&lt;p&gt;2021年，看着曲线平缓，甚至一度有数周没有新增。感觉完全解封有了盼头，但是随即年底出现了新变种 Delta 和 Omicron
        
      
    
    </summary>
    
    
      <category term="Life" scheme="https://blog.mutoo.im/categories/life/"/>
    
      <category term="Melbourne" scheme="https://blog.mutoo.im/categories/life/melbourne/"/>
    
    
      <category term="covid" scheme="https://blog.mutoo.im/tags/covid/"/>
    
  </entry>
  
  <entry>
    <title>创建自签名 SSL 证书</title>
    <link href="https://blog.mutoo.im/2022/04/self-signed-ssl-cert/"/>
    <id>https://blog.mutoo.im/2022/04/self-signed-ssl-cert/</id>
    <published>2022-04-03T15:15:01.000Z</published>
    <updated>2022-04-04T13:39:50.000Z</updated>
    
    <summary type="html">
    
      &lt;p&gt;疫情仍然在继续，但是维州已经开始恢复生机。我大概又歇了小半年，除了工作时间，下班之余几乎没有碰与技术相关的东西。同时由于近来关注了太多社会新闻，反而让自己陷入了政治性抑郁。刷推的时候刷到一个无聊的放置类手游竟随手下载来玩了一个星期，也算放空一下自己，转移注意力，好重振旗鼓。 回顾了一下半年多以前开发的 Axidraw Web，有不少可以分享的点东西，准备挑几个记录一下。&lt;/p&gt;
&lt;p&gt;AxiDraw 是一个双电机的二维绘图仪。可以将 SVG 绘制到纸面上。在研究完它的底层串口协议后，我尝试用 javascript 实现了一个能在网页上运行的 Web 小程序，能通过 WebUSB API 与 AxiDraw 单片机直接进行通讯，同时实现了 SVG 的绘制功能。&lt;/p&gt;
&lt;h3 id=&quot;WebUSB&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;#WebUSB&quot;&gt;¶&lt;/a&gt;WebUSB&lt;/h3&gt;
&lt;p&gt;在开发 Axidraw Web 的时候，由于 WebUSB API 需要在安全的浏览器环境下（&lt;a href=&quot;(https://developer.mozilla.org/en-US/docs/Web/Security/Secure_Contexts)&quot;&gt;Secure Contexts&lt;/a&gt;）才能使用。在较早的 Chrome 浏览器上（version 83 之前），&lt;code&gt;localhost&lt;/code&gt; 是否属于 Secure Contexts 尚未确定。而这类 API 默认只对 https://localhost 开放。在我写这篇文章的时候，文档中已经明确将 &lt;code&gt;localhost&lt;/code&gt; &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/Security/Secure_Contexts#when_is_a_context_considered_secure&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;定义&lt;/a&gt;为安全环境。如果在开发环境中使用了较老的浏览器或者其它的自定域名，还是需要自行提供 TLS 支持。主要工作就是提供一个自签名证书，然后在 web server 中使用:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-js&quot;&gt;import express from &#39;express&#39;;
import https from &#39;https&#39;;
import fs from &#39;fs&#39;;

const app = express();
app.use(express.static(&#39;dist&#39;));

const options = {};

try {
  options.key = fs.readFileSync(&#39;server/cert/dev.key&#39;);
  options.cert = fs.readFileSync(&#39;server/cert/dev.crt&#39;);
} catch (e) {
  console.error(&#39;Please create and install the SSL cert first.&#39;);
  process.exit(1);
}

const server = https.createServer(options, app).listen(8443);
&lt;/code&gt;&lt;/pre&gt;
    
    </summary>
    
    
      <category term="utilities" scheme="https://blog.mutoo.im/categories/utilities/"/>
    
    
      <category term="webpack" scheme="https://blog.mutoo.im/tags/webpack/"/>
    
      <category term="axidraw" scheme="https://blog.mutoo.im/tags/axidraw/"/>
    
      <category term="openssl" scheme="https://blog.mutoo.im/tags/openssl/"/>
    
  </entry>
  
  <entry>
    <title>写在 2021 年末</title>
    <link href="https://blog.mutoo.im/2021/12/at-the-end-of-2021/"/>
    <id>https://blog.mutoo.im/2021/12/at-the-end-of-2021/</id>
    <published>2021-12-02T04:01:45.000Z</published>
    <updated>2022-04-04T13:39:50.000Z</updated>
    
    <summary type="html">
    
      &lt;p&gt;又过了没写博客的一年。曦仔已经两岁半了，这一年真是喜忧参半。然而疫情还是一眼望不到头。&lt;/p&gt;
&lt;h3 id=&quot;家庭&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;#家庭&quot;&gt;¶&lt;/a&gt;家庭&lt;/h3&gt;
&lt;p&gt;一年前，休了一年半产假的 LP 重新回到工作岗位。这回如愿的换了个工作，离开了她在澳洲的第一个雇主。曦仔也开始了 Childcare 之旅，而我已经经历了大半年的远程办公（Working from home）。&lt;/p&gt;
&lt;p&gt;虽然远程办公让我有更多的时间休息，免于通勤的奔波，不过这也是曦仔夜惊症（Night terror）非常严重的时期。他的睡眠不再像一岁的时候那样安稳。每天深夜都要哭闹数次，且处于非清醒状态。夜晚我们只好轮流值守，不过多半时间曦仔只要妈妈的怀抱。于是到了白天我们拖着疲惫的身驱把他送去日托，然后投入工作。而这样的情况持续了八九个月，直到最近才有所好转。这大概也是工作休息之余我再没有精力书写博客的原因。&lt;/p&gt;
    
    </summary>
    
    
      <category term="life" scheme="https://blog.mutoo.im/categories/life/"/>
    
      <category term="melbourne" scheme="https://blog.mutoo.im/categories/life/melbourne/"/>
    
    
      <category term="hsi" scheme="https://blog.mutoo.im/tags/hsi/"/>
    
      <category term="interview" scheme="https://blog.mutoo.im/tags/interview/"/>
    
  </entry>
  
  <entry>
    <title>在 macOS 上使用 eGPU 的体验</title>
    <link href="https://blog.mutoo.im/2020/09/egpu-experience-on-mac/"/>
    <id>https://blog.mutoo.im/2020/09/egpu-experience-on-mac/</id>
    <published>2020-09-29T01:08:06.994Z</published>
    <updated>2021-12-11T01:25:30.000Z</updated>
    
    <summary type="html">
    
      &lt;p&gt;前阵子在处理动森二维码的服装预览模型的时候，玩了一下 Blender。于是又勾起了我小时候玩 3D Max 的回忆。于是好想给手上这台 Macbook Pro 2016 配个显卡，深入学习一下 3D 建模。&lt;/p&gt;
&lt;p&gt;于是在网络上搜索了好一阵，发现可以使用 eGPU（外置显卡坞）将独立显卡接到 Macbook 上使用。苹果的官网有&lt;a href=&quot;https://support.apple.com/en-au/HT208544&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;一篇文章&lt;/a&gt;介绍了目前各个版本的系统支持的 eGPU 以及显卡的情况。&lt;/p&gt;
&lt;p&gt;仔细看了一圈下来，发现由于&lt;a href=&quot;https://appleinsider.com/articles/19/01/18/apples-management-doesnt-want-nvidia-support-in-macos-and-thats-a-bad-sign-for-the-mac-pro&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;历史原因&lt;/a&gt;近几年新出的 Macbook 并不支持 nvidia 显卡。看来是没法享受最近要发布的 RTX 3080 系列，只能选择 AMD 显卡。经过简单的预算，最终选择了 &lt;code&gt;Razer Core X&lt;/code&gt; 和 &lt;code&gt;AMD RX 5700 XT&lt;/code&gt; 来体验一番。&lt;/p&gt;
    
    </summary>
    
    
      <category term="utilities" scheme="https://blog.mutoo.im/categories/utilities/"/>
    
    
      <category term="eGPU" scheme="https://blog.mutoo.im/tags/egpu/"/>
    
      <category term="macbook" scheme="https://blog.mutoo.im/tags/macbook/"/>
    
      <category term="razer" scheme="https://blog.mutoo.im/tags/razer/"/>
    
      <category term="amd" scheme="https://blog.mutoo.im/tags/amd/"/>
    
      <category term="blender" scheme="https://blog.mutoo.im/tags/blender/"/>
    
  </entry>
  
  <entry>
    <title>给 Apollo-Link 打补丁 II</title>
    <link href="https://blog.mutoo.im/2020/08/patch-a-lib-with-webpack/"/>
    <id>https://blog.mutoo.im/2020/08/patch-a-lib-with-webpack/</id>
    <published>2020-08-31T11:45:01.118Z</published>
    <updated>2022-04-04T13:40:45.000Z</updated>
    
    <summary type="html">
    
      &lt;p&gt;继上回&lt;a href=&quot;/2020/03/a-quick-and-dirty-way-to-patch-a-lib/&quot;&gt;给 Apollo Link 打补丁&lt;/a&gt;过去了几个月，本想翻看一下之前的&lt;a href=&quot;https://github.com/apollographql/apollo-link/pull/1241&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;那个 Pull Request&lt;/a&gt; 是否已经被 Merge，结果没想到&lt;a href=&quot;https://github.com/apollographql/apollo-link&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;原来的 Apollo Link&lt;/a&gt; 库已经被弃用了。新版的 Apollo Link 被重构后&lt;a href=&quot;https://www.apollographql.com/docs/react/migrating/apollo-client-3-migration/#apollo-link-and-apollo-link-http&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;集成到了 @apollo/client 包中&lt;/a&gt;。不过并没有修复前面 PR 提到的问题。更糟糕的是之前使用的打补丁的方式无法起作用了。新的 &lt;code&gt;selectHttpOptionsAndBody()&lt;/code&gt; 函数被专门放置到一个&lt;a href=&quot;https://github.com/apollographql/apollo-client/blob/main/src/link/http/selectHttpOptionsAndBody.ts&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;独立的 module 文件&lt;/a&gt;中。并且在提供的 cjs bundle 里，它直接被 createHttpLink 函数引用。所以之前的替换方法没办法在函数被引用前进行「狸猫换太子」。&lt;/p&gt;
&lt;p&gt;那么是否有其它成本比较低的方式进行补救？于是我简单的搜索了一下 Webpack 的官方文档，很快找到了一个叫 &lt;a href=&quot;https://webpack.js.org/plugins/normal-module-replacement-plugin/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;NormalModuleReplacementPlugin&lt;/a&gt; 的内置插件。使用它可以非常方便地替换指定的模块文件。&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;new webpack.NormalModuleReplacementPlugin(
  resourceRegExp,
  newResource
);
&lt;/code&gt;&lt;/pre&gt;
    
    </summary>
    
    
      <category term="programming" scheme="https://blog.mutoo.im/categories/programming/"/>
    
      <category term="web" scheme="https://blog.mutoo.im/categories/programming/web/"/>
    
    
      <category term="javascript" scheme="https://blog.mutoo.im/tags/javascript/"/>
    
      <category term="webpack" scheme="https://blog.mutoo.im/tags/webpack/"/>
    
      <category term="patch" scheme="https://blog.mutoo.im/tags/patch/"/>
    
  </entry>
  
  <entry>
    <title>动森二维码生成器：服装类（后篇）</title>
    <link href="https://blog.mutoo.im/2020/07/pro-design-for-animalcrossing-qrcode-gen-part-ii/"/>
    <id>https://blog.mutoo.im/2020/07/pro-design-for-animalcrossing-qrcode-gen-part-ii/</id>
    <published>2020-07-05T11:27:30.000Z</published>
    <updated>2021-12-02T14:43:19.000Z</updated>
    
    <summary type="html">
    
      &lt;p&gt;&lt;a href=&quot;/2020/06/pro-design-for-animalcrossing-qrcode-gen-part-i/&quot;&gt;前篇&lt;/a&gt;写到动森二维码生成器的二维码划分规则以及预览模型的 UV 贴图。根据我的设想，接下来我要在 Aseprite 画板上将这个模型渲染出来，并将用户绘制的图案通过 UV 贴图的方式绘制到模型上。而目前我所拥有的东西只有：调整过 UV 贴图坐标的 6 个衣服模型、在 Aseprite 读取和写入像素的 Lua API，还有记忆中模糊的图形学知识。本文简单记录一下我当时的思路，以及遇到的一些细节问题，如果对实现有兴趣，可以直接访问 Github 上的&lt;a href=&quot;https://github.com/mutoo/aseprite-animalcrossing-qrcode-gen&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;该项目&lt;/a&gt;。&lt;/p&gt;
    
    </summary>
    
    
      <category term="project" scheme="https://blog.mutoo.im/categories/project/"/>
    
    
      <category term="aseprite" scheme="https://blog.mutoo.im/tags/aseprite/"/>
    
      <category term="animalcrossing" scheme="https://blog.mutoo.im/tags/animalcrossing/"/>
    
      <category term="rasterization" scheme="https://blog.mutoo.im/tags/rasterization/"/>
    
  </entry>
  
  <entry>
    <title>动森二维码生成器：服装类（前篇）</title>
    <link href="https://blog.mutoo.im/2020/06/pro-design-for-animalcrossing-qrcode-gen-part-i/"/>
    <id>https://blog.mutoo.im/2020/06/pro-design-for-animalcrossing-qrcode-gen-part-i/</id>
    <published>2020-06-27T11:46:38.346Z</published>
    <updated>2021-12-02T14:43:19.000Z</updated>
    
    <summary type="html">
    
      &lt;p&gt;在开发动森二维码生成器的时候，对于服装类设计的生成，一开始我并没有很好的想法。游戏中对贴图的是分块绘制的，并且有一个动态模型可以展示衣服绘制的效果。对比同类工具 &lt;a href=&quot;https://acpatterns.com/editor&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Animal Crossing Pattern Tool&lt;/a&gt;（下称 ACPT），他们也提供了 3D 模型用于展示贴图效果。但要如何在 Aseprite 中实现展示 3D 模型，我并不是很有把握，毕竟这是一款用于绘制 2D 像素图的工具。另外如何给贴图分块，也需要深入分析。本文先记录一下贴图的划分，之后再写一篇分析 3D 模型的渲染。&lt;/p&gt;
    
    </summary>
    
    
      <category term="project" scheme="https://blog.mutoo.im/categories/project/"/>
    
    
      <category term="qrcode" scheme="https://blog.mutoo.im/tags/qrcode/"/>
    
      <category term="aseprite" scheme="https://blog.mutoo.im/tags/aseprite/"/>
    
      <category term="animalcrossing" scheme="https://blog.mutoo.im/tags/animalcrossing/"/>
    
  </entry>
  
  <entry>
    <title>动森二维码生成器 for Aseprite</title>
    <link href="https://blog.mutoo.im/2020/05/qrcode-generator-for-aseprite/"/>
    <id>https://blog.mutoo.im/2020/05/qrcode-generator-for-aseprite/</id>
    <published>2020-05-18T23:28:53.000Z</published>
    <updated>2021-12-02T14:43:19.000Z</updated>
    
    <summary type="html">
    
      &lt;p&gt;最近翻到一本不错的像素书：由 &lt;a href=&quot;https://nostarch.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Nostarch Press&lt;/a&gt; 出版的 &lt;a href=&quot;https://nostarch.com/pixelart&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Make Your Own Pixel Art&lt;/a&gt;。Nostrach Press 专门出版极客类的书籍，里面有很多看到标题就有兴趣读下去的书，非常适合我。&lt;/p&gt;
&lt;p&gt;而这本 Make Your Own Pixel Art 的作者 &lt;a href=&quot;https://twitter.com/gmshivers&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Janeifer&lt;/a&gt; 拥有 30 年的像素画经验，在书中非常系统地讲解了像素画入门的各个方面，还提供了不错的练习素材。并且书中使用的编辑器正是我非常喜欢的 &lt;a href=&quot;https://www.aseprite.org/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Aseprite&lt;/a&gt;。正好最近时间比较多，就又拿起来画板和鼠标瞎画点东西。&lt;/p&gt;
&lt;p&gt;而更让我惊喜的是，这款买了很久的小而专业的像素绘画软件，居然支持自己编写插件。从 Aseprite v1.2.10-beta2 版本开始，作者引入了 Lua 语言来扩展编辑器，允许用户编写一些&lt;a href=&quot;https://community.aseprite.org/t/aseprite-scripts-collection/3599&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;定制化的功能&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;于是我开始琢磨着用它做点什么。正好最近在玩动物森友会，游戏里允许玩家自己创做像素风格的图案用来装饰各种物品、衣服、地面。另外，新版的 Animal Crossing: New Horizons 可以通过手机 App 扫描早期版本的 Animal Crossing: New Leaf （下称 ACNL） 玩家绘制的图案的二维码，导入这些现存的图案。&lt;/p&gt;
&lt;p&gt;但要知道，不像 3DS 上的 ACNL 可以使用双屏 + 画笔来做画。在 Nintendo Switch 上使用手柄做画有多难受，可想而知。虽然基础画板只有 32 x 32 像素，但是切换颜色、工具等操作，实再不如在电脑上作画来得舒服。我想，如果能直接在 Aseprite 这种专业软件中作画，然后直接生成二维码，再传送到游戏里使用，岂不是非常方便。&lt;/p&gt;
    
    </summary>
    
    
      <category term="project" scheme="https://blog.mutoo.im/categories/project/"/>
    
    
      <category term="qrcode" scheme="https://blog.mutoo.im/tags/qrcode/"/>
    
      <category term="aseprite" scheme="https://blog.mutoo.im/tags/aseprite/"/>
    
      <category term="pixel" scheme="https://blog.mutoo.im/tags/pixel/"/>
    
      <category term="animalcrossing" scheme="https://blog.mutoo.im/tags/animalcrossing/"/>
    
  </entry>
  
  <entry>
    <title>动森图鉴+开发笔记</title>
    <link href="https://blog.mutoo.im/2020/05/critterpedia-plus-devlog/"/>
    <id>https://blog.mutoo.im/2020/05/critterpedia-plus-devlog/</id>
    <published>2020-05-07T01:59:04.000Z</published>
    <updated>2021-12-02T14:43:19.000Z</updated>
    
    <summary type="html">
    
      &lt;p&gt;这两个月受到疫情影响，从四月中开始在家办公，四月底开始降薪，并且到五月初的这两个多星期进入了做三休四的节奏，每周强制休二天年假，不知何时是头。&lt;/p&gt;
&lt;p&gt;由于在家工作，有更多的时间做自己想做的事。为了给自己减压，于是入了动物之森 Switch 版开始捡树枝。玩了几个星期发现其实自己并不是很喜欢联机，硬是把一个休闲社交游戏玩成了单机游戏。&lt;/p&gt;
&lt;p&gt;不过动森的探索性还是挺强的，光是收集小动物就可以折腾很久。而且游戏时间与现实同步，每过一个月就会有新的物种出现。有时候需要查一下攻略才知道最近新出了啥动物。&lt;/p&gt;
&lt;p&gt;在网上浏览这些攻略的时候就想，为啥大家都把数据做成表格的形式，非常不直观，不如做成像游戏中的图鉴，还可以加上自己的改进。例如其它网站上对鱼的影子的描述，只是用文字写着 “Smallest (1)”、“Small (2)”…“Latest (6)” 这样让人摸不着头脑的表述。&lt;/p&gt;
    
    </summary>
    
    
      <category term="project" scheme="https://blog.mutoo.im/categories/project/"/>
    
    
      <category term="github" scheme="https://blog.mutoo.im/tags/github/"/>
    
      <category term="animalcrossing" scheme="https://blog.mutoo.im/tags/animalcrossing/"/>
    
      <category term="critterpedia" scheme="https://blog.mutoo.im/tags/critterpedia/"/>
    
      <category term="react" scheme="https://blog.mutoo.im/tags/react/"/>
    
  </entry>
  
  <entry>
    <title>给 Apollo-Link 打补丁</title>
    <link href="https://blog.mutoo.im/2020/03/a-quick-and-dirty-way-to-patch-a-lib/"/>
    <id>https://blog.mutoo.im/2020/03/a-quick-and-dirty-way-to-patch-a-lib/</id>
    <published>2020-03-17T17:19:47.000Z</published>
    <updated>2021-12-02T14:43:19.000Z</updated>
    
    <summary type="html">
    
      &lt;p&gt;公司最近上线了一个主要由我负责的 React 项目。Frontend Team Lead 希望把 Graphql 请求由 POST 方式改成 GET 方式，这样就可以借助 CDN 进行缓存。&lt;/p&gt;
&lt;p&gt;由于项目中使用的是 Apollo Client，于是只需要简单地对 ApolloHttpLink 加上一条配置即可：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;const client = new ApolloClient({
  link: ApolloLink.from([
    // ...
    createHttpLink({
      // ...
      useGETForQueries: true,
    }),
  ]),
  cache: new InMemoryCache(),
});

export default client;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;不过我检查了一下项目中的一些 query 定义。有些 query 还是挺大的，其中最长的那个请求有 2288 个字符。我印象中 Internet Explorer 似乎有&lt;a href=&quot;https://support.microsoft.com/en-us/help/208427/maximum-url-length-is-2-083-characters-in-internet-explorer&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;最长 URL 限制&lt;/a&gt;，于是下载了个微软官网的 &lt;a href=&quot;https://developer.microsoft.com/en-us/microsoft-edge/tools/vms/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;IE11 虚拟机&lt;/a&gt;，随手做了一下测试。&lt;/p&gt;
    
    </summary>
    
    
      <category term="programming" scheme="https://blog.mutoo.im/categories/programming/"/>
    
      <category term="web" scheme="https://blog.mutoo.im/categories/programming/web/"/>
    
    
      <category term="javascript" scheme="https://blog.mutoo.im/tags/javascript/"/>
    
      <category term="patch" scheme="https://blog.mutoo.im/tags/patch/"/>
    
  </entry>
  
  <entry>
    <title>「攻略」JetBrains Quest S1E3</title>
    <link href="https://blog.mutoo.im/2020/03/jetbrains-quest-session-1-episode-3/"/>
    <id>https://blog.mutoo.im/2020/03/jetbrains-quest-session-1-episode-3/</id>
    <published>2020-03-14T11:50:00.000Z</published>
    <updated>2022-03-02T03:33:59.000Z</updated>
    
    <summary type="html">
    
      &lt;p&gt;书接上回，续 &lt;a href=&quot;/2020/03/jetbrains-quest-session-1-episode-1/&quot;&gt;JetBrains Quest S1E2&lt;/a&gt; 之后，3月13日 JetBrains Quest 发布了本次&lt;a href=&quot;https://twitter.com/jetbrains/status/1238420744817782784&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;最后一个挑战&lt;/a&gt;。因为感冒的原因，休息了一天，在周六深夜才发现题目已经出来了，又精神了起来。迷面如下：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Last Quest #JetBrainsQuest ⚔
SGF2ZSB5b3Ugc2VlbiB0aGUgcG9zdCBvbiBvdXIgSW5zdGFncmFtIGFjY291bnQ/
&lt;/code&gt;&lt;/pre&gt;
&lt;div class=&quot;mt-error&quot;&gt;
剧透警告！！！本文记录了挑战 III 的攻略过程。如果有兴趣自行通关，请暂时不要往下读！！！
&lt;/div&gt;
    
    </summary>
    
    
    
      <category term="jetbrains" scheme="https://blog.mutoo.im/tags/jetbrains/"/>
    
      <category term="quest" scheme="https://blog.mutoo.im/tags/quest/"/>
    
  </entry>
  
  <entry>
    <title>「攻略」JetBrains Quest S1E2</title>
    <link href="https://blog.mutoo.im/2020/03/jetbrains-quest-session-1-episode-2/"/>
    <id>https://blog.mutoo.im/2020/03/jetbrains-quest-session-1-episode-2/</id>
    <published>2020-03-12T02:20:17.000Z</published>
    <updated>2021-12-02T14:43:19.000Z</updated>
    
    <summary type="html">
    
      &lt;p&gt;书接上回，续 &lt;a href=&quot;/2020/03/jetbrains-quest-session-1/&quot;&gt;JetBrains Quest S1E1&lt;/a&gt; 之后，@JetBrains 发布了&lt;a href=&quot;https://twitter.com/jetbrains/status/1237694815283879943&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;挑战第二弹&lt;/a&gt;。废话少说，来看迷面：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Time for the next #JetBrainsQuest!
.spleh A+lrtC/dmC .thgis fo tuo si ti semitemos ,etihw si txet nehw sa drah kooL .tseretni wohs dluohs uoy ecalp a si ,dessecorp si xat hctuD erehw esac ehT .sedih tseuq fo txen eht erehw si ,deificeps era segaugnal cificeps-niamod tcudorp ehT
&lt;/code&gt;&lt;/pre&gt;
&lt;div class=&quot;mt-error&quot;&gt;
剧透警告！！！本文记录了挑战 II 的攻略过程。如果有兴趣自行通关，请暂时不要往下读！！！
&lt;/div&gt;
    
    </summary>
    
    
    
      <category term="jetbrains" scheme="https://blog.mutoo.im/tags/jetbrains/"/>
    
      <category term="quest" scheme="https://blog.mutoo.im/tags/quest/"/>
    
  </entry>
  
  <entry>
    <title>「攻略」JetBrains Quest S1E1</title>
    <link href="https://blog.mutoo.im/2020/03/jetbrains-quest-session-1/"/>
    <id>https://blog.mutoo.im/2020/03/jetbrains-quest-session-1/</id>
    <published>2020-03-11T22:37:28.000Z</published>
    <updated>2021-12-02T14:43:19.000Z</updated>
    
    <summary type="html">
    
      &lt;p&gt;换工作后，新的公司没有提供 Jetbrains IDE 的包年订阅。在这四个多月里，秉承入乡随俗的习惯，我跟新团队一起用 Visual Studio Code 进行项目开发。一开始非常不顺手，后来安装了各种插件并慢慢适应，勉强还能工作。虽然 VSC 也是可以将就的，但就是没有 Webstorm/Phpstorm&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;#fn1&quot; id=&quot;fnref1&quot;&gt;[1]&lt;/a&gt;&lt;/sup&gt; 来得爽。&lt;/p&gt;
&lt;p&gt;Jetbrains 的 IDE 功能强大，就连内置的版本控制都比其它独立的 App 要强大得多。为了配合 VSC，我还得挑选其它的 Git 客户端来协作，先后用了 &lt;a href=&quot;https://www.sourcetreeapp.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Source Tree&lt;/a&gt;，&lt;a href=&quot;https://www.gitkraken.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Git Kraken&lt;/a&gt; 和 &lt;a href=&quot;https://git-fork.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Fork&lt;/a&gt;。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Source Tree - 免费，但是 Diff / Merge 功能不够强大，没有 fast-forward 之类的功能。&lt;/li&gt;
&lt;li&gt;Git Kraken - 非常强大，前期免费，但是后来改成个人版 30 天试用，到期后开始对私有仓库收费了。&lt;/li&gt;
&lt;li&gt;Fork - 免费，小清新。比 Source Tree 易用，有同分支 fast-forward 功能，但不能跨分支。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;折腾了一圈，到最后还打算自费回到 JetBrains IDE 的怀抱。&lt;/p&gt;
&lt;p&gt;来得早不如来得巧，3月9日，&lt;a href=&quot;https://twitter.com/jetbrains/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;@JetBrains&lt;/a&gt; 发布了&lt;a href=&quot;https://twitter.com/jetbrains/status/1236986174075482113&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;第一个挑战信&lt;/a&gt;，内容如下：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;JetBrains Quest begins… #JetBrainsQuest
48 61 76 65 20 79 6f 75 20 73 65 65 6e 20 74 68 65 20 73 6f 75 72 63 65 20 63 6f 64 65 20 6f 66 20 74 68 65 20 4a 65 74 42 72 61 69 6e 73 20 77 65 62 73 69 74 65 3f
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;作为解迷爱好者，一下就精神起来了。&lt;/p&gt;
&lt;div class=&quot;mt-error&quot;&gt;
剧透警告！！！本文记录了挑战 I 的攻略过程。如果有兴趣自行通关，请暂时不要往下读！！！
&lt;/div&gt;
    
    </summary>
    
    
    
      <category term="jetbrains" scheme="https://blog.mutoo.im/tags/jetbrains/"/>
    
      <category term="quest" scheme="https://blog.mutoo.im/tags/quest/"/>
    
  </entry>
  
  <entry>
    <title>助你同时维护多个项目的终端神器：Tmux</title>
    <link href="https://blog.mutoo.im/2020/02/working-on-multiple-project-with-tmux/"/>
    <id>https://blog.mutoo.im/2020/02/working-on-multiple-project-with-tmux/</id>
    <published>2020-02-18T00:24:08.000Z</published>
    <updated>2021-12-02T14:43:19.000Z</updated>
    
    <summary type="html">
    
      &lt;p&gt;最近工作中需要来回在几个项目间切换，即使是使用支持多标签的终端感觉也有点不够用。于是开始寻找新的解决方案。最后遇到了 &lt;a href=&quot;https://github.com/tmux/tmux&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;tmux&lt;/a&gt; 感觉有点相见恨晚。&lt;/p&gt;
&lt;p&gt;Tmux 是一个虚拟终端管理工具，或者叫终端复用器（Terminal Multiplexer）。它支持同屏多面板（Panel）、多窗口（Window）、多会话（Session），还能够后台挂起、恢复。这些抽象概念都是为了帮助你快速地从中断状态回到工作状态。&lt;/p&gt;
&lt;p&gt;终端复用这个概念我之前有接触过。最早的时候使用过的一款叫 GNU Screen 的工具。当你远程登陆到服务器上的时候，由于各种原因断开连接，再重联到服务器，之前在终端运行的各种脚本就不见了，正在运行的程序也会被终止。而 Screen 相当于在服务端运行一个守护进程（Daemon），当你挂起当前终端的时候，它并没有被真的关掉，而是原地待命，直到你再次接入，先前的终端就像没有被动过一样。&lt;/p&gt;
&lt;p&gt;而 Tmux 不仅延续了这些基本理念，还发展出了一套非常高级的终端管理方案。此外开源社区还提供了大量优秀的插件给大家自定义。本文简单记录一下我的 Tmux 使用过程。&lt;/p&gt;
    
    </summary>
    
    
      <category term="utilities" scheme="https://blog.mutoo.im/categories/utilities/"/>
    
    
      <category term="tmux" scheme="https://blog.mutoo.im/tags/tmux/"/>
    
  </entry>
  
  <entry>
    <title>中文博客的字体选型</title>
    <link href="https://blog.mutoo.im/2020/02/fonts-for-my-blog-theme/"/>
    <id>https://blog.mutoo.im/2020/02/fonts-for-my-blog-theme/</id>
    <published>2020-02-05T12:14:55.000Z</published>
    <updated>2021-12-02T14:43:19.000Z</updated>
    
    <summary type="html">
    
      &lt;p&gt;去年五月份制作这个主题的时候，特别研究了一下博客字体的选型，当时想写个博客记录一下，但是因为曦仔出生后比较忙就忘了。&lt;/p&gt;
&lt;p&gt;如今 &lt;a href=&quot;https://www.jetbrains.com/lp/mono/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;JetBrains Mono&lt;/a&gt; 发布后有一段时间了，在 IDE 中使用了几个星期，感觉非常好。于是想把它放到博客上用，也趁机把这篇博客整理出来。&lt;/p&gt;
&lt;p&gt;如果是纯英文博客的话，选字体的事情比较好办，因为直接引入 &lt;a href=&quot;https://fonts.google.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Web Fonts&lt;/a&gt; 的成本非常低（文件小），而且现在 Web Fonts 的&lt;a href=&quot;https://caniuse.com/#search=web%20font&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;兼容性&lt;/a&gt;很好，基本上所有主流浏览器都支持。于是只要选择几款好看的 Web Fonts 就能保证各个平台所用的字体的一致性。&lt;/p&gt;
&lt;p&gt;但是对于中文博客来说，使用 Web Font 的使用成本太高了。由于中文的复杂性，每个汉字都有专门的字形，而非像拉丁文一样由一些基本字母符号组成单词，这就导致中文字体文件非常之大。所以中文 Web Font 很难流行起来。&lt;/p&gt;
&lt;p&gt;于是，中文博客的字体选型最安全的作法，就是从各平台的系统字体中选择可以用的方案。不过对于博客中的代码片段，我们仍然可以选择喜欢的专用字体。&lt;/p&gt;
    
    </summary>
    
    
    
      <category term="blog" scheme="https://blog.mutoo.im/tags/blog/"/>
    
      <category term="font" scheme="https://blog.mutoo.im/tags/font/"/>
    
      <category term="webfont" scheme="https://blog.mutoo.im/tags/webfont/"/>
    
  </entry>
  
  <entry>
    <title>使用 Webpack Loader 加载 Icon Font 映射</title>
    <link href="https://blog.mutoo.im/2020/02/icon-font-loader/"/>
    <id>https://blog.mutoo.im/2020/02/icon-font-loader/</id>
    <published>2020-02-03T03:25:00.000Z</published>
    <updated>2021-12-02T14:43:19.000Z</updated>
    
    <summary type="html">
    
      &lt;p&gt;最近在做的新项目是使用 React 构建一个新的网站，实现新的需求的同时慢慢将旧网站迁移过来。其中的一部分工作是建立一个可重用的前端组件库。&lt;/p&gt;
&lt;p&gt;实现一个前端组件库需要非常多的工作量，这里有一份详细的 &lt;a href=&quot;https://designsystemchecklist.com/category/core-components/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Checklist&lt;/a&gt; 可供参考。除此之外，我们还需要为这些可重用组件建立一份文档，这样大家就可以照着文档去使用这些组件了。在对比了一些文档工具后，我选择了 &lt;a href=&quot;https://storybook.js.org/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Storybook&lt;/a&gt; 这款非常小清新的可视化组件文档生成器。它支持各种主流框架。&lt;/p&gt;
&lt;p&gt;集成 Storybook 到项目的过程遇到了不少坑，不过这篇博客我们暂时不讨论这些，有空的话我再另开一篇文章吧。本文我想聊聊写文档的时候遇到的一些需求。&lt;/p&gt;
&lt;h3 id=&quot;背景&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;#背景&quot;&gt;¶&lt;/a&gt;背景&lt;/h3&gt;
&lt;p&gt;在项目中我们使用了一款自制的图标字体（Icon Font），以字体的形式将网站常用的图标打包成 Web Font，然后再在页面中使用。&lt;/p&gt;
&lt;p&gt;从设计师同事那获得的素材文件如下：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-plain&quot;&gt;~/Downloads/racing20_march
├── fonts
│   ├── racing20.eot
│   ├── racing20.svg
│   ├── racing20.ttf
│   └── racing20.woff
├── icons-reference.html
└── styles.css
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;其中 &lt;code&gt;icons-reference.html&lt;/code&gt; 是说明文档，内里介绍了如何使用这个字体，以及一个图标名称及对应字符的映射关系。&lt;/p&gt;
&lt;p&gt;所谓映射（Mapping），可以从 &lt;code&gt;styles.css&lt;/code&gt; 中看到一些例子：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-css&quot;&gt;.icon-article:before {
  content: &amp;quot;\61&amp;quot;;
}
.icon-calendar:before {
  content: &amp;quot;\64&amp;quot;;
}
...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;即 &lt;code&gt;article&lt;/code&gt; 图标对应的字符是 &lt;code&gt;\61&lt;/code&gt; 即字母 &lt;code&gt;a&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;不过使用的时候我们并不需要关心这个映射。只要知道想用这个图标的话，引用对应的英文名即可：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-html&quot;&gt;&amp;lt;i class=&amp;quot;icon icon-article&amp;quot;&amp;gt;&amp;lt;/i&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;需求&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;#需求&quot;&gt;¶&lt;/a&gt;需求&lt;/h3&gt;
&lt;p&gt;我们要做的正是将这个说明文档中的映射关系集成到我们的 Storybook 组件文档中去。以便在文档中显示所有图标，还可以直接点击图标复制组件代码，方便引用。&lt;/p&gt;
&lt;p&gt;一个简单的方法就是手动创建这个列表，把映射关系整理到一个数组中。但是考虑到后期的维护，如新增图标或者映射有变化，就需要重新校对这个列表，是一件很麻烦的事。&lt;/p&gt;
&lt;p&gt;既然如此，何不一开始就将其自动化？我们只需要写一个脚本将这个 &lt;code&gt;styles.css&lt;/code&gt; 中的映射关系提取出来，就可以为我所用。另外这个 &lt;code&gt;styles.css&lt;/code&gt; 作为唯一数据源，更新起来也很方便，直接将设计师提供的新文件覆盖旧文件即可。符合 &lt;code&gt;Single Source of Truth&lt;/code&gt; 原则。&lt;/p&gt;
    
    </summary>
    
    
    
      <category term="font" scheme="https://blog.mutoo.im/tags/font/"/>
    
      <category term="webpack" scheme="https://blog.mutoo.im/tags/webpack/"/>
    
      <category term="icon" scheme="https://blog.mutoo.im/tags/icon/"/>
    
  </entry>
  
  <entry>
    <title>写在 2019 年末</title>
    <link href="https://blog.mutoo.im/2019/12/at-the-end-of-2019/"/>
    <id>https://blog.mutoo.im/2019/12/at-the-end-of-2019/</id>
    <published>2019-12-21T10:43:02.000Z</published>
    <updated>2021-12-02T14:43:19.000Z</updated>
    
    <summary type="html">
    
      
      
        
        
          &lt;p&gt;2019
        
      
    
    </summary>
    
    
      <category term="life" scheme="https://blog.mutoo.im/categories/life/"/>
    
      <category term="melbourne" scheme="https://blog.mutoo.im/categories/life/melbourne/"/>
    
    
      <category term="hsi" scheme="https://blog.mutoo.im/tags/hsi/"/>
    
  </entry>
  
  <entry>
    <title>Edge 浏览器无法访问 VirtualBox 内的网站</title>
    <link href="https://blog.mutoo.im/2019/07/edge-could-not-access-sites-in-virtualbox-issue/"/>
    <id>https://blog.mutoo.im/2019/07/edge-could-not-access-sites-in-virtualbox-issue/</id>
    <published>2019-07-25T23:31:10.000Z</published>
    <updated>2021-12-02T14:43:19.000Z</updated>
    
    <summary type="html">
    
      
      
        
        
          &lt;h2 id=&quot;Issue&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;#Issue&quot;&gt;¶&lt;/a&gt;Issue&lt;/h2&gt;
&lt;p&gt;公司的项目会把 Development 阶段的网站用 Vagrant 管理，托管在 VirtualBox 虚拟机中。虚拟机使用的网络接口是 Host-Only 类型的，只允许主机访问虚拟机，而阻止内网中其它设备访问虚拟机（区别于桥接）。同时方便同一个主机上多个虚拟机之间组网通讯（提供 DHCP）。最近升级了 VirtualBox 到最新版 6.0
        
      
    
    </summary>
    
    
      <category term="issues" scheme="https://blog.mutoo.im/categories/issues/"/>
    
    
      <category term="edge" scheme="https://blog.mutoo.im/tags/edge/"/>
    
      <category term="virtualbox" scheme="https://blog.mutoo.im/tags/virtualbox/"/>
    
  </entry>
  
</feed>
