Reading
tech
2022

2022

2022.02.07 18:25:29

sass 编译器的历史 (opens in a new tab)

从 ruby-sass,node

React hooks (opens in a new tab)

作者:“红脸太常见,也来唱个黑脸,本文将站在一个「挑刺儿」的视角,聊聊我眼中的 React Hooks ~”

React hooks 在设计上的一些问题和缺陷,挺好的文章,对 hooks 的理解又多了

JS undefined & null (opens in a new tab)

讲述了 undefined 和 null 在 js 中的不同表现:

以及提到了底层 typeof null 为什么是 object

对于所有的对象,它的前 3位 都以 000 作为类型标记位。在 JavaScript 早期版本中, null 被认为是一个特殊的值,用来对应 C 中的 空指针 。但 JavaScript 中没有 C 中的指针,所以 null 意味着什么都没有或者 void 并以 全0(32个) 表示。因此每当 JavaScript 读取 null 时,它前端的 3位 将它视为 对象类型 ,这也是为什么 typeof null 返回 'object' 的原因。

btw 中间的排版有点错乱。。

一个 DNS 解析器 toy (opens in a new tab)

据说作者很牛

文章通过漫画讲述了 DNS 解析的过程,挺生动易懂的

对 DNS 查询的输入和返回进行了剖析

然后通过简短的 go 代码将整个 resolve 方法描述了(简化版)挺有意思

【好文】intro of Worker Threads in Nodejs (opens in a new tab)

这篇文章主要介绍了 Nodejs 应用在处理 CPU-bound task(CPU 计算密集型任务)中可以使用的提升性能的工具/方法

基于 Nodejs 自身的运行机制(event loop,异步非阻塞 IO),对于 CPU 计算型任务会阻塞 eventloop,导致处理并发请求的吞吐量降低,文章介绍了几种方法(结合简单代码 example):

  • Splitting up tasks with setImmediate() (single-threaded)
    • 相当于是将一个完整任务拆成很多片段,让他们在 event loop 的间隙里执行
  • Spawning a child process
  • Using worker threads(文章重点,但不一定是最好方法,还是根据实际情况看)
    • 在另一个独立的 js context(V8 eventloop)中执行(不会阻塞主线程的 eventloop)
    • 比 child process 更好的点
      • 更加轻量
      • 可以共享数据
    • 不用考虑线程间同步问题(除了 SharedArrayBuffer),可以减少 bug
    • 使用 worker pool(有开源现成的 npm 包 workerpool (opens in a new tab))减少每次创建 worker 的开销
    • ArrayBuffer 和 SharedArrayBuffer

最后文章的 summary 部分也写的非常好,一切软件都是 trade-off,There is no silver bullet

Successful software projects make trade-offs that enable them to excel at their core use case, while (hopefully) leaving some room for flexibility.

JS Array 的 search 函数通用化 (opens in a new tab)

挺有意思的编程思路,将 filter find 之类的 search 方法抽离出来,通过 this 来得到实现通用化

  • filter 之类的函数接受第二个参数就是一个对象 thisValue 是给 predicator 的上下文,相当于是 fn.bind(obj)
  • 方便单元测试

直接看他的一个普适性的例子代码,挺有意思

function matches(item) {
  const expected = item[this.value];
  const actual = item[this.property];
  switch (this.comparator) {
    case "===":
      return actual === expected;
    case ">":
      return actual > expected;
    case "<":
      return actual < expected;
    case "includes":
      return actual.includes(expected);
    case "after":
      return new Date(actual) > expected;
  }
}
 
function compare(property, comparator, value) {
  return { property, comparator, value };
}
 
items.filter(matches, compare("id", ">", 40));
 
// borrowing from the previous example:
blogPosts.filter(matches, compare("tags", "includes", "b"));
blogPosts.filter(
  matches,
  compare("published", "after", new Date(2020, 12, 15))
);

不过唯一的不足是,绑定 this 对于性能上来说,会差一些

TODO js 中真正的 sleep (opens in a new tab)

如何让 js 的线程真正的 sleep,最 naive 的想法就是用 while 循环,但是对于 cpu 的占用率是非常高的

文中介绍了几种更高效的 tricky 的方法

都是比较骚的实现,还不能完全理解,日后实践

【好文】我做系统架构的一些原则 (opens in a new tab)

coolshell 的深度好文,讲架构的一些好的原则,值得反复阅读和品味

why svelte (opens in a new tab)

大佬对 svelte 的一些看法,自己虽然也只是看了文档还没有实操,对 svelte 还是有很大的兴趣,从文档中能看到

  • mutability in svelte
  • 作者对 svelte 和 react 之间的看法,以及框架的理解/看法
  • svelte 存在的一些问题,作者自己选择框架的方式 For now, my approach is ”Svelte for sites, React for apps“.

git commit template (opens in a new tab)为何/如何写好 commit (opens in a new tab)

git commit 的模版,可以让我们更方便的写完更好的 commit 信息,有机会 try try

A diff will tell you what changed, but only the commit message can properly tell you why.

浏览器被 fingerprint (opens in a new tab)

概念/定义 什么是 fingerprint?

  • 对某一个东西的唯一标识(比如身份证、指纹信息

浏览器的 fingerprint 就是浏览网站的人的唯一标识,这个标识当然是存在服务端数据库里面的

文章介绍了禁用 js 之后仍然可以通过一系列的浏览器信息获取,通过这些信息生成对应浏览器的指纹(hash)

  • ip
  • http request header/UA/Client Hints/...
  • 浏览器 CSS 引擎的各种 feature(有没有开启
  • 字体信息
  • ...

脑洞十足呀,附上 github (opens in a new tab)

开发团队的效率 (opens in a new tab)

团队开发的各种毛病!和现实十分贴切!

H.264 (opens in a new tab)

H.264 视频编码到底是什么(有损的视频压缩编码),文章比较生动和细致的讲了 H.264(虽然还不知道该怎么读他)所用到的压缩方法:

  • 2D 空间上:
    • entropy encoder:信息熵不变,但是他的 representation 变了
    • frequency domain quantization:频域压缩,图像处理很常用,去除低频(变化不那么大的元素),前提是其实是基于人们对于颜色变化其实不敏感
    • Chroma Subsampling:颜色变化细节不敏感,去除图片区块的部分像素
  • 时序上:
    • Motion compensation
      1. split to macro blocks
      2. one static image I-frame,others are P-frame(predicted) or B-frame(bi-directionaly predicted)
      3. use motion vectors to define P or B-frames
      4. at cost of calculations
      5. Entropy Coder to reduce the redundancy of I-frames

weapenisation of open source (opens in a new tab)

now: 2022.04.05 20:28:28

前不久俄罗斯向乌克兰发起了战争,在开源社区也有一些行为在做抵制俄罗斯的行为,但他们的影响面导致了一些公司依赖的软件遭到连带(collateral damage)

utopia (opens in a new tab)

非常牛的一个产品,react code with design,代码开发 + 设计软件双向同步,代码编辑器采用 vscode,设计的编辑器也非常牛啊。

2022.05.03 11:17:28

RPC from scratch (opens in a new tab)

文章介绍了 RPC 的概念,并用一个 toy example 解释

烟蒂 stub 模型,RPC 是一个比较抽象的设计模式(?)封装了 client 和 server 之间的通信方式(协议、接受参数、打包/解包数据、返回)

最后介绍一个正真的 RPC 框架需要满足的能力:

  • Discoverability:在网络中可被发现性,服务是否在线等
  • RPC type:辨别不同类型的 RPC 服务
  • Packing:打包/解包不同数据结构的数据,传输协议、压缩、节省带宽
  • Generating code automatically:只需要定义 interface,不用每次写很多重复代码
  • Multiple languages:cross-service and cross-language communication
  • Error & timeout handling:失败和超时的处理、通信
  • Versioning:版本控制
  • All of the other caveats that go along with running servers: threading, blocking, multiplexing, security, encryption, authorization… 以及其他一些运行时服务一样会遇到的问题,都需要得到很好的解决

Thunk 是什么 (opens in a new tab)

这篇文章真正解答了我用 redux 以来这么久对于 thunk 的疑惑

thunk 这个单词本身含义就是一个能返回函数的函数(常用的 wrapper 方法)

redux-thunk 的作用和意义就是在于能在一个 redux action 中去执行其他的 action,增加 action 的灵活性,把 action 的形态拓展成函数。

P.S. 对于 redux action 来说就是一个 pure object 包含了 type

redux-thunk 的实现其实也是运用了 redux 的 middleware,判断一个 action 是否是 function,如果是就执行他,如果不是就正常的走 next 方法

补充:来自 redux-thunk 源码

A thunk (opens in a new tab) is a function that wraps an expression to delay its evaluation.

维基百科:Thunks are primarily used to delay a calculation until its result is needed, or to insert operations at the beginning or end of the other subroutine.

所以 thunk action 他一定是一个函数(区别于 pure object 的 action)

And 看了源码,短短 50 行,很厉害,单测也很完备!不愧是 Dan。

Youtube State of CSS (opens in a new tab)

介绍了 2022 年的一些新 css 特性,很强大。

浅浅了解一下 Web3 开发 (opens in a new tab)

Web3 创业的大佬(郭宇,貌似就是之前在字节自由的人),介绍了 Web3 开发的基本全部的部分吧。

macos 系统界面里的 webview (opens in a new tab)

命令行中输入 defaults write NSGlobalDomain WebKitDeveloperExtras -bool true defaults write -g WebKitDeveloperExtras -bool YES 可以在一些界面通过右键审查元素,但是目前只发现在设置中家人共享可以,还挺有意思的,能看到很多源码,比如 html 就是用 react 写的,有一个自定义 hook,

import { useState, useEffect } from "react";
 
// This hook will set a flag once the requested image is loaded. This should help with large images not being downloaded fast enough.
const usePreloadedImage = (imageUrl: string): boolean => {
  const [isImagePreloaded, setIsImagePreloaded] = useState(false);
 
  useEffect(() => {
    const preload = new Image();
    preload.src = imageUrl;
    preload.onload = () => {
      setIsImagePreloaded(true);
    };
  }, []);
 
  return isImagePreloaded;
};
 
export default usePreloadedImage;

可以检查素数的正则 (opens in a new tab)

这篇文章挺久远的,07 年的 先看下最终的这个正则:/^1?$|^(11+?)\1+$/ 这个正则有两个部分

  1. 检查是否是 0 or 1
  2. 用 11 开始匹配,\1 是指前一个部分匹配到的变量,先用 11+ 匹配有多少个,然后在看是不是以这个的倍数结尾的

挺有意思的,但是呢,需要将数字 n 转换成 '1'.repeat(n),然后在进行 test

这个步骤的分析其实文章里也写的很清楚,其实主要是转换成了 n 个 1 的字符串,在第二部分的正则中会去开始从最小的素数 2(两个 1 11)来猜这个数是否是它的倍数(\1+$ 倍数结尾),如果不满足,正则引擎会继续走 11+,用 3 开始猜,以此类推。

不得不说用正则来做这个计算还是很骚的,但是问题就在于对于大数的匹配有性能和内存的问题。。

favicon 的分析 (opens in a new tab)

爬取了 100k 个网站,下载了 425,909 个 favcion(favorites icon)

如何获取 favicon 的:link(icon、apple-touch-icon),/favicon.ico,/apple-touch-icon.png,icons from link rel=“manifest” JSON

逐步分析了 icon 的大小/下载速度、文件类型、主导色(紫色、白色、橙色、蓝色、黑色、...)

爬虫方法、分析方法

mac 个性化菜单栏 (opens in a new tab)

Github (opens in a new tab) 挺不错的,但是有点难搞,装了好久,原生的菜单栏突然去掉还挺尴尬的。

VSCode CodeTour (opens in a new tab)

还不错的一个插件!可以 tell the story of the code,适合给别人介绍如何阅读代码,要是每个开源仓库都能配这个就好了哈哈

VSCode dev (opens in a new tab)

支持 web 版的编辑器了!

  • 浏览器可以访问/修改本地文件,chrome 支持的 api!

  • 当然对于一些场景的体验会差一些

    • 插件
    • 语言的 language server

Product-first or Code-first (opens in a new tab)

两类程序员:1)code-first 专注代码写的是否优雅、是否用了最新的技术、架构设计、...2)product-first 聚焦的目标是最终产品是不是 work well。

这里的 product 泛指一切代码的产出,api、sdk、页面、产品、...

一个好的产品意味着好的代码,不好的产品意味着不好的代码,可以去问这么两个问题:

  1. 产品是否 work well
  2. 产品是否能 produce quickly

Programming is about building products that solve problems for users not about writing beautiful code for its own sake.

还是挺有收获的,也能在生边看到这两类程序员,自我评估是两者兼备吧,一切都是 tradeoff,需要不断的做好这两者的平衡。

protocols not platforms (opens in a new tab)

twitter 的 CEO 都收到鼓舞的文章,很长,论述了当前社交网络从大平台掌控到基于协议的系统/服务,的一些好处:free speech and innovation

大致内容:protocol 和 platform 能做的,现在大的 platform 存在的问题,protocol 的优势/劣势,怎么做,结论

http 连接池 (opens in a new tab)

浅了解一下,顺便复习一下网络知识

解决的目标:

  • QPS 暴增的时候,解决每次 http 建立连接的开销,降低并发请求的总耗时

长/短链接:

  • http1.1 开始默认长连接,能在一个 TCP 连接上传递多个 HTTP 请求

长连接

  • 客户端发送一个 Connection: keep-alive 的 header,表示需要保持连接
  • 客户端可以顺带 Keep-Alive: timeout=5,max=100 这个 header 给服务端,表示 tcp 连接最多保持 5 秒,长连接接受 100 次请求就断开,不过浏览器看了一些请求貌似没看到带这个参数的
  • 服务端必须能识别 Connection: keep-alive 这个 header,并且通过 Response Header 带同样的 Connection: keep-alive,告诉客户端我可以保持连接
  • 客户端和服务端之间通过保持的通道收发数据
  • 最后一次请求数据,客户端带 Connection:close 这个 header,表示连接关闭

记录:

  • http 的 keep-alive 是为了复用已有连接
  • tcp 的 keep-alive 是为了保活,即保证对端还存活,不然对端已经不在了我这边还占着和对端的这个连接,浪费服务器资源,做法是隔一段时间发送一个心跳包到对端服务器,一旦长时间没有接收到应答,就主动关闭连接

TSL 层的优化:每次 HTTPs 的连接都会进行 tsl 的握手,文中提到两种优化思路(都是缓存/解析)

连接池个数的设置,不太好控,有没有什么自适应的方法呢?

reduce 来按序 resolve promise (opens in a new tab)

reduce => Take a collection of things, and reduce them to a single value

其思路就是将多个 promise 按顺序挂到一个 promise 的 then 上

js framework 的时代 (opens in a new tab)

粗读了一下,有空再看一遍。

前端框架的演进,未来又会是怎么样的呢。

【好文】程序员的喵 weekly18 (opens in a new tab)

这期的周刊不错,收藏下(2022/7/2)

  1. 程序员的软技能:mark,是个需要不断学习的东西。“写代码只是个门槛,本质上来说在公司工作,是和同事一起帮公司解决问题,所以沟通和协作特别重要。特别是要从广度上增加自己的影响力,沟通力起决定性作用。”
    1. 软技能演讲 ppt(slidev) (opens in a new tab)
  2. “人一生的三次死亡”。程序员写的代码可能还在世界上的某处运行着,这样也许就不会被世界遗忘吧。

2022.07.14 12:46:47

重新构想 atomic css (opens in a new tab)

依旧是 antfu 大佬的文章(原文 (opens in a new tab)) 以及他的作品 unocss (opens in a new tab)

文章也是剖析了当下(写于 21 年 10 月)atomic css 方案的一些问题:(tailwind 为主)

  • 无用的 css 过多,生成器的流程需要变革
  • 不够定制化,维护成本
  • ...

介绍了 windicss,先扫描再生成

最后介绍他自己的 unocss,完全可以自定义的、高灵活度的 css 生成引擎

很是牛逼。

Pure CSS Icon (opens in a new tab)

依旧是 antfu 的

纯 CSS 图标

  • 使用 DataURI
  • 可缩放(scalable),用了 em 单位
  • Colorable,纯色图标用 mask 和 background-color: currentColor

使用:unocss 的 preset

以及 egoist 他是怎么用 (opens in a new tab)的(updated on 2023.03.30 19:13:28 +0800)

hide a photo inside another (opens in a new tab)

文章介绍了一种在一张图片中藏另一张图片的 trick,能做水印、存储、....

一种密码学(steganography)

利用 LSB(Least significant bit),将图片以二维矩阵的结构(考虑单个 channel),每个元素用二进制表达,当我们修改最右的一位之后,新的图片和原图其实看不出什么差异

于是就能用每一个像素点的最后一个 bit 来存储需要 hide 的图片。所以 hidden photo 是有大小限制的:还得是个正方形,边长 = sqr(ori_H * ori_W / 8)

限制:对于有损压缩的图片格式(如 jpeg),在取图的时候可能就会损失惨重,噪音也会很大。

扩展:

  • 想象一下如果用两位最低 bit 取存,是不是能存更大的图片
  • 如果再加入一些 header 信息,比如 size 之类的 hidden photo 会更加丰富

Tilg (opens in a new tab)

源码阅读 useTilg

这是一个 react hooks,tiny logger to help you debug your components. 详细功能可以去 github (opens in a new tab)

主要提炼核心的几个点:

  1. 整体结构是在每次 render 中输出 log:
    1. 组件名,props,变更属性,自定义的 log 信息
  2. 在 React 环境如何获取到当前渲染组件的信息:
    1. 首先是组件名,非常骚,用了 React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED,但这么写在生产环境大概率是会报错的(uglify js),当然它 README 的最后 (opens in a new tab)也写了不要自己再用这种东西实现 hh
    2. 如何统计同一个组件多次 render,用了 WeakMap(见es6)存了一个数组 WeakMap<ComponentId, HookPath[]>,这里的 HookPath 就是每次调用 useTilg 的时候都会去看看是在哪里调用的,如果是不同的调用路径,就认为是同一个组件的另一个实例。BTW 为什么用 WeakMap,如果一个组件直接从 React 上下文去除掉了,也没必要继续存了(我猜的)
    3. 怎么获取调用 path?给我惊到了,通过对 new Error().stack 的处理,能拿到当前 call 的调用栈,里面包含了 caller 和代码 path,做了正则匹配提取。
    4. 在组建中多次 hook 调用只会执行第一次,用了一个闭包的 id 做的。
  3. MarkDown 的实现
    1. 不得不说为了支持 md,足足得多 200+行代码,真是煞费苦心。
    2. 支持了 node 和 webview 环境,详细的可以看代码。。

整个代码还是比较精炼好懂的(除了 markdown 的部分。。),确实如同作者说的非常 hacky。哈哈。

【open source】CONTRIBUTING.md 是什么 (opens in a new tab)

介绍了 CONTRIBUTING.md 存在的意义,以及如何写 CONTRIBUTING.md

atom 项目的例子 (opens in a new tab)

别在用 TODO 啦 (opens in a new tab)

用以下这些更有实际意义的词来替换 comment 中的 TODO

  • FIXME
  • HACK/OPTIMIZE
  • BUG
  • CHECKME/REVIEW
  • DOCME
  • TESTME

vscode 插件 TODO tree、TODO highlight

terser (opens in a new tab)

偶然打开这个库的 GitHub 看了下,才发现 uglify-es 已经不维护了 (opens in a new tab)

terser 也是现在主流使用的 js 压缩工具(es6+)

将 base64 字符串文件转成 js 文件对象可以作为 form 的 input (opens in a new tab)

来自 stackoverflow,直接贴牛逼的代码吧 hh

function dataURLtoFile(dataurl, filename) {
  var arr = dataurl.split(","),
    mime = arr[0].match(/:(.*?);/)[1],
    bstr = atob(arr[1]),
    n = bstr.length,
    u8arr = new Uint8Array(n);
 
  while (n--) {
    u8arr[n] = bstr.charCodeAt(n);
  }
 
  return new File([u8arr], filename, { type: mime });
}
 
//Usage example:
var file = dataURLtoFile(
  "data:text/plain;base64,aGVsbG8gd29ybGQ=",
  "hello.txt"
);
console.log(file);

Math and Front End (opens in a new tab)

数学在前端的作用~在 web 开发过程中不会注意到的数学知识

数值:

几何:

  • border-radius
    • 可以是 60px/30px 其实可以接受两个参数,第一个是 horizontal 的值,第二个是 vertical 的值,以这两个值画的椭圆,就是这个 radius 了,原来可以这样!
    • 同样,如果是给百分比数值,那他就分别是 width 和 height 的宽度,所以如果给 50%,就是完美的过渡圆角
  • 三角形:通常我们会用 border + transparent 去 hack 三角形,会需要计算高度

why not use prettier (opens in a new tab)

来自 antifu 自己的项目代码更会去选择 eslint 作为质量保证和 formatter 其他场景可以选择 prettier 安利了他自己的 eslint config 工具没有好坏之分,只是根据适用场景

10 years of TS (opens in a new tab)

typescript 的十年回顾 回顾加感谢的文章,读完能更加了解 ts 真正之于 js 的定位,很不错

16 进制颜色的透明度数值 (opens in a new tab)

很早就学到的东西,但一直没有记录,就顺便归档下

能够解决有透明度色彩的 hex 表达值,其实就是在 A 通道用 16 进制表达透明度百分比即可

直接看标准答案吧(转换百分比 -> 16 进制),然后 append 到字符串后面,记得补齐 2 位

const percentToHex = (p) => {
  const percent = Math.max(0, Math.min(100, p)); // bound percent from 0 to 100
  const intValue = Math.round((p / 100) * 255); // map percent to nearest integer (0 - 255)
  const hexValue = intValue.toString(16); // get hexadecimal representation
  return hexValue.padStart(2, "0").toUpperCase(); // format with leading 0 and upper case characters
};
 
console.log(percentToHex(0)); // 00
console.log(percentToHex(50)); // 80
console.log(percentToHex(80)); // CC
console.log(percentToHex(100)); // FF

当然,很多地方(ide)都支持各种方式的转换,比较方便

js container (opens in a new tab)

来自 deno 的文章,首先讲了大多数 server 的容器都是 Linux container 比如 docker,配置比较复杂,不高效,js 会将成为 universal scripting language 但这里指的是 browser 里的(node 设计的败笔就是加了很多非标准化的 api) deno deploy 已经在将 js 容器落地了,能够高效的提升业务逻辑效率 一些复杂的实现也可以用 wasm 来代替 js

flexible.js? (opens in a new tab)

Recap:

  • rem: font size of the root element,相对于根元素(即 html 元素)font-size 计算值的倍数。
  • 移动端屏幕尺寸适配:1)替换 px 单位为 rem,2)根据屏幕尺寸动态调整 html 元素的 font-size 属性

目前业界已经有很多种方案(flexible.js,scss 结合 media-query,...)

这篇文章提出用 vw 直接做动态调整

  1. 根据视觉稿宽度,750px == 100vw -> 1px = 0.133333vw -> 100px = 13.333333vw,所以设置 html 的 font-size 为 13.3333vw
  2. 1rem == 1 unit('font-size') == 100px,所以视觉稿的 n 需要转换成 n/100 rem
  3. 后者的单位转换可以用 postcss & pxToRem 来做
  4. html 的 font-size 可以通过配置 + 构建脚本来做

当然,也可以不用 100 倍的换算,直接 1rem -> 1px 来写,于是设置 font-size 为 0.13333vw

pdd 两年记 (opens in a new tab)

同事之前推的文章。又完整的读了之后,感慨很多,pdd 的公司文化还是很不错的,也学到了很多技术方案的思路,也感叹移动端的这些事情还是做 native 比较有意思呀哈哈哈 XD。

长期价值 & 平常心。

谷歌软件工程文化 (opens in a new tab)

也是正巧翻到自己 mac 的 books 里面有这本 'software engineering at Google'(全英版)最近好像很火的一本书,google 搜了一下发现 @madawei 也写过文章(SEO 做的真好)

也趁此机会准备开始抽空看一下这本。

figma 构建 web 上的专业设计软件 (opens in a new tab)

文章是 figma 的创始人写的,讲述了想把专业设计软件做在 web 上的这个过程中遇到的种种困难(emscripten(WebAssembly)、渲染(webGL)、浏览器所提供的功能不足),同时强调了 figma 最重视的两个要素:Performance and quality

2022-12

petite-vue (opens in a new tab)

在 vue conf 2022 上听到尤大说把 vue1 的设计重新实现了一份 petite-vue,发现 demo 上一段 script:

<script src="https://unpkg.com/petite-vue" defer init></script>
 
<!-- anywhere on the page -->
<div v-scope="{ count: 0 }">
  {{ count }}
  <button @click="count++">inc</button>
</div>

就是说 script 标签的 init 很不是理解,然后搜了一下在这个回答 (opens in a new tab)里才知道,原来是 petite-vue 自己识别了这个 attr,很骚。

lodash.get 类型推导 (opens in a new tab)

来自公司里的一位大神,帮 lodash 的 get 新增了类型,太厉害了!可以详细看下这个 PR

不用括号来调用函数 (opens in a new tab)

脑洞还是很大的,主要原理还是基于模版字符串的标签模版

function x() {
  console.log(arguments);
}
 
x`a${123}`;
// { '0': [ 'a', '' ], '1': 123 }

当一个函数被用作标签模版来调用之后,arguments(形参)是有一个规则的:

  1. 第一个参数是根据模版字符串生成的一个数组,规则是分割占位符${}的字符串组合,包括最后一个空字符串
  2. 后面的参数就是每个占位符了,可以无限放,他的值就是变量本身(注意了,什么都能放)

所以作者首先利用模版字符串可以喊(call)函数,干掉了括号 (),接着利用标签模版的调用规则,可以通过占位符放入各种想要的参数,但问题是第一个参数(分割字符串)通常是很多内置函数不需要的,所以得想办法 hack 跳过他。

于是用 call,因为第一个参数会绑定给 this,但是说不在 window 上?浏览器直接报错(Uncaught TypeError: Illegal invocation),但是 node 环境可以。

setTimeout.call`${console.log}${1000}${123}`;

所以再次 hack

[].sort.call`${alert}1337`;

文中还用到了 Reflect.apply

小程序的同层渲染 (opens in a new tab)

“解决了原生组件的层级问题,同时也让原生组件有了更丰富的展示和交互的能力”

小程序是基于 webview 定制的渲染方案,如果要在 webview 之上扩展一些定制能力,比如说 video、map 组件,客户端渲染的层级是在 webview 之上的,所以要解决这个问题,让 webview 能扩展丰富的组件

文章讲到了两个端分别实现“同层渲染”的方案,核心思路就是通过 webview 内核的一些机制,让自定义组件渲染在 webview 的同一层(详细看文章就好了)

2020 js13k 游戏 top10 (opens in a new tab)

JS13K 竞赛 (opens in a new tab):每年举办的,h5 游戏开发比赛,限制就是代码大小在 13kb 之内。

2020 年的主题是 404,其中我觉得最有意思的是 track not found (opens in a new tab),通过转变相机视角和 2D/3D,让火车轨道能够通行,很有意思。

husky (opens in a new tab)

用了很久的 husky,来看看他的文档吧

You can use it to lint your commit messages, run tests, lint code, etc... when you commit or push. Husky supports all Git hooks (opens in a new tab).

可以在各个 git 环节(hook)增加指令

数据大屏自适应方案 (opens in a new tab)

先上代码:

/*
	JS部分
*/
//数据大屏自适应函数
const handleScreenAuto = () => {
const designDraftWidth = 1920;//设计稿的宽度
const designDraftHeight = 960;//设计稿的高度
//根据屏幕的变化适配的比例
const scale = document.documentElement.clientWidth / document.documentElement.clientHeight < designDraftWidth / designDraftHeight ?
  (document.documentElement.clientWidth / designDraftWidth) :
(document.documentElement.clientHeight / designDraftHeight);
//缩放比例
(document.querySelector('#screen') as any).style.transform = `scale(${scale}) translate(-50%)`;
}
 
//React的生命周期 如果你是vue可以放到mountd或created中
useEffect(() => {
//初始化自适应  ----在刚显示的时候就开始适配一次
handleScreenAuto();
//绑定自适应函数   ---防止浏览器栏变化后不再适配
window.onresize = () => handleScreenAuto();
//退出大屏后自适应消失   ---这是react的组件销毁生命周期,如果你是vue则写在deleted中。最好在退出大屏的时候接触自适应
return () => window.onresize = null;
}, [])
 

不用 rem 的方案,纯靠 scale 来进行自适应,思路也比较简单:onresize 的时候通过计算宽高比和预设的设计稿宽高比进行比较,如果小于就选择宽作为缩放比例,大于就用高做缩放比,最后让容器 div #screen 进行 transform,这里为啥还要 translate(-50%) 呢,移动到中间?

% 和 px 随便用,好评,不用担心单位计算

主要存在两个问题

  1. 当缩放比例过大时候,字体会有一点点模糊,就一点点。
  2. 当缩放比例过大时候,事件热区会偏移。