当前位置: 首页 > news >正文

2024 基于 Rust 的 linter 工具速度很快

2024 年 Web 工具的一大趋势是使用 Rust 重写现有工具。Rust 是一种出色的编程语言,能生成运行速度惊人的二进制文件,且与其它 Web 工具的互操作性极佳,这得益于 WebAssembly 的帮助。swc 和 Turbopack 等工具的速度提升为快速开发体验带来了巨大变革。

Biome、deno lint、Oxc 和 RSLint 等项目都有一个用 Rust 编写的 JavaScript/TypeScript 代码检查器。对于那些对开发工具速度缓慢感到不满的开发人员来说,以Rust(本机代码)速度运行代码检查器,而非JavaScript(JIT脚本)速度,无疑是很有吸引力的。Prettier 甚至为 Biome 提供了 20,000 美元的奖金,以表彰其实现了与 Prettier 格式部分的 >95% 兼容性!

然而,基于 Rust 的 linters 是无法完全取代 ESLint 的。虽然性能优势明显,但也存在一个明显的缺陷:类型检查的 linting 功能缺失

回顾:类型检查的 Linting

传统上,像 ESLint 这样的 lint 工具一次只能检查一个源代码文件。这使得它们运行速度较快,理论上可以进行缓存和并行处理。

typescript-eslint 引入了使用类型信息的 linting 概念。通过调用 TypeScript 的类型检查 API,lint 规则可以根据项目中的其他文件提供的类型信息,对代码做出更加明智的决策。

类型检查的 lint 规则可能比传统的 lint 规则功能更强大。例如:

  • @typescript-eslint/await-thenable :禁止在非 Promise 值上使用不必要的 await 调用。

  • @typescript-eslint/no-floating-promises :可以提醒是否创建了一个 Promise 但忘记安全地处理它。

  • @typescript-eslint/no-for-in-array :用于标记对数组的不安全的 for...in 迭代(不是 for...of)。

这些规则只有在能够使用类型信息来确定何时报告问题时才有实际用处。没有类型信息,它们将无法理解从另一个模块导入的值的类型。

类型检查的 Linting 性能

类型检查的 linting 相比传统 linting 存在的主要劣势在于性能。这是因为类型化的 lint 规则需要调用 TypeScript 等 API 来获取类型信息,通常需要读取所有文件以确定哪些文件会影响其他文件的类型。因此,类型检查的 linting 性能通常会低于对整个项目运行 TypeScript 的性能。

TypeScript 本身也在不断优化性能。例如,项目引用可以显著帮助处理更大的项目。TypeScript 即将推出的独立声明模式看起来也可以显著提高处理更大项目的性能。

但即使所有这些加速都完美地工作,类型检查的 linting 设计上仍然比传统的 linting 慢几个数量级。因为从项目中推断类型的过程本质上比传统的 lint 规则一次只查看一个文件要慢得多。

大多数情况下,当看到类型检查的速度慢的项目时,根本原因要么是 typescript-eslint 配置错误,要么是 TypeScript 类型慢。

基于 Rust 的代码检查工具和类型检查

目前还没有基于 Rust 的代码检查器与 TypeScript 的类型检查 API 集成,这意味着基于 Rust 的代码检查器不能完全替代 ESLint + typescript-lint。

如果你不需要任何类型检查的 lint 规则,那么可以切换到基于 Rust 的 linter。但强烈建议你至少查看 typescript-lint 中推荐的类型检查规则,以了解缺少什么。

甚至可以同时运行这两种工具:首先使用原生速度的 linter 快速反馈,然后仅使用 typescript-eslint 查看包含类型信息的规则。这个想法得到了多个原生速度 linter 维护者的支持:

  • Biome 的 Emanuele 认为双重 linting 是一种合理的策略。

  • Oxc 的公告将 oxlint 描述为在 ESLint 过慢时的增强工具,而不是完全替代品。

这种互补而非取代的愿望部分源于这两种 lint 工具在运作方式上的重大结构性差异。原生速度的 lint 工具尚未在其 lint 规则中实现类型检查。下面来深入探讨这一奇怪的功能差距。

集成类型检查的 Linting 和基于 Rust 的 Linting

目前,TypeScript 的核心功能是为 TypeScript 编译器和语言服务提供支持的代码,它是唯一能够为 TypeScript 代码提供可靠类型检查的组件。由于TypeScript是用TypeScript编写的,因此其类型检查以JavaScript的速度运行。

为了实现与 TypeScript 的类型检查的集成,基于Rust的代码检查器面临几个选择:

  1. 承受性能损失,调用TypeScript的JavaScript速度类型检查API。

  2. 使用原生速度语言重新实现TypeScript的API。

  3. 将 TypeScript 的 API 提升到原生速度。

此外,基于 Rust 的 linter 不允许在 JavaScript 中编写自定义 lint 规则。虽然这对大多数 JavaScript 生态系统来说是一个贡献障碍,但这与本文的重点是两个独立的问题。

因此,将基于 Rust 的代码检查器与 TypeScript 的类型检查集成在一起有不同的选项。

降低 JavaScript 速度

选择这种性能影响方案可能会使基于 Rust 的 linter 速度降低到几乎与 ESLint 无明显性能优势的程度。

以原生速度重新实现 TypeScript

对于 TypeScript 用户来说,以原生速度重新实现 TypeScript 是一个极具吸引力的前景,而不仅仅是对于 linter。目前已有三个重要的尝试:

  • Ezno:一种类似于 TypeScript 的新语言,增加了依赖类型等特性。

  • stc:一个可以替代 TypeScript 类型检查的 Rust 编写项目。

  • TypeRunner:一个较早的尝试,使用 C++ 编写,但已不再积极开发。

需要注意的是,以新语言重新实现 TypeScript 是一项艰巨的任务。TypeScript 的类型推理需要处理泛型类型、协变、逆变等复杂边缘情况,这是一项极具挑战性的任务。这些项目目前都处于非常早期的阶段,可能需要很长时间才能准备投产。

那是否可以通过缩小项目的范围,只实现TypeScript的类型推理部分,从而降低这一选项的复杂性呢?对于 linters 来说,一个简化版的TypeScript,跳过源代码转换、类型检查可分配性错误等部分,只专注于编程类型检查API,或许更为实用。例如,Oxc 项目已经成功地实现了一个 TypeScript 类型推理的简化版,仅用几千行Rust代码就完成了这一任务。

然而,我们必须正视TypeScript背后有一个强大的开发团队和社区支持的现实。TypeScript团队由专业的编程语言专家组成,并且持续从社区中获得贡献。对于任何尝试重新实现TypeScript的项目来说,跟上TypeScript的更新步伐是一项几乎不可能完成的任务。尽管Ezno和stc等项目展现了令人印象深刻的成果,但它们作为独立项目的长期可行性仍然充满了不确定性。

将 TypeScript 的 API 提升到原生速度

为了提高TypeScript的性能,一个更具可行性的长期方案是优化其类型检查器的运行速度。目前有几种可能的解决方案:

  • 将TypeScript的类型检查器转换为更高效的编程语言,如Go或Rust。这可以通过编写一个转换工具来实现,将TypeScript源代码转换为这些更快的语言。

  • 对TypeScript进行预编译和优化,类似于将其转换为二进制格式。这种方法可以在编译时对代码进行优化,以提高运行时的性能。

  • 利用Node.js的用户快照技术来优化启动时间。通过在启动时预先优化代码,可以加快冷启动编译器的速度。

  • AssemblyScript和Static TypeScript是另外两个有趣的探索方向,它们通过使用TypeScript的子集或修改版本来关注低级性能。

这些方案都面临一定的挑战,需要投入时间和资源进行开发。然而,通过持续优化和改进,可以逐步提高TypeScript的性能,使其更加适应快速发展的开发需求。

虽然可以通过各种方法来加速TypeScript的运行,但其实TypeScript本身的架构是阻碍性能提升的主要因素。它的代码基于一种假设,即运行时环境将提供内置的垃圾回收、可变对象等功能,而这些功能往往会带来性能上的损耗。

为了真正提高TypeScript的性能,我们可能需要重新设计其架构,使其更加适应高性能场景:

  1. 隔离声明模式:这可能是最直接的方法,通过将类型声明与实际代码隔离,可以减少编译时的计算量,从而提高运行速度。

  2. 优化全局类型扩展:为了更好地支持并行化,我们需要限制全局类型扩展的使用,以减少潜在的性能瓶颈。

  3. 改进检查器运行方式:通过改变TypeScript检查器的运行方式,可以避免一些不必要的性能损耗,进一步提高运行速度。

然而,任何对TypeScript结构的重大更改都可能导致其API的重大变化,并可能引入新的问题。目前看来,除了可能在2024年推出的隔离声明模式外,其他的大规模改动短期内不太可能实现。

TypeScript 集成 Linting

另一个策略是将 linting 集成到现有的 TypeScript 语言服务器基础架构中。TypeScript 语言服务插件允许添加工具作为 TypeScript 编辑体验的一部分运行。

可以看到过两次尝试:

  • Quramy/typescript-🐴-language-service:ESLint 的通用 TypeScript 语言服务插件

  • johnsoncodehk/typescript-linter:基于 TypeScript 语言服务器构建的代码检查器的重新实现

两者似乎都有希望。为了与现有规则兼容,在短期内将 ESLint 作为 TypeScript 语言服务插件运行是更可行的。无论哪种方式,在不落后于其他语言的情况下,如何使 TypeScript 体验变得更好,尤其是考虑到 ESLint 打算拥抱其他 Web 语言,这将是一个关键挑战。

小结

基于 Rust 的 JavaScript/TypeScript 代码检查器,如 Biome、deno lint、Oxc 和 RSLint,都是非常快速的项目。但与 ESLint + typescript-ndrings 的类型检查代码规则相比,这种速度存在严重的功能差距。在决定使用哪个工具时,你应该了解这些权衡。Biome 和 oxlint 都表示在一定程度上建议先运行一个更快的原生速度代码检查器,而不是运行基于类型的 typescript-lint。

基于 Rust 的 linter 最终可能会以原生速度代码获得类型检查 linting 的好处。但要实现这一点还有很长的路要走。

当然也有好处和坏处,按照自己需求使用即可。

相关文章:

2024 基于 Rust 的 linter 工具速度很快

2024 年 Web 工具的一大趋势是使用 Rust 重写现有工具。Rust 是一种出色的编程语言,能生成运行速度惊人的二进制文件,且与其它 Web 工具的互操作性极佳,这得益于 WebAssembly 的帮助。swc 和 Turbopack 等工具的速度提升为快速开发体验带来了…...

JWT相关问题及答案(2024)

1、什么是 JWT,它通常用于什么目的? JWT(JSON Web Token)是一种开放标准(RFC 7519),用于在不同实体之间安全地传输信息。它由三个部分组成:头部(Header)、载…...

Linux例行性工作 at和crontab命令

1,例行性工作 例行性工作 —— 在某一时刻,必须要做的事情 —— 定时任务 (比如:闹钟) 例行性工作分为两种:“单一的例行性工作 at”和“循环的例行性工作 crontab” 2,单一执行的例行性工作 …...

cookie共享和session共享实例演示

1、cookie共享实例 1.test1.share.com/index.php setcookie(dangqian, value, [domain > test1.share.com]); setcookie(gen, value, [domain > share.com]);2、test2.share.com/index.php $cookies $_COOKIE; // 打印所有Cookie的名称和值 foreach ($cookies as $n…...

设计模式之开闭原则:如何优雅地扩展软件系统

在现代软件开发中,设计模式是解决常见问题的最佳实践。其中,开闭原则作为面向对象设计的六大基本原则之一,为软件系统的可维护性和扩展性提供了强大的支持。本文将深入探讨开闭原则的核心理念,以及如何在实际项目中运用这一原则&a…...

Python Pandera 用于数据验证和清洗:是一个强大的工具用起来

今天为大家分享一个非常好用的 Python 库 - pandera。 Github地址:https://github.com/unionai-oss/pandera 在数据科学和数据分析中,数据的质量至关重要。不良的数据质量可能导致不准确的分析和决策。为了确保数据的质量,Python Pandera 库…...

英诺赛科推出BMS方案,搭载100V双向导通VGaN

BMS 俗称电池保姆或电池管家,主要是为了智能化管理及维护各个电池单元,防止电池出现过充电和过放电,保障电池安全使用的同时延长使用寿命。 当前市面上出现的电池管理系统大多数采用 Si MOS,由于 Si MOSFET 具有寄生二极管&#x…...

如何用Mac工具制作“苹果高管形象照”

大伙儿最近有没有刷到“苹果高管形象照”风格,详细说来就是: 以苹果官网管理层简介页面中,各位高管形象照为模型,佐以磨皮、美白、高光等修图术,打造的看上去既有事业又有时间有氧的证件照,又称“苹…...

回环检测算法:Stable Trangle Descriptor

回环检测是指检测传感器的两次测量(如图像、激光雷达扫描)是否发生在同一场景,它是对于SLAM问题至关重要。基于激光雷达的回环检测应该满足如下要求: 无论视点如何变化,回环检测方法应该实现旋转和平移不变性&#xf…...

MetaGPT入门(二)

接着MetaGPT入门(一),在文件里再添加一个role类 class SimpleCoder(Role):def __init__(self,name:str"Alice",profile:str"SimpleCoder",**kwargs):super().__init__(name,profile,**kwargs)self._init_actions([Write…...

AI嵌入式K210项目(4)-FPIOA

文章目录 前言一、FPIOA是什么?二、FPIOA代码分析总结 前言 磨刀不误砍柴工,在正式开始学习之前,我们先来了解下K210自带的FPIOA,这个概念可能与我们之前学习STM32有很多不同,STM32每个引脚都有特定的功能&#xff0c…...

FPGA开发设计

一、概述 FPGA是可编程逻辑器件的一种,本质上是一种高密度可编程逻辑器件。 FPGA的灵活性高、开发周期短、并行性高、具备可重构特性,是一种广泛应用的半定制电路。 FPGA的原理 采用基于SRAM工艺的查位表结构(LUT),…...

上海亚商投顾:沪指冲高回落 旅游板块全天强势

上海亚商投顾前言:无惧大盘涨跌,解密龙虎榜资金,跟踪一线游资和机构资金动向,识别短期热点和强势个股。 一.市场情绪 沪指昨日冲高回落,创业板指跌近1%,北证50指数跌超3%。旅游、零售板块全天强势&#xf…...

Linux网络--- SSH服务

一、ssh服务简介 1、什么是ssh SSH(Secure Shell)是一种安全通道协议,主要用来实现字符界面的远程登录、远程复制等功能。SSH 协议对通信双方的数据传输进行了加密处理,其中包括用户登录时输入的用户口令,SSH 为建立在…...

2.1 数组

2.1 数组 (1) 概述 定义 在计算机科学中,数组是由一组元素(值或变量)组成的数据结构,每个元素有至少一个索引或键来标识 因为数组内的元素是连续存储的,所以数组中元素的地址,可以通过其索引…...

超维空间M1无人机使用说明书——53、ROS无人机二维码识别与降落——V2升级版本

引言:使用二维码引导无人机实现精准降落,首先需要实现对二维码的识别和定位,可以参考博客的二维码识别和定位内容。本小节主要是通过获取拿到的二维码位置,控制无人机全向的移动和降落,本小节再V1版本的基础上增加了动…...

瑞萨IDE:CS+ for CC进行BootLoader升级时开发环境配置

瑞萨IDE:CS+ for CC进行BootLoader升级时开发环境配置 2023-06-17 726 发布于河北 版权 简介: BootLoader程序设计是常用的嵌入式升级方案之一,通过使用UART、SPI、IIC等接口实现对嵌入式节点的远程升级。本片博文并不是讲解如何实现BootLoader升级程序,而是讲解使用CS+…...

翻译: Streamlit从入门到精通 显示图表Graphs 地图Map 主题Themes 二

Streamlit从入门到精通 系列: 翻译: Streamlit从入门到精通 基础控件 一 1. 使用Streamlit显示图表Graphs 1.1 为什么我们需要可视化? 数据可视化通过将数据整理成更容易理解的格式来讲述故事,凸显趋势和异常点。好的可视化能够讲述一个故…...

Java 开源扫雷游戏 JMine 发布新版 3.0 及介绍视频

Java 开源扫雷游戏 JMine 发布新版 3.0 及介绍视频 Java 开源扫雷游戏 JMine 是笔者开发的基于 Swing 的 Java 扫雷游戏,现已发布新版 3.0 及其介绍视频。视频请见: https://www.bilibili.com/video/BV1RK4y1z7Qz/ 老版本 JMine 1.2.5 的介绍视频请见…...

Vue v-model 详解

✨ 专栏介绍 在当今Web开发领域中,构建交互性强、可复用且易于维护的用户界面是至关重要的。而Vue.js作为一款现代化且流行的JavaScript框架,正是为了满足这些需求而诞生。它采用了MVVM架构模式,并通过数据驱动和组件化的方式,使…...

18年产品经理生涯精华:从交付到规划,项目管理、解决方案、业务理解深度解析!

本期访谈只有1位老师,大海老师,18年工作经验,从干交付,到项目管理,再到资深技术专家、解决方案专家,目前做的更多的是业务规划、产品规划,是从一线实战走到真正的专家层面,老师分享的…...

编译期类型自省如何拯救百万行遗留代码?C++27静态反射工业改造全链路拆解,从PoC到A/B灰度发布

第一章:编译期类型自省如何拯救百万行遗留代码?C27静态反射工业改造全链路拆解,从PoC到A/B灰度发布在某金融核心交易系统中,127万行C11遗留代码长期依赖宏字符串硬编码实现序列化与配置绑定,导致每次协议变更需人工同步…...

SearXNG 高级部署方案:自带反向代理的专家级配置

SearXNG 高级部署方案:自带反向代理的专家级配置 【免费下载链接】searxng-docker The docker-compose files for setting up a SearXNG instance with docker. 项目地址: https://gitcode.com/gh_mirrors/se/searxng-docker 想要快速搭建一个安全、隐私保护…...

头皮上也长痘痘,一梳头就碰到好痛怎么办?

很多人都有过头皮长痘的困扰,一梳头碰到就痛,别提多难受了。其实,头皮长痘和我们的健康息息相关,下面就来详细说说其中的原因和解决办法。痘痘成因大揭秘清洁不到位头皮和脸部皮肤一样,会分泌油脂。如果平时洗头不勤&a…...

聊着天把虾队管了:用 HiClaw 正确打开多智能体协作方式【限时领 PPT】

作者:戴靖泽(静择) 本文整理自 DataWhale x HiClaw 直播分享,聊聊多 Agent 协作背后的工程思考。 点击此处,查看分享! 你有没有试过让一个 AI 同时写前端和后端?聊到后面它把自己定好的 API …...

OpenClaw + Seedance 2.0实战:从零搭建全自动AI视频生成流水线

OpenClaw Seedance 2.0实战:从零搭建全自动AI视频生成流水线 前言 这篇记录我用OpenClaw Agent串联Seedance 2.0满血版API,搭建全自动视频生产流水线的完整过程。包括架构设计、Skill编写、API调用细节和踩坑记录。 一、架构设计 用户输入&#xff…...

第五章作业

233817310313 文章目录图1&#xff1a;单位数码管显示7图2&#xff1a;单位数码管轮播0-9图3&#xff1a;6位数码管显示9图1&#xff1a;单位数码管显示7 #include <reg52.h>#define uchar unsigned char #define uint unsigned int// 定义锁存器控制引脚 sbit LE P2^7;…...

元宇宙中的软件开发和测试:新场景,新挑战

从二维平面到三维宇宙的范式跃迁我们正站在一个数字时代的分水岭上。元宇宙&#xff0c;这个融合了虚拟现实、增强现实、区块链、人工智能与物联网的复杂数字生态&#xff0c;正将软件测试的战场从熟悉的二维平面界面&#xff0c;推向一个充满无限可能的三维沉浸式宇宙。对于软…...

手把手教你用FPGA实现SGMII接口:从IP核配置到板级调试全流程

手把手教你用FPGA实现SGMII接口&#xff1a;从IP核配置到板级调试全流程 在当今高速网络设备开发中&#xff0c;SGMII&#xff08;Serial Gigabit Media Independent Interface&#xff09;因其引脚精简、抗干扰强等优势&#xff0c;已成为FPGA与PHY芯片间千兆通信的首选方案。…...

告别ArcGIS依赖!用QGIS 3.28把SHP属性表一键导出Excel,附赠3个数据清洗小技巧

告别ArcGIS依赖&#xff01;用QGIS 3.28高效导出SHP属性表到Excel的完整指南 当你在处理地理空间数据时&#xff0c;是否曾因ArcGIS的复杂操作或高昂成本而感到困扰&#xff1f;QGIS作为一款开源GIS软件&#xff0c;不仅完全免费&#xff0c;还能轻松完成从基础到高级的空间数据…...