全部版块 我的主页
论坛 数据科学与人工智能 IT基础 JAVA语言开发
396 0
2022-11-10
人人都能学会数据分析五千仞岳上摩天
当你有技术深度的时候,你很可能同时也有技术广度。
第一次学习经历
当我第一次开始写一些研究Babel插件的技术文章时,我就是从那里开始的:
Babel是JS的编译器,把高语法的代码转换成低语法的代码,会自动引入polyfill。
它分为三个步骤,解析、转换和生成:

在解析阶段,代码从字符串转换为AST。在转换阶段,AST被添加、删除和修改。在生成阶段,将转换后的AST打印到目标代码中,并生成sourcemap。
的所有转换都是AST的转换,也就是说,它们在转换阶段生效。Babel把这些AST转换逻辑整理成了插件,插件很多,用起来比较麻烦,所以也提供了preset,是插件的集合。
这样我们只需要使用preset-xx,不需要关心具体的插件。比如常用的@babel/preset-env,只要指定了targets运行环境,对应的插件就会自动引入preset-env做AST转换。
本质上,巴别塔的核心功能是改造AST。我们也可以编写插件来完成这种转换。
当然,除了代码转换,还可以做静态分析,也就是通过分析AST发现一些问题,在编译时报错。
说到静态分析,ESLint和TypeScript编译器自然会出现在脑海中。他们不是也在做JS的静态分析吗?在代码中也发现了一些问题,并在编译过程中报告了错误。然而,ESLint发现了一些逻辑错误或格式错误,而TSC发现了一些类型错误。
两者都是基于AST的,那么Babel能实现ESLint和TSC的功能吗?
当时我尝试用Babel插件实现Lint的功能:
我发现ESLint里面的逻辑错误很容易实现,因为都是AST的分析。
例如,For迭代方向的误差取决于条件是<或>以及对应的条件是++还是-,这可以基于AST很容易地分析出来:

但是格式不对就没办法了,因为Babel插件中无法获取与这个AST相关联的令牌信息。
我去看看ESLint插件是怎么检测到格式错误的:
发现ESLint提供api根据AST节点获取其token信息,比如block语句可以获取{,即所在行号的token信息等。:

您还可以获取{ }的前一个令牌(即,)的令牌信息,包括行号:

那么这两个行号对比的时候,不知道是不是在同一排,中间有空格吗?也知道是否有格式问题。
ESLint插件可以检查这种格式错误,但是Babel插件不能。
是因为AST不包含这部分信息吗?
其实不是的。@babel/parser也支持用token生成AST,但是没有为插件提供相应的api:

如果Babel插件提供查询AST节点token的api,完全可以替代ESLint插件的功能。
然后我注意到ESLint插件提供了fix功能,可以自动修复一些错误。很好奇是怎么实现的。递归打印AST也像巴别塔吗?
研究了一下,发现不是。
ESLint插件可以指定在报告错误时用另一段文本替换某个范围的文本:

原理是字符串替换:

所以,Babel插件和ESLint插件之间至少有两个区别:

ESLint插件可以通过api获取与AST关联的令牌信息,并检查格式问题,而Babel插件不能。
ESLint的自动修复修改代码是通过字符串替换实现的,而Babel是通过递归将修改后的AST打印为字符串。

ESLint的静态分析清楚了,我又在想:TSC的类型检查不也是AST的静态分析吗?用巴别塔外挂能实现吗?
我真的实现了一个简单版本的类型检查,也支持泛型和简单类型编程:

但是我发现有很多功能是无法实现的。例如,TypeScript可以跨文件合并命名空间。例如,TypeScript可以跨文件声明全局类型。
Babel的编译是针对单个文件的,即一个文件经过解析、转换、生成,下一个文件经过解析、转换、生成。
TSC将根据配置加载lib和types下的类型,然后根据inclues、EXCLUSIONS和files的配置加载项目代码中的类型。这样就要把大局放在整体上,把合并做好,把最后的把关做好。
这种编译过程的差异导致Babel可以编译TS代码,但无法实现类型检查。它在处理TS代码时会忽略类型语法。
当然,不仅仅是巴别塔。用swc,esbuild等也是一样的。
如果要做类型检查,只能单独运行tsc - noEmit。没有第二种选择。
知道了Babel,ESLint,TSC的区别,就知道为什么Babel是基于AST的,却不能取代二者。
然后就是代码转换,这是巴别塔的强项。但是我们不仅用Babel转换代码,还用terser压缩一次(es6之前的代码很丑,然后Terser)。
为什么Babel在编译过程中明明可以实现这个压缩功能,却需要Terser单独压缩?
其实有可能。巴贝尔一直在推进这个,但是还没完成。这个babel/minify项目仍处于测试阶段:

它的原理很容易想到,就是一系列分析转换代码的巴别塔插件:

之前的编译工具都是处理JS的。后来发现postcss是css版本的babel,配置方法也是一样的。
Lint,也就是stylelint工具,也可以基于postcss实现,也可以实现压缩。
而且,给css类添加hash的css模块或者作用域CSS都是用它实现的。
然后我发现所有的前端编译工具都是解析、转换、生成三个阶段,都是基于AST进行分析转换。
这也很好理解,因为源代码和目标代码都是字符串,中间的处理是AST,自然是这样一个过程。
Vue template Compiler也是如此,只不过它是一个模板到渲染的函数,并且还支持转换插件。
编译后自然会涉及到打包工具,因为我们一般不会直接使用编译工具,而是声明对什么文件编译什么,让打包工具调用这些编译器,把生成的代码做成几个组块。
打包工具做的就是根据AST分析依赖图,然后调用不同的编译器对依赖图中的每个节点进行编译。之后,它被分成几个部分,并且包装一层UMD代码以生成最终的代码。当然,也可以注入一些运行时代码。
要学习打包工具,你只需要知道块分割和它的运行时代码做了什么。编译和包装是两个维度。
最近工具链有统一的趋势,比如bun,rome,esbuild等等。他们中的一些人希望将编译、Lint、压缩、打包等统一到一个工具中。原则上这是可行的,但是成本比较高,不然babel minify现在也不会还是beta。
说到这里,我们再来回顾一下:
其实我在研究Babel的时候发现,它的静态分析是基于AST的,就像ESLint和TSC一样,它的代码转换和Terser重叠。然后发现postcss也差不多,于是发现前端编译工具原理都差不多,完全可以统一。况且编译和包装是二维的东西。
当我深入研究巴别塔的时候,为了了解巴别塔和一些相关技术的区别,我研究了其他技术,最后我了解了巴别塔和其他很多工具的原理。
这就是为什么我的标题说有了技术深度,也会有技术广度。
第二次学习经历
再比如我最近在研究的调试:
我们通常使用Chrome DevTools进行调试,它可以调试网页,也可以调试Node.js为什么?
因为Chrome DevTools是基于CDP(Chrome Devtools协议)和JS运行时通信的:

Node.js调试之前都是命令行,没有UI,所以对接了CDP,这样就可以直接用Chrome DevTools的UI调试了。

只要CDP对接了,就不用用Chrome DevTools调试了,完全可以用VSCode调试器。
只有VSCode调试器有一个附加的适配器协议层:

这个多层协议是VSCode,目的是使调试器UI可以跨语言重用。
后来发现很多小程序调试工具和跨端引擎调试工具也是用Chrome DevTools调试的。其实他们也是和CDP对接的,这样他们的代码就可以用Chrome DevTools调试了。
调试工具分为后端和前端,UI部分是前端,代码运行时是后端。
我尝试了集成Chrome DevTools前端,自己实现后端的CDP服务。这是可能的。这就是跨端引擎调试工具的原理。
前端部分也可以基于JS运行时后端对接CDP实现。
在这个过程中,我了解到木偶戏是基于CDP实现的,也就是说它在调试模式下运行一个Chromium,然后连接CDP进行远程控制。
基于CDP实现这个并不难,所以我自己写了一个简单版的木偶师。
不仅是木偶师,灯塔的cli也可以获取网页的运行数据并做一些记录和分析,而且也是基于CDP实现的。有网页分析需求的时候,也可以基于CDP自己做。
这是我学习调试的经验:发现网页和Node.js都可以用Chrome DevTools和VSCode调试器调试,了解到它们的原理都是基于CDP的,小程序调试工具、跨端引擎调试工具等等都可以用Chrome DevTools调试,因为有CDP的对接。我尝试自己实现CDP后端和前端,然后了解到Puppetteer和LightHouse CLI也是基于CDP实现的,于是实现了一个简单版本的Puppetteer。
在学习网页和节点调试的同时,还学习了跨端引擎、小程序调试工具、木偶师的原理。
这个案例也可以说明,会有技术广度,也会有技术深度。
摘要
表面上看,很多技术都是不相关的,但深入下去,你会发现它们之间有着千丝万缕的联系。在深入研究一项技术的同时,你也可以掌握其他技术的原理,你会比单独研究那项技术理解得更深刻。
当你有了技术深度,你可能同时也有了技术广度。这两者并不冲突。
人人都能学会数据分析
download:链接:https://pan.baidu.com/s/10-csVKweSdcpouXNeBJB1g?pwd=ugz3
提取码:ugz3
--来自百度网盘超级会员V5的分享

二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

栏目导航
热门文章
推荐文章

说点什么

分享

扫码加好友,拉您进群
各岗位、行业、专业交流群