木匣子

Web/Game/Programming/Life etc.

动森图鉴+开发笔记

这两个月受到疫情影响,从四月中开始在家办公,四月底开始降薪,并且到五月初的这两个多星期进入了做三休四的节奏,每周强制休二天年假,不知何时是头。

由于在家工作,有更多的时间做自己想做的事。为了给自己减压,于是入了动物之森 Switch 版开始捡树枝。玩了几个星期发现其实自己并不是很喜欢联机,硬是把一个休闲社交游戏玩成了单机游戏。

不过动森的探索性还是挺强的,光是收集小动物就可以折腾很久。而且游戏时间与现实同步,每过一个月就会有新的物种出现。有时候需要查一下攻略才知道最近新出了啥动物。

在网上浏览这些攻略的时候就想,为啥大家都把数据做成表格的形式,非常不直观,不如做成像游戏中的图鉴,还可以加上自己的改进。例如其它网站上对鱼的影子的描述,只是用文字写着 “Smallest (1)”、“Small (2)”…“Latest (6)” 这样让人摸不着头脑的表述。

给 Apollo-Link 打补丁

公司最近上线了一个主要由我负责的 React 项目。Frontend Team Lead 希望把 Graphql 请求由 POST 方式改成 GET 方式,这样就可以借助 CDN 进行缓存。

由于项目中使用的是 Apollo Client,于是只需要简单地对 ApolloHttpLink 加上一条配置即可:

const client = new ApolloClient({
  link: ApolloLink.from([
    // ...
    createHttpLink({
      // ...
      useGETForQueries: true,
    }),
  ]),
  cache: new InMemoryCache(),
});

export default client;

不过我检查了一下项目中的一些 query 定义。有些 query 还是挺大的,其中最长的那个请求有 2288 个字符。我印象中 Internet Explorer 似乎有最长 URL 限制,于是下载了个微软官网的 IE11 虚拟机,随手做了一下测试。

「攻略」JetBrains Quest S1E3

书接上回,续 JetBrains Quest S1E2 之后,3月13日 JetBrains Quest 发布了本次最后一个挑战。因为感冒的原因,休息了一天,在周六深夜才发现题目已经出来了,又精神了起来。迷面如下:

Last Quest #JetBrainsQuest ⚔
SGF2ZSB5b3Ugc2VlbiB0aGUgcG9zdCBvbiBvdXIgSW5zdGFncmFtIGFjY291bnQ/
剧透警告!!!本文记录了挑战 III 的攻略过程。如果有兴趣自行通关,请暂时不要往下读!!!

「攻略」JetBrains Quest S1E2

书接上回,续 JetBrains Quest S1E1 之后,@JetBrains 发布了挑战第二弹。废话少说,来看迷面:

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
剧透警告!!!本文记录了挑战 II 的攻略过程。如果有兴趣自行通关,请暂时不要往下读!!!

「攻略」JetBrains Quest S1E1

换工作后,新的公司没有提供 Jetbrains IDE 的包年订阅。在这四个多月里,秉承入乡随俗的习惯,我跟新团队一起用 Visual Studio Code 进行项目开发。一开始非常不顺手,后来安装了各种插件并慢慢适应,勉强还能工作。虽然 VSC 也是可以将就的,但就是没有 Webstorm/Phpstorm[1] 来得爽。

Jetbrains 的 IDE 功能强大,就连内置的版本控制都比其它独立的 App 要强大得多。为了配合 VSC,我还得挑选其它的 Git 客户端来协作,先后用了 Source TreeGit KrakenFork

  • Source Tree - 免费,但是 Diff / Merge 功能不够强大,没有 fast-forward 之类的功能。
  • Git Kraken - 非常强大,前期免费,但是后来改成个人版 30 天试用,到期后开始对私有仓库收费了。
  • Fork - 免费,小清新。比 Source Tree 易用,有同分支 fast-forward 功能,但不能跨分支。

折腾了一圈,到最后还打算自费回到 JetBrains IDE 的怀抱。

来得早不如来得巧,3月9日,@JetBrains 发布了第一个挑战信,内容如下:

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

作为解迷爱好者,一下就精神起来了。

剧透警告!!!本文记录了挑战 I 的攻略过程。如果有兴趣自行通关,请暂时不要往下读!!!

助你同时维护多个项目的终端神器:Tmux

最近工作中需要来回在几个项目间切换,即使是使用支持多标签的终端感觉也有点不够用。于是开始寻找新的解决方案。最后遇到了 tmux 感觉有点相见恨晚。

Tmux 是一个虚拟终端管理工具,或者叫终端复用器(Terminal Multiplexer)。它支持同屏多面板(Panel)、多窗口(Window)、多会话(Session),还能够后台挂起、恢复。这些抽象概念都是为了帮助你快速地从中断状态回到工作状态。

终端复用这个概念我之前有接触过。最早的时候使用过的一款叫 GNU Screen 的工具。当你远程登陆到服务器上的时候,由于各种原因断开连接,再重联到服务器,之前在终端运行的各种脚本就不见了,正在运行的程序也会被终止。而 Screen 相当于在服务端运行一个守护进程(Daemon),当你挂起当前终端的时候,它并没有被真的关掉,而是原地待命,直到你再次接入,先前的终端就像没有被动过一样。

而 Tmux 不仅延续了这些基本理念,还发展出了一套非常高级的终端管理方案。此外开源社区还提供了大量优秀的插件给大家自定义。本文简单记录一下我的 Tmux 使用过程。

中文博客的字体选型

去年五月份制作这个主题的时候,特别研究了一下博客字体的选型,当时想写个博客记录一下,但是因为曦仔出生后比较忙就忘了。

如今 JetBrains Mono 发布后有一段时间了,在 IDE 中使用了几个星期,感觉非常好。于是想把它放到博客上用,也趁机把这篇博客整理出来。

如果是纯英文博客的话,选字体的事情比较好办,因为直接引入 Web Fonts 的成本非常低(文件小),而且现在 Web Fonts 的兼容性很好,基本上所有主流浏览器都支持。于是只要选择几款好看的 Web Fonts 就能保证各个平台所用的字体的一致性。

但是对于中文博客来说,使用 Web Font 的使用成本太高了。由于中文的复杂性,每个汉字都有专门的字形,而非像拉丁文一样由一些基本字母符号组成单词,这就导致中文字体文件非常之大。所以中文 Web Font 很难流行起来。

于是,中文博客的字体选型最安全的作法,就是从各平台的系统字体中选择可以用的方案。不过对于博客中的代码片段,我们仍然可以选择喜欢的专用字体。

使用 Webpack Loader 加载 Icon Font 映射

最近在做的新项目是使用 React 构建一个新的网站,实现新的需求的同时慢慢将旧网站迁移过来。其中的一部分工作是建立一个可重用的前端组件库。

实现一个前端组件库需要非常多的工作量,这里有一份详细的 Checklist 可供参考。除此之外,我们还需要为这些可重用组件建立一份文档,这样大家就可以照着文档去使用这些组件了。在对比了一些文档工具后,我选择了 Storybook 这款非常小清新的可视化组件文档生成器。它支持各种主流框架。

集成 Storybook 到项目的过程遇到了不少坑,不过这篇博客我们暂时不讨论这些,有空的话我再另开一篇文章吧。本文我想聊聊写文档的时候遇到的一些需求。

背景

在项目中我们使用了一款自制的图标字体(Icon Font),以字体的形式将网站常用的图标打包成 Web Font,然后再在页面中使用。

从设计师同事那获得的素材文件如下:

~/Downloads/racing20_march
├── fonts
│   ├── racing20.eot
│   ├── racing20.svg
│   ├── racing20.ttf
│   └── racing20.woff
├── icons-reference.html
└── styles.css

其中 icons-reference.html 是说明文档,内里介绍了如何使用这个字体,以及一个图标名称及对应字符的映射关系。

所谓映射(Mapping),可以从 styles.css 中看到一些例子:

.icon-article:before {
  content: "\61";
}
.icon-calendar:before {
  content: "\64";
}
...

article 图标对应的字符是 \61 即字母 a

不过使用的时候我们并不需要关心这个映射。只要知道想用这个图标的话,引用对应的英文名即可:

<i class="icon icon-article"></i>

需求

我们要做的正是将这个说明文档中的映射关系集成到我们的 Storybook 组件文档中去。以便在文档中显示所有图标,还可以直接点击图标复制组件代码,方便引用。

一个简单的方法就是手动创建这个列表,把映射关系整理到一个数组中。但是考虑到后期的维护,如新增图标或者映射有变化,就需要重新校对这个列表,是一件很麻烦的事。

既然如此,何不一开始就将其自动化?我们只需要写一个脚本将这个 styles.css 中的映射关系提取出来,就可以为我所用。另外这个 styles.css 作为唯一数据源,更新起来也很方便,直接将设计师提供的新文件覆盖旧文件即可。符合 Single Source of Truth 原则。

写在 2019 年末

2019 年马上就要翻篇了,但是回想这两年却没有留下多少文字,有些许遗憾。今年发生了很多大事——对于世界,也对于我。正好借此圣诞假期,作一些记录。

来墨尔本三年多,我爱上了这里,并决定扎根于此。半年前曦仔出生,现在已经是七个多月的健康男宝。也是半年前我们入住了自己拥有的真正意义上的家,结束了到处漂泊的日子。

然而有一件我没有料到的事,这半年来前东家的人事变动,让我犹豫起要不要考虑新的工作机会。随后在老婆大人的鼓励下,在与许多猎头的沟通后,于上个月就职了本地的一家赛马业媒体,负责新网站的前端构建。

跳槽的动力来源有两个:一是对新技术的渴望。我是一个终生学习主义者,并且我希望自己能学以致用。前端发展迅猛,我不想拘泥于一种框架或思维,否则会导致思想僵化。感于尝鲜,并发掘新事物的优势,取长补短,才能让自己立于不败之地。二是来自生活的压力,家里多了一个大娃和小屋要养,原来那点工资已经入不敷出,不得不寻求升职或加薪。而跳槽对我而言是一个较优的选项。

然而生活并不是一帆风顺,我觉得这一年来牺牲最大的就是老婆大人。曦仔出生后,LP 请了一年的产假。前三个月有政府提供的产假津贴,而之后是停薪留职。这半年来我不断地体会到 LP 作为一个母亲的伟大与付出。感慨着女人的不易的同时我也学会了包容和体谅,并尽可能在工作之余参与到曦仔的成长中来。

对比自己的原生家庭,我的父亲这二十年来经营自己的小本生意,兢兢业业辛勤工作,赚的不多,但几乎全年无休。于是我的童年很少有父亲主动的参与。我不希望曦仔的童年也是如此。

庆幸在澳洲文化中「家庭第一」深得人心。下班之后的你是属于家庭的,几乎没有人加班加点。并且大家对新手爸妈是非常宽容的,工作上有更灵活的调整,请假调休非常容易。这些因素大大降低了育娃的心理压力。

看了韩国电影《82 年生金智英》,我觉得东方社会对女性要求得太多,即要牺牲自己的事业,还要奉献自己给家庭和孩子;我觉得这样的社会会产生不少的问题,多数孩子只看到母亲的牺牲,而看不到其实母亲在其它方面也很强大,渐渐地接受了所谓的「现实」,认为女性的归宿便是如此。孩子长大后,留下的男女不平等的「思想钢印」便是得之如此。而这些的观念,往往是代代相传的。这是社会的悲哀。

「金智英」在韩国引起了广泛的讨论,不过与其说是讨论,不如说是对编剧的「讨伐」。连韩国这样的发达国家都如此愚昧不堪,西朝鲜就更不用提了。

LP 希望产假结束后回到工作岗位,一方面可以减轻我的压力,另一方面还可以继续自己的职业规划,为自己的梦想奋斗。我是非常支持的,毕竟曦仔的成长是我们两共同的责任,没有理由让她为了孩子牺牲自己的未来。而我相信孩子在这样的家庭中成长,也会更加健康。

2020 年很快就要到来,把握机遇,迎接挑战 :D

Edge 浏览器无法访问 VirtualBox 内的网站

Issue

公司的项目会把 Development 阶段的网站用 Vagrant 管理,托管在 VirtualBox 虚拟机中。虚拟机使用的网络接口是 Host-Only 类型的,只允许主机访问虚拟机,而阻止内网中其它设备访问虚拟机(区别于桥接)。同时方便同一个主机上多个虚拟机之间组网通讯(提供 DHCP)。最近升级了 VirtualBox 到最新版 6.0 ,但遇到了个怪事。所有的浏览器都能正常打开虚拟机中的网站,唯独 Edge 浏览器不行:

issue-preview

访问网址会出现 DNS 错误的页面,并显示如下信息:

There was a temporary DNS error. Try refreshing the page.
Error Code: INET_E_RESOURCE_NOT_FOUND

发生临时 DNS 错误。请尝试刷新页面。
错误代码: INET_E_RESOURCE_NOT_FOUND

Solution

经过一番检索,试了好几种方法都没有搞定。最终在这个帖子里找了解决方案:

You can workaround this issue by changing your VirtualBox Host-Only Ethernet Adapter’s *NdisDeviceType to 0 and rebooting. You can find the key in Computer\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\{4d36e972-e325-11ce-bfc1-08002be10318}\00XX. The downside to this is that now you’ll have an “Unidentified Network” in your Network and Sharing Center. It’s also managed by Windows Firewall now and by default it is in the Public Profile and it can’t be really changed easily.

– Jani L. Oct 4, 2017

如果你有多个 VirtualBox 网络接口,需要找到正确的网络适配器,可以在 Control Panel\All Control Panel Items\Network Connections 目录下右键相应的网络适配器,然后在 Properties > Networking > Configure... > EventsInformation 文本框架找到如下描述:

Driver Management has concluded the process to add Service
VBoxNetAdp for Device Instance ID ROOT\NET\0000 with the following
status: 0.

其中的 ROOT\NET\0000 应与注册表中 {4d36e972-e325-11ce-bfc1-08002be10318}\00XX\DeviceInstanceID 的键值相对应。则 00XX 就是你要修改的那个网络适配器了。

接下来要做的就是将该路径下键名为 *NdisDeviceType 的键值由 1 改为 0,并重启主机即可。

How / Why

MSDN 对 *NdisDeviceType 这个键的解释可以在这里找到。简而言之就是 UWP(Universal Windows Platform)程序会检查网络适配器的这个键来判断其是否是一个可以联网的网络接口,然后决定是否使用它。

IE 和其它浏览器不是使用 UWP 框架开发的,所以不受影响。而 Edge 正好躺枪。


本文在以下环境中测试

  • Windows 10 Pro(Version 1803, OS Build 17134.885)
  • Microsoft Edge 42.17134.1.0
  • Version 6.0.10 r132072 (Qt5.6.2)