普通视图

发现新文章,点击刷新页面。
今天 — 2025年5月19日首页

「译文」我买不起奔驰 🚗,但是奔驰买得起 Oxlint ⚓️ 和 Rolldown ⚡️!

2025年5月19日 21:08

前言

今天刷推特看到的一篇博客,作者是奔驰技术团队!

尤雨溪转发的推特

往期精彩推荐

正文

在当今快速发展的 JavaScript 生态系统中,现代工具发挥着关键作用,不仅影响我们的编码方式,还影响我们花费在编码上的时间和金钱。

JavaScript 生态系统中工作时,我们可以利用各种工具来提升质量、一致性和效率。今天,我们将重点介绍两款出色的工具,它们在实现重大里程碑的同时,仍然是大多数用例的直接替代品。

我们将讨论 捆绑器代码检查器,因为它们可能会成为开发或生产构建的瓶颈。

JavaScript 开发中,捆绑器 采用单个代码模块(无论是以 ESM 还是 CommonJS 编写),并将它们组装成一个有凝聚力的、更大的输出,例如完整的应用程序或可重用的库。

对于 Web 应用而言,即使使用 HTTP/2,此过程也能提升加载速度和运行时效率。对于库而言,提前打包可以减少使用方项目重新打包的需要,并提升执行性能。

相反,JavaScript 中的 linting 涉及检查代码以捕获潜在的错误、风格不一致以及不良的编码习惯。linter 是一种根据一组定义的规则或标准扫描代码库的工具,它有助于确保代码一致性、增强可读性,并在常见错误成为实际问题之前将其预防。

它是如何变化的?

多年来,各种构建工具层出不穷,包括 WebpackTurbopackRspackVite。其中,Vite 凭借其灵活性、用户友好性以及与各种项目的无缝兼容性,在 JavaScript 社区中得到了广泛的采用。

Vite 底层使用了两个打包器:esbuildRollup。您可以在这里找到更多详细信息,因此我们在此不再赘述。Vite 优秀的开源团队在 VoidZero 的支持下,推出了一款基于 Rust 的全新打包器,旨在取代 esbuildRollup。这款新的打包器保留了 Rollup 的 API,同时显著提升了性能并进行了许多其他改进。

在代码检查方面,ESLint 一直以来都是 JavaScript 代码中发现问题的首选工具。然而,VoidZero 也推出了一款基于 Rust 的替代方案 Oxlint,它的性能得到了提升,运行速度比 ESLint 快 50 到 100 倍。

补充一点,需要记住的是,仅仅迁移到 Rust 并不会自动提升速度。许多此类工具也借此机会考察了其他开源项目的架构,找出了设计瓶颈,并根据我们目前所了解的现实情况,为未来做出更可持续的决策。

它对我们有何影响?

这些新工具更令人印象深刻的是,它们可以直接作为替代品。无需重构代码,也无需花时间思考如何集成所有功能。

Mercedes-Benz.io,我们的前端本质上是微前端,所以我们无法仅仅测试完整构建版本并查看其改进程度。尽管如此,我仍然好奇这些工具会给我们带来多少时间和金钱上的影响,而金钱不一定是机器时间,主要是工程时间。

我从一些团队中挑选了几个代码库,一些团队拥有较多的微前端,而另一些团队拥有较少的微前端,并运行了 4 种类型的测试:

  1. 使用 Rolldown 进行直接替换
  2. 使用 SASS-EmbeddedRolldown 进行直接替换
  3. 使用 SASS-Embedded + Lightning CSSRolldown 进行直接替换
  4. 使用 Oxlint 替代 ESLint

由于我已经在测试它,所以我决定采用两个可用于生产的替代品,如上所示。

Sass-EmbeddedSass 包的替代方案。它支持与 Sass 相同的 JS API,并且由同一团队维护。然而,Sass-Embedded 是一个 JavaScript 封装器,封装了原生 Dart 可执行文件。这意味着它通常速度更快,尤其是在处理大型 Sass 编译时。

LightningCSS 是一款用 Rust 编写的超快速 CSS 解析器、转换器、打包器和压缩器。它是一款能够编译、优化和转换 CSS 的工具,旨在比其他传统工具更快、更高效。

让我们来看看数字

在您测试的所有代码库中,平均结果显示:

  1. 仅使用 Rolldown,构建时间减少了 23%,最高可达 33%。
  2. 使用 Rolldown + Sass-Embedded,构建时间减少了 25%,最高可达 33%。
  3. 使用 Rolldown + Sass-Embedded + Lightning CSS,构建时间减少了 34%,最高可达 38%。

在 linting 方面,转向 Oxlint 后,平均减少了 71%,最高减少了 97%。

这只是这些工具的开始。Rolldown 仍在开发中,但已经经过社区的大量测试,而 Oxlint 目前处于 Beta 阶段。这两款工具都计划进行更多改进。

这真是太神奇了:我们谈论的不是重构代码,也不是花时间理解和尝试适应新工具。我们谈论的是一些可以让我们的 CI 流程减少 64% 的嵌入式替换(仅指构建 + linting)。

假设大约有 100 个项目,每个项目平均每年有 600 次提交,每次提交都需要构建和 lint。这意味着每年可以节省大约 500 个小时,差不多 21 天。由于机器成本难以计算,因此不计入机器成本,我们可以想象工程成本,包括生产力、专注度,以及能否顺利进入流程。

这种节省不仅能显著提高开发效率,还能让团队有更多时间专注于功能开发和创新,从而提升整体项目的质量和响应速度。

最后

原文地址:www.mercedes-benz.io/blog/2025-0…

原推特地址:x.com/boshen_c/st…

往期精彩推荐

一文读懂 webpack 配置选项 output.publicPath

2025年5月18日 00:43

引出问题

入口文件为:

// src/index.js
import path from './assets/webpack.png';
console.log(path);
const img = document.createElement('img');
img.src = path;
document.body.appendChild(img);

配置文件为:

// webpack.config.js
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  mode: 'development',
  output: {
    filename: 'scripts/[name].[chunkhash:3].js',
    clean: true
  },
  devServer: {
    open: 'html/index.html',
    static: './dist'
  },
  plugins: [
    new HtmlWebpackPlugin({
      filename: 'html/index.html'
    })
  ],
  module: {
    rules: [
      {
        test: /\.(png|jpe?g|gif)$/i,
        use: {
          loader: 'file-loader',
          options: {
            name: 'img/[name].[hash:3].[ext]'
          }
        }
      }
    ]
  }
}

打包后 dist 目录的结构为:

dist
  |—— img
    |—— webpack.xxx.png
  |—— scripts
    |—— main.yyy.js
  |—— html
    |—— index.html

打包生成的 dist/html/index.html 文件:

该文件由 html-webpack-plugin 生成,作为一个插件,它知道最终输出的文件在 dist 目录中的位置,因此能够正确引入

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Webpack App</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <script defer src="../scripts/main.yyy.js"></script>
  </head>
  <body>
  </body>
</html>

运行 dist/html/index.html 文件(请求 http://localhost:8080/html/index.html 页面),浏览器控制台输出:img/webpack.xxx.png,该相对路径最终转换成的绝对路径为 http://localhost:8080/html/img/webpack.xxx.png,图片找不到

问题出现的原因

src/assets/webpack.png 图片会交给 file-loader 处理,作为一个 loader,它在运行时,webpack 还未输出文件到 dist 目录,因此,它只知道最终生成到 dist 目录中的图片路径为 img/webpack.xxx.png(配置该 loader 时指定的),并不知道该图片将来会被哪个文件使用

解决方法

// webpack.config.js
module.exports = {
    // ...
    output: {
        // ...
        publicPath: '/'
    }
}

output.publicPath 本质就是一个字符串,并不会影响 webpack 的打包构建过程,只不过该字段的值会被某些 plugin 和 loader 读取使用,例如 html-webpack-plugin、file-loader 等等。

配置 output.publicPath 后:

  • html-webpack-plugin 生成的 html 页面中,会将该值作为 script 标签和 link 标签引入的资源路径的前缀
  • file-loader 在处理文件时,会将该值作为输出路径的前缀
  • ...etc

所以配置了 output.publicPath="/" 后,file-loader 处理 webpack.png 图片时,输出的路径为:/img/webpack.xxx.png,转换为绝对路径后为:http://localhost:8080/img/webpack.xxx.png,路径正确,能够正常找到图片

扩展

若某些 plugin 和 loader 需要使用不同的资源路径前缀,那么可以为这些 plugin 和 loader 分别配置 publicPath,以 file-loaderhtml-webpack-plugin 为例:

// webpack.config.js
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  // ...
  plugins: [
    new HtmlWebpackPlugin({
      // ...
      publicPath: "abc"
    })
  ],
  module: {
    rules: [
      {
        test: /\.(png|jpe?g|gif)$/i,
        use: {
          loader: 'file-loader',
          options: {
            // ...
            publicPath: "bcd"
          }
        }
      }
    ]
  }
}

tip:并不是所有的 plugin 和 loader 都可以配置自己的 publicPath,具体可以参考其 npm 文档

❌
❌