分类
远程工作

远程工作需要的特质:愿意负责

本来想写“愿意背锅”的,后来想想还是不要那么标题党了。

前些天跟朋友聊天,聊到我厂的日常工作。他问我:“你们怎么解决人员互相不熟悉的协作问题的?Tower还是IM?”

我厂日常主要用 IM,包括文字或语音或共享桌面,但这并不是他要的答案。这位朋友是位产品经理,曾经多次向我抱怨说他们公司的前端太不给力,这不会做那不能做,他们产品设计,到最终实现总是大打折扣,产品人员不得不仔细核对每一项细节,并不断跟前端讨价还价,才能有所保障。

所以夏虫不可以语冰,从他的角度,很难理解我厂(全职远程)日常怎么才做能保证效率。

所以我回答:“IM 和文档。还有就是不要甩锅。其实我觉得,协同问题70%来自甩锅。”

“责任分清是不是甩锅?”他又问。

其实对于创业公司而言,最可怕的情况就是,没有大公司的命,得了大公司的病。在做出足够宽足够深的护城河之前,先琢磨怎么厘清责任;大家惦记的不是怎么把事情做好,而是出了问题不是我的责任。

对于远程创业公司来说,这个问题更加致命,因为这样要浪费非常多的沟通成本。所以我如实说出我的想法:“要看具体操作,很可能是。这里的问题在于,分清责任后,是只把自己的责任摘出来做,还是连带督促另一个人;就是分清责任之后,是选择做执行人,还是PM+执行人。”

“团队是合作关系还是里面存在管理关系?”

“合作,基本不存在管理。”

“督促另一个人时,对方如果不愿意怎么办?”

“说明那个人不适合在远程团队里。如果远程团队不能形成互相督促互相配合的氛围,工作效率多半是不够的。”

这两个问题其实是一个意思:你说督促就督促了?别人不听怎么办?其实回顾我的从业经验,大部分互联网公司都没有那么明确的上下级概念,也很少有人会去挑战督促者。大部分情况是,大家都不愿意出头(特有国情),但是有人出头,只要不犯傻,大家多半还是愿意接受领导的。

“挺好。”他最后总结道。

总结

远程工作,对每个参与者的要求都更高,除了能完成日常工作,更友好的合作精神,更主动的参与精神也非常重要。

希望这段对话对大家有帮助。

分类
npm

解决新机不能 npm install 私有仓库的问题

前些天换了电脑,从 iMac 27 Retina 2014 late 升级到 iMac 27 2019。关于前因后果,我写在张大妈,感兴趣的同学可以看下:《肉山的电子产品 篇九:机不如新,人不如故——iMac 27 换新记》

换机器要搭环境。有两个选择:

  1. 整盘复制,利用 Time Machine 之类的工具
  2. 自己慢慢搭

考虑到老电脑已经工作了 5 年,经历了小十个系统版本,各种软件删装无数,里面的垃圾很多;再加上我的环境并不复杂,所以我决定自己慢慢搭。

然后遇到一个问题:npm install 会卡住,没有明显的提示信息,只有一段比较可疑:

The authenticity of host 'GitHub.com (1.1.1.1)' can't be established.
ECDSA key fingerprint is SHA256:abcdefg.
Are you sure you want to continue connecting (yes/no)? 

因为项目中用到一些私有仓库的依赖,所以我怀疑是它们的问题。于是我把私有仓库从 package.json 里移除,再安装,成功。看来猜的没错。

然后我手动 git clone 一个项目到本地,clone 的过程中,会看到上面的提示,手动输入 yes,记录目标机器的指纹,视它安全可靠。clone 完成。再把私有仓库依赖加回 package.json,安装,成功。问题解决。

原因:使用 npm 安装 GitHub 仓库作为依赖,实际上等同于使用 git clone 将目标仓库 clone 到 node_modules 里。而 git 协议依托于 ssh 协议。在新机器上安装时,因为没有访问过目标机器,本地不信任目标机器,而 npm 又没有对这个异常做处理,所以就会卡住,不上不下。

分类
招聘

代友招聘:新西兰远程 Ng 岗位

求推荐前端开发 (Angular),要求三年以上 Angular 经验,英语沟通流利。新西兰公司远程办公,将来有机会来新西兰工作。 ​​​​

详细 JD 点这里

分类
技术

npm 支持开发者添加募款链接

昨天随手升级个人首页的依赖,更新完之后,npm 提示:

6 packages are looking for funding
  run `npm fund` for details

如果你执行 npm fund,可以看到类似这样的信息:

your-repo@0.1.0
├─┬ core-js@3.4.2
│ ├── type: opencollective
│ └── url: https://opencollective.com/core-js
├─┬ eslint@6.7.0
│ └── url: https://opencollective.com/eslint
└─┬ swiper@5.2.1
  ├── type: patreon
  └── url: https://www.patreon.com/vladimirkharlampidi

opencollective 和 patreon 都是众筹网站,只不过众筹的内容不是实物商品,而是支持你喜欢的创作者,无论他是摄影师、画家,还是开源软件作者。据说 Vue 的作者尤雨溪每年可以从 Patreon 上获得将近 $20w 的捐赠,这笔钱可以帮助他以独立身份继续开发 Vue,还可以雇佣一名全职开发者帮助他把这份工作做得更好。

我去 NPM 官网找了一下,npm fund 的文档还没更新上去,只找到这篇 RFC: Add funding support to package.json,大意是包开发者可以在包的描述文件(package.json)里放上一段募款声明,这样包的用户在安装的时候,就会看到我开篇写的那些文字。提醒包的开发者:你们可以通过捐赠的方式,表达对依赖开发者的感谢。

我觉得这种形式挺好的。当然,有些人可能看不惯这种有“伸手嫌疑”的行为,但是,与其在无酬工作中纠结、放弃自己的项目、甚至被别有用心的人利用埋后门,任何不影响安全性、不增加使用负担的变现方式都是合理且值得鼓励的。

希望开源软件开发者越过越好,开源基建开发者越过越好,世界越来越好。

分类
perl

在新 Mac 上配置 Perl

最新的 macOS Catalina 10.15.1 自带 Perl 5.18,但是不包含包管理工具 Cpanm,所以要手动安装。

第一步,安装 xcode。

第二步,安装 homebrew

第三步,安装最新 Perl 5.30(没有 Perl 6……)

brew install perl

安装完成之后,需要验证一下当前使用的 perl 路径 perl -v 如果还是 5.18,那么检查一下引用 whereis perl,应该能看到 /usr/local/bin/perl/usr/bin/perl 前面,并且指向 /usr/local/Cellar/perl/{version}/bin/perl,那么就退出当前 Terminal,重新打开,应该就好了。

第四步,安装 Cpanm

brew install cpanm

第五步,安装其它包

cpan install Test::Base
cpan install IPC::Run

分类
css

诡异的 `height: intrinsic`

我厂最新也是最重要的产品 OpenResty XRay 即将开始邀请测试,所以官网上自然要添加对应的网页。目前该网页已经部署到生产环境,大家可以访问 https://openresty.com.cn/cn/xray/ 简单了解一下。

这个页面的最下面,“信任与合规”区块是一些标准化组织的认证,按照需求应该放几个 logo。然后我就很自然的用 display: flex 来做了。在桌面浏览器显示正常。

但是在 iPhone Safari 上,上面的两个图标会变得瘦长,看起来是高度计算有问题。我尝试修复这个问题,却除了写明高度,只有 height: intrinsic 可以让它显示正常。去 MDN 一搜,竟然没有这个属性?!只提到 max-contentmin-content 两种“intrinsic”的属性。

caniuse 上,可以看到 intrinsic 是个非标准化的属性,应该是以前浏览器自发实现过,后来被 max-contentmin-content 取代。但是为何 Safari 明明支持这几个属性,但是只有 height: intrinsic 能显示正常,我就不知道了,也没有查到。

先记一下吧,将来再看。如果有同学遇到类似的,图片在 display:flex 横排时尺寸出现问题,可以试试这个。

分类
html

使用 <input type=”file”> 上传 ZIP/RAR 文件

上传文件要用到 <input type="file">,这个元素有个 accept 属性,可以用来筛选文件类型,方便用户选择。按照 MDN 的说法,这个属性的值支持以下几种形式:

  1. 合法的文件扩展名,大小写不敏感,以 . 作为开头,比如 .jpg.pdf
  2. 合法的 MIME type,不需要扩展名
  3. 媒体文件,audio/* 适配任意声音文件,video/* 适配任意视频,image/* 适配任意图片

同时,属性值可以使用 , 连接,表示“或”的意思。注意,这里只能是单独的 ,,不能有空格,不然有空格的部分会失效。所以,比如,一个上传图片、以及 PDF 的元素就可以写成:

<input type="file" accept="image/*,.pdf">

使用扩展名比较方便,但是扩展名太多不方便管理,比如 .jpg.jpeg,容易漏掉,所以我更喜欢 MIME type。那么压缩文件的 MIME type 是什么呢?经过一番搜索和尝试,是:.zip,.rar,application/x-rar-compressed,application/zip,application/x-zip-compressed,application/octet-stream

分类
js 技术

基于 @vue/cli 的项目配置 browserslist

前些日子虽然写了 最近折腾 @babel/preset-env 的一些小心得,但其实没有正确的理解和配置 browserslist,所以今天问题又来了。

分类
js

Nuxt.js 支持 core-js 3

Vue CLI 升级到 v4 之后,将内部的 core-js 依赖升级到 v3,关于 core-js v3 和 core-js v2 之间的区别,我在 最近折腾 @babel/preset-env 的一些小心得 里简单介绍过。

升级完 Vue CLI 之后,在调用 nuxt generate 生成静态页,就会报错,因为 Nuxt.js 默认使用 core-js 2。这个时候,如果 Nuxt.js 版本在 2.6.0 之后,就只需要修改 nuxt.config.js 里的配置,指定 core-js 的版本:

module.exports = {
  build: {
    babel: {
      presets({ isServer }) {
        return [
          [
            require.resolve('@nuxt/babel-preset-app'),
            // require.resolve('@nuxt/babel-preset-app-edge'), // For nuxt-edge users
            {
              buildTarget: isServer ? 'server' : 'client',
              corejs: { version: 3 }
            }
          ]
        ]
      }
    }
  }
}

参考文档:https://nuxtjs.org/guide/release-notes#v2.6.0

说起来 Nuxt.js,用它发布静态页比想象中复杂,如果你想快速掌握这个技能,不妨看下我的这本小书:

分类
js

解决 Firefox 下的 race 问题

我厂有几个产品,需要从后端获取大量的信息,为了让用户能够近乎实时的看到这些信息,大部分数据都是通过 WebSocket 发给前端。这些产品在 Chrome 下表现正常,但是在 Firefox 下经常把数据格式搞乱,最终渲染失败。

因为 Firefox DevTools 没法解析 WebSocket 数据,而且市场占有率比较低,所以我一直没有解决这个问题。前几天终于把最小可复现实例搞出来,正准备研究,结果同事已经修好了。

预览版的 Firefox 终于可以在 DevTools 里查看 WebSocket 每一帧的数据,所以她尝试看了一下,发现从解析二进制数据的角度来看,Firefox 应该没问题。于是又回到代码,发现了一个可能产生 race 的点:

if (data instanceof Blob) {
  data = await new Response(data).arrayBuffer();
}

因为服务器返回的数据是二进制,所以我需要进行一次转换,把它变成 ArrayBuffer,然后再通过 TextDecoder 转换成文本,然后处理。Response.arrayBuffer 返回的是 Promise,所以我就很自然的用 await,并且在 Chrome 上运行良好。

但是在 Firefox 里,某些帧会后发先完成转换,a b c 变成 a c b,于是数据格式错乱,无法正常解析。我怀疑 Chrome 并没有真的把这一步保留到用户,而是同时存了两份数据,这样转换的时候直接给出数据就好,所以是微任务,不走 Event loop,不会产生 race。而 Firefox 则是实时转换,所以是宏任务,所以出问题。

我尝试去翻了一下源码,无奈平时没看过,所以没能找到证据。如果有哪位同学刚好知道,可以在评论里告诉我。