MDH 前端周刊第 42 期:手写 Babel、手写文本编辑器、阅读 ES 规范

399次阅读  |  发布于2年以前

封面图:good_citizen @ unsplash。

本期主要内容有这些:

手写 Babel 之 Tokenizer

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,前者在屏幕刷新时调用,后者在浏览器空闲时调用

如何阅读 ES 规范

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 的可信来源,各浏览器厂商和客户端均是基于此实现。

React component as Props

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% 的问题。你喜欢哪种?

gti

https://r-wos.org/hacks/gti

给你的 git 命令加个 ASCII 动画的 Loading 效果。

pnpm + monorepo

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