封面图:good_citizen @ unsplash。
本期主要内容有这些:
https://www.nan.fyi/tokenizer
编译器的步骤是 Tokenizer、Parser、Transform 和 Generate,上一步的结果是下一步的输入,源码进,修改后的代码出。这篇只介绍第一部分:Tokenizer。
Tokenizer 是把代码转化为一系列机器友好的记号,变成更结构化的数据格式,见下图,把源码转化为区分 keyword、identifier、string 等的 token。
token 包含单字符 token(比如点、括号、大括号、分号等)、identifier、关键词(function、const 等)、字符串等。实现的方式是逐个字符循环判断,实现详见 156 行的 TypeScript 代码,https://github.com/narendrasss/compiler/blob/main/src/tokenizer.ts 。
除了 tokenizier,作者仓库里其实实现了全套,想深入的可以直接看源码。
https://www.smashingmagazine.com/2022/02/develop-text-editor-web/
基于 Textarea 的文本编辑器,摘要如下,
1、input 和 textarea 虽然能处理输入,但不支持富文本。要开启富文本编辑有两种方式,1)设置 contenteditable,2)嵌入 iframe,然后设置 document.designMode = on
2、除了基础的字体、样式、颜色、修饰外,我们还可以通过 font-feature-settings 修改 OpenType 字体特性,通过 font-variation-settings 修改字体变量
3、可以为隐藏字符比如回车、不间断空格添加样式,通过 span:before + 图片的形式
4、⌘/Ctrl + V 会复制带样式的文本,⌘/Ctrl + ⇧ + V 会复制纯文本,也可在 paste 事件里通过 e.clipboardData.getData('text/plain')
和 e.clipboardData.getData('text/html')
拿到不同格式的文本
5、文本选择和聚焦。文本编辑通常会有工具栏,我们选中工具栏之后,会让文本操作区失去焦点和文本选择。如何让一个页面有多个选择和焦点?作者给了个方案是用 iframe 把文本框包起来,见上图
6、文本编辑要注意性能,可通过检测 FPS 拿到,思路是综合使用 requestAnimationFrame 和 requestIdleCallback API,前者在屏幕刷新时调用,后者在浏览器空闲时调用
https://timothygu.me/es-howto/
为什么要读 ES 规范?
> Array.prototype.push(42)
1
> Array.prototype
[ 42 ]
> Array.isArray(Array.prototype)
true
> Set.prototype.add(42)
TypeError: Method Set.prototype.add called on incompatible receiver #<Set>
at Set.add (<anonymous>)
> Set.prototype
Set {}
假如你在试 ES 语法,但遇到问题,怎么办?虽然 google 能解部分问题,但要追根究底,还得看 ES 规范。ES 规范是 JavaScript 的可信来源,各浏览器厂商和客户端均是基于此实现。
https://www.developerway.com/posts/react-component-as-prop-the-right-way
React 中,做一件事通常都有很多方法,把组件作为 props 往下传也不例外,通常有三种方式:
1、传 Element,比如 <Button icon={<Icon />} />
2、传 Component,比如 <Button Icon={Icon} />
3、传 Function,比如 <Button renderIcon={() => <Icon />} />
作者比较了 3 种方式,但没能给出推荐,因为每种方式都能解 99% 的问题。你喜欢哪种?
https://r-wos.org/hacks/gti
给你的 git 命令加个 ASCII 动画的 Loading 效果。
https://egoist.sh/pnpm-monorepo
作者给了用 pnpm 管理 monorepo 一些有用的 Tips,其中提到 pnpm 的 --filter 参数,我深入看了下,非常强大,以下是摘要,
1、--filter foo 用于精确匹配一个包,可以用 *
2、--filter foo... 用于匹配 foo 及其依赖包,并且依赖包先执行
3、--filter foo^... 用于匹配 foo 的所有依赖包
4、--filter ...^foo 用于匹配所有依赖 foo 的包
5、--filter ./foo 用于匹配所有 foo 目录下的包
6、--filter {foo} 同上,但可和 ... 结合选择依赖和被依赖,也可和 [] 结合选择改动过的包,比如 --filter {packages}[origin/master]...
7、--filter "...[origin/master]" 用于匹配相比于某个 Commit 或分支有过改动的包
以下是上周社区的重要发布。
Copyright© 2013-2020
All Rights Reserved 京ICP备2023019179号-8