jjzjj

Bun 会是 Webpack 之后的下一件大事吗?

涅槃快乐是金 2023-10-16 原文

JavaScript 工具的未来将离 JavaScript 越来越远,一些工具(如 Webpack 和 Babel)的重要性正在日益下降。为什么?

目前已经证明一些语言(如 Rust、Go 甚至 Zig)在捆绑、转译和编译方面比 JavaScript 具有更好的性能。它们不是单线程的,这在处理大量文件方面具有优势。

是什么原因导致一定要用 JavaScript 开发生态系统的工具?毕竟这些工具主要运行在开发人员的机器上,而不是在浏览器上。此外,JavaScript 开发人员不需要调试这些工具的内部代码。

SWC 是最早摆脱 JavaScript 的工具项目之一,不久之后,Esbuild 发布了,很多人为之兴奋不已,因为在性能方面表现出色,它们成了真正的游戏规则改变者。目前,Vite 2.0 正在底层使用 Esbuild 来提供高性能的构建体验。

最近,JavaScript 工具生态系统中出现了一个新成员——Bun。它的目标是让整个 JavaScript 开发过程更加快速,这是一个全能的工具,它不仅加快了编译和解析的速度,还提供了自己的依赖项管理器工具和捆绑。

这个工具还没有为在生产环境中使用做好准备,但它的未来看起来很光明。本文将介绍这个新工具,以及它与 NPM、Esbuild、Babel 和 Webpack 之间的对比。

概览

与其他使用 Rust 或 Go 开发的工具不同,Bun 是用 Zig 开发的。Zig 是一种通用的编程语言和工具链,用于开发和维护健壮、优化和可重用的软件。

尽管它是从头开始开发的,但开发者采用了与 Esbuild 项目类似的开发方式。

Bun 支持一些开箱即用的复杂特性,如 TypeScript、CSS in Js、JSX,不过还缺少一些基本功能,如源映射、Minifier、摇树优化等。

Bun 的一个显著特性是它提供了自己的 Node 模块解析器实现,这是最值得关注的优化之一。

与 NPM 和 Yarn 一样,Bun 也会创建锁文件,叫作 bun.lockb。这里需要注意的是,它生成的是二进制文件,而不是纯文本文件。为什么是二进制文件?主要是出于性能的考虑。坏处是不便于我们检查 PR 的变化。

检查锁文件的唯一方法是使用下面的命令:

bun install -y

Bun 目前支持下面这些加载器:

image.png

安装配置

Bun 还不是一个公开项目,你需要加入他们的 Discord 频道并发出邀请请求。在进入 Discord 后找到他们的 #invites 频道,然后在“I want bun”频道上发起邀请请求。

你将获得一个一次性的 jarred-sumner/bun 代码库邀请。

要安装 Bun,你需要执行下面的命令:

curl -fsSL https://bun.sh/install | bash

检查是否可以正常运行:

bun --version

你会看到它还没有达到 1.0.0 版本。正如我前面提到的,它还没有为在生产环境中使用做好准备。

使用

它的用法很简单。如果你熟悉 Yarn 或 NPM,你会发现它们几乎是一样的。

安装包:

bun install

与 Yarn 一样,它将使用已有的 package.json 与锁文件(如果有的话)的组合。

添加或删除包:

bun remove react

我们可以将 Bun 作为执行器:

# instead of `npm run clean`

它通过 create 命令提供了与最新的 React 生态系统的一些集成。

我们来创建一个 Next.js 应用:

bun create next ./app

我们来创建一个 Create-React 应用:

bun create react ./app

如何生成捆绑文件?

运行bun bun ./path-to.js可以生成 node_modules.bun 文件,它包含了所有导入的依赖项。

你可以通过执行./node_modules.bun > build.js来查看包的内容。

基准测试

让我们通过运行一些基准测试来了解它的速度。当然,这些都是近似的测量值,并且跟运行环境的配置有关。因为这是开发人员的工具,所以我主要关注最常见的开发任务:

  • 启动开发服务器;

  • 对文件做一些修改;

  • 安装包;

  • 构建生产发行包;

  • 创建一个新的 Web 应用程序。

作为参考,我的笔记本电脑配备了 AMD Raizen 7 CPU 和 16GB 内存,系统是 Ubuntu 20.04。

我使用了一个生成随机 jsx 文件的工具。我生成了 21 个随机的 jsx 文件,我将它们包含在所有测试项目中。

Bun 与 Babel

这个对比可能不是很公平,但它确实让我们看到这个工具与传统工具相比是多么的快。

转译 React 文件对比
创建一个 Create-React 应用

我们可以看到,使用 Bun 和 Webpack+NPM 创建 Create React 应用之间的明显区别。前者几乎没有任何延迟,只需要 4.4 秒就可以完成所有设置。

创建 CRA 对比
创建一个 Next.js 应用

之前的结果其实并没有那么令人印象深刻,毕竟我们已经习惯了用其他工具痛击 Webpack。我们来进行一场公平的战斗,比较一下 Bun 和 SWC。

Bun 与 SWC 对比

两者之间的差异非常明显,特别是在处理文件变更方面。在我的笔记本电脑上,Bun 只需要 10 毫秒,而 SWC 需要 70 毫秒。

包管理器

在模块的安装和操作方面,Bun 也有一些优势。其他工具依赖 NPM 或 Yarn 来完成这项工作,Bun 的性能大约比 NPM 快 4 到 100 倍。

我们已经第二步中看到了两者的巨大差异。不过,我们现在来做一个更基本的例子。我们创建一个 package.json 文件,其中的依赖项如下:

  • date-fns@2.28.0——89.5KB

  • jspdf@2.5.1——339.1KB

  • react@17.0.2——6.9KB

然后我们对第一次安装和基于缓存安装进行基准测试。为了让差异更加明显,我选择了一个大型的库(jspdf)。


Bun 与 NPM 安装包对比

时间差异很明显。如果通过网络安装,速度快 4 倍,如果从缓存中解析,速度会快更多。

Bun 与 Vite

Esbuild 是 Bun 真正的竞争对手。对于这个测试,我使用了 Vite,因为它内部使用了 Esbuild。

Bun 与 Vite 在开发服务器方面的对比

我还基于之前相同的代码使用三个主要工具生成了捆绑包。需要注意的是,我们不建议在生产环境中使用 Bun,因为它缺少了相当多的特性。尽管基准测试结果令人印象深刻,但我们还是要持谨慎的态度。

在最坏的情况下,最长构建时间是 7 秒。这三个工具在这方面做得很出色,不是没有道理的。


Bun、Vite、SWC 构建一个用于生产环境的捆绑包

总结

JavaScript 工具从未像现在这么好过,即使这个工具还没有为在生产环境中使用做好准备,但出现了新的竞争对手总是一件好事。Webpack 的未来还不明朗,它在 JavaScript 领域内外都有很多竞争对手。

Bun 并不是万能的工具,它擅长的是构建网站和 Web 应用。如果要构建库,Bun 团队建议使用 Esbuild,甚至 Rollup。

现在,Bun 开发团队的重心仍然不在生产就绪方面,他们专注于开发以及与现有框架和工具的兼容性。

原文链接:
https://betterprogramming.pub/is-bun-the-next-big-thing-after-webpack-d683441f77b9

有关Bun 会是 Webpack 之后的下一件大事吗?的更多相关文章

  1. ETH 徘徊在 1,700 美元附近;下一步是什么? - 2

    以太坊价格分析表明横盘整理,偏向中性。价格从前一交易日的高点1,791美元回落后正在盘整。但是,有趣的是,多头在1,680美元附近持有重要支撑。多头在1,700美元的心理水平附近聚集动能,并准备在接下来的几个交易日推向1,800美元。以太坊价格显示出盘整迹象,因为它形成了多个连续的顶部形态。这种回撤可能是第二大加密货币下一轮上涨的基石。以太坊连续第二个交易日走低。过去10天,价格在1,590-1,760美元的短期区间内盘整。每日烛台高于1,800美元将维持ETH的进一步上涨。ETH价格走低日线图上,以太坊价格在上升趋势线附近获得一轮支撑。来自879.80美元低点的看涨趋势线为ETH买家提供了支

  2. ruby - 变量赋值后的 if 语句 - 有多常见? - 2

    我最近与一位同事讨论了以下Ruby语法:value=ifa==0"foo"elsifa>42"bar"else"fizz"end我个人并没有看到太多这种逻辑,但我的同事指出,这实际上是一种相当普遍的Rubyism。我试着用谷歌搜索这个主题,但没有找到任何文章、页面或SO问题来讨论它,这让我相信这可能是一种非常实际的技术。然而,另一位同事发现语法令人困惑,而是将上面的逻辑写成这样:ifa==0value="foo"elsifa>42value="bar"elsevalue="fizz"end缺点是value=的重复声明和隐式elsenil的丢失,如果我们想使用它的话。这也感觉它与Ruby

  3. Ruby:数组中的下一个/上一个值,循环数组,数组位置 - 2

    假设我有一个没有特定顺序的随机数数组。假设这些是参加马拉松比赛的人的ID#,他们按照完成的顺序添加到数组中,例如:race1=[8,102,67,58,91,16,27]race2=[51,31,7,15,99,58,22]这是一个简化且有些做作的示例,但我认为它传达了基本思想。现在有几个问题:首先,我如何获得特定条目之前和之后的ID?假设我正在查看运行者58,我想知道谁在他之前和之后完成了比赛。race1,runner58:previousfinisher=67,nextfinisher=91race2,runner58:previousfinisher=99,nextfinishe

  4. ruby - 无论如何要在 REPL 中重新加载修改后的 gem 文件 - 2

    在尝试构建Rubygem(使用Bundler)时,我倾向于使用Bundler提供的REPL测试代码——可通过bundleconsole访问。有什么方法可以重新加载整个项目吗?我最终再次加载单个(更改的)文件以测试新更改。 最佳答案 以下hack适用于我的一个相对简单的gem和Ruby2.2.2。我很想看看它是否适合你。它做出以下假设:您具有传统的文件夹结构:一个名为lib/my_gem_name.rb的文件和一个文件夹lib/my_gem_name/,其中包含任何文件/文件夹结构。您要重新加载的所有类都嵌套在您的顶级模块MyGemN

  5. ruby - 删除指定节点之后的所有节点 - 2

    这个问题在这里已经有了答案:Nokogiri:SelectcontentbetweenelementAandB(3个答案)关闭2年前。我正在从url中抓取文本的div,并想删除具有backtotop类的段落下方的所有内容。我在stackoverflow上看到了一段遍历代码片段,看起来很有希望,但我不知道如何将它合并,所以@el只包含第一个p.backtotop之前的所有内容分区我的代码:@doc=Nokogiri::HTML(open(url))@el=@doc.css("div")[0]end遍历片段:doc=Nokogiri::HTML(code)stop_node=doc.css

  6. ruby - `+` 在 `*` 之后的含义,当后者在正则表达式中用作量词时 - 2

    今天我遇到了下面的正则表达式,想知道Ruby会用它做什么:>"#a"=~/^[\W].*+$/=>0>"1a"=~/^[\W].*+$/=>nil在这种情况下,Ruby似乎忽略了+字符。如果这是不正确的,我不确定它在做什么。我猜它没有被解释为量词,因为*没有转义并且被用作量词。在Perl/Ruby正则表达式中,有时当一个字符(例如,-)在不能被解释为特殊字符的上下文中使用时,它会被视为文字。但如果在这种情况下发生这种情况,我希望第一个匹配失败,因为左值字符串中没有+。这是对+字符的巧妙正确使用吗?以上行为是错误吗?我是否遗漏了一些明显的东西? 最佳答案

  7. ruby-on-rails - Ruby:给定日期找到下一个第二或第四个星期二 - 2

    我似乎找不到一种优雅的方式来做到这一点......给定一个日期,我如何找到下一个星期二,即日历月的第2个或第4个星期二?例如:给定2012-10-19然后返回2012-10-23或给定2012-10-31然后返回2012-11-13OctoberNovemberSuMoTuWeThFrSaSuMoTuWeThFrSa12345612378910111213456789101415161718192011121314151617212223242526271819202122232428293031252627282930 最佳答案

  8. ruby - 用于删除下一个/尾随字符的转义序列? - 2

    除了使用\x08删除前导字符外,是否可以同时删除尾随字符?是否有一个转义序列将删除下一个字符而不是前一个字符?我看到delete显然映射到ASCII127,即Hex7F,但以下代码:puts"a\x08b\x7fcd"产生b⌂cd我预计\x7f会删除它后面的'c'字符,但它没有。 最佳答案 您实际上并没有使用\x08删除任何内容,您只是用“b”覆盖了“a”。想象一下您使用电传纸质终端的过去。您实际上会在纸上看到的是打印的“a”,电传打字机会备份一个空格,然后在其上打印“b”。所有非打印的ascii码都是为了控制电传纸终端的移动而发明

  9. Ruby URI - 如何在 URL 之后获取完整路径 - 2

    给定以下内容,如何获取URL的完整路径uri=URI("http://foo.com/posts?id=30&limit=5#time=1305298413")我只想要posts?id=30&limit=5#time=1305298413我试过uri.path并返回/posts和ui.query返回'id=30&limit=5' 最佳答案 您要找的方法是request_uriuri.request_uri=>"/posts?id=30&limit=5"如果需要,您可以使用任何您想要删除前导/的方法。编辑:要获取#符号后的部分,请使用

  10. ruby-on-rails - 在 Rails 中计算到下一个生日的天数 - 2

    我有一个模型,其中有一个名为birthday的date列。我如何计算距离用户下一个生日还有多少天? 最佳答案 这是一个简单的方法。你要确保捕获今年已经通过的案例(以及尚未通过的案例)classUser=bday(bday-Date.today).to_iendend并证明这一点!(我添加的是timecopgem以保持计算截至今天(2012-10-16)的准确性require'test_helper'classUserTest 关于ruby-on-rails-在Rails中计算到下一个生日

随机推荐