Bun vs Node.js
<div><div class="image-package">
<div class="image-container">
<div class="image-container-fill"> </div>
</div>
<div class="image-caption">
<p><img src="https://img2024.cnblogs.com/blog/1422254/202408/1422254-20240830100511938-860561071.png" alt="" loading="lazy"></p>
<p> </p>
</div>
</div>
<p>2023年9月8日,<code>JavaScript</code>社区再次掀起了新一轮热潮:由<code>Jarred Sumner</code>创建的<code>Bun v1.0</code>问世了。然而,随着各种讨论的进行,许多人都在疑惑:<code>Bun</code>的本质是什么?为什么人们会将其与经过时间考验的<code>Node.js</code>相提并论?<code>Bun</code>只是又一个短暂的趋势,还是它将重新定义游戏规则?在本文中,让我们深入了解``Bun,了解其特点,并了解它与深受信任的<code>Node.js</code>相比如何。</p>
<h2>什么是Bun?</h2>
<p><code>Bun</code>是一个针对<code>JavaScript</code>和<code>TypeScript</code>应用的超快全能工具包。<code>Bun</code>的美妙之处在于它能够简化开发流程,使其比以往更加顺畅和高效。这是可能的,因为<code>Bun</code>不仅是一个运行时,它还是一个包管理器、一个打包工具和一个测试运行器。想象一下拥有一个<code>JS</code>开发的瑞士军刀;那就是<code>Bun</code>。</p>
<h2>Bun解决的问题</h2>
<p><code>Node.js</code>在2009年的诞生是具有突破性的。然而,就像许多技术一样,随着它的发展,它的复杂性也在增加。想象一下城市。随着城市的扩张,交通拥堵可能成为一个问题。</p>
<p><code>Bun</code>旨在成为缓解这种拥堵的新基础设施,使事物运行更加顺畅和快速。这并不是要重复造轮子,而是要对其进行精益求精,确保我们既获得了速度和简单性,又没有失去<code>JavaScript</code>独特和强大之处的本质。</p>
<p><code>Bun</code>被设计为<code>Node.js</code>的更快、更精简、更现代化的替代品,因此让我们更详细地比较一下它们的一些差异。但首先让我们讨论另一个话题。</p>
<h5>Node.js vs Deno vs Bun</h5>
<p>当讨论<code>JavaScript</code>运行时的演变时,很难忽略<code>Deno</code>。<code>Node.js</code>的创始人<code>Ryan Dahl</code>介绍了<code>Deno</code>作为一个新的运行时,旨在解决他在<code>Node.js</code>中发现的一些问题和缺陷。</p>
<p><code>Deno</code>是一个用于<code>JavaScript</code>和<code>TypeScript</code>的安全运行时。它直接解决了<code>Node.js</code>的许多缺点。例如,<code>Deno</code>原生支持<code>TypeScript</code>,无需外部工具。与<code>Node.js</code>不同,<code>Node.js</code>默认情况下脚本具有广泛的权限,<code>Deno</code>采用安全优先的方法,要求开发人员明确授予权限,以执行可能涉及敏感操作的操作,例如文件系统访问或网络连接。</p>
<p>虽然<code>Deno</code>为<code>Node.js</code>提供了一种引人注目的替代方案,但它还没有达到<code>Node.js</code>的广泛应用。因此,本文重点讨论<code>Bun</code>与深受信任的<code>Node.js</code>之间的对比。</p>
<h2>入门</h2>
<p>使用<code>Bun</code>,我们可以使用命令<code>bun init -y</code>创建一个空项目。我们生成了一些文件,在<code>index.ts</code>中添加一行,<code>console.log("Hello, Bun!")</code>。在终端中,运行命令<code>bun index.ts</code>以查看<code>“Hello, Bun!”</code>被记录。</p>
<h2>Bun vs Node.js:JavaScript运行时</h2>
<p><code>JavaScript</code>运行时是提供所有必要组件以便使用和运行<code>JavaScript</code>程序的环境。</p>
<p><code>Node.js</code>和<code>Bun</code>都是运行时。<code>Node.js</code>主要是用<code>C++</code>编写的,而<code>Bun</code>是用一种称为<code>Zig</code>的低级通用编程语言编写的。但这只是冰山一角。让我们更仔细地看看在将Bun视为仅运行时时的其他区别。</p>
<h5>JavaScript引擎</h5>
<p><code>JavaScript</code>引擎是一个将我们编写的<code>JavaScript</code>代码转换为机器代码的程序,从而使计算机能够执行特定任务。</p>
<p><code>Node.js</code>使用了谷歌的<code>V8</code>引擎,该引擎驱动<code>Chrome</code>浏览器,而Bun使用了<code>JavaScriptCore(JSC)</code>,这是由苹果为<code>Safari</code>开发的开源<code>JavaScript</code>引擎。</p>
<p><code>V8</code>和<code>JSC</code>具有不同的架构和优化策略。<code>JSC</code>优先考虑更快的启动时间和更少的内存使用,而执行时间略慢一些。另一方面,<code>V8</code>优先考虑快速执行,具有更多的运行时优化,这可能导致更多的内存使用。<br>
这使得<code>Bun</code>启动速度快,比<code>Node.js</code>快4倍。<br>
</p>
<div class="image-package">
<div class="image-container">
<div class="image-container-fill"> </div>
<div class="image-view" data-width="2000" data-height="1386"><img src="//upload-images.jianshu.io/upload_images/10024246-8af12c6fdf893e27.png?imageMogr2/auto-orient/strip|imageView2/2/w/1200/format/webp" title="" data-original-src="//upload-images.jianshu.io/upload_images/10024246-8af12c6fdf893e27.png" data-original-width="2000" data-original-height="1386" data-original-format="image/png" data-original-filesize="1242403" data-image-index="1"></div>
</div>
<div class="image-caption">
<p><img src="https://img2024.cnblogs.com/blog/1422254/202408/1422254-20240830100545790-1439705935.png" alt="" loading="lazy"></p>
<p> </p>
</div>
</div>
<blockquote>
<p>总结:<code>bun</code>比<code>deno</code>快2.19倍,比<code>node</code>快4.81倍。</p>
</blockquote>
<h5>转译器</h5>
<p>虽然<code>Node.js</code>是<code>JavaScript</code>的强大运行时,但它不直接支持<code>TypeScript</code>文件。要在<code>Node.js</code>环境中执行<code>TypeScript</code>,需要外部依赖。一个常见的方法是使用构建步骤将<code>TypeScript(TS)</code>转译为<code>JavaScript(JS)</code>,然后运行生成的<code>JS</code>代码。以下是一个使用ts-node包的基本设置:</p>
<ul>
<li>1.安装</li>
</ul>
<div class="_2Uzcx_">
<div class="cnblogs_Highlighter">
<pre class="brush:javascript;gutter:true;">npm install -D typescript ts-node
</pre>
</div>
<p> </p>
</div>
<ul>
<li>2.脚本配置</li>
</ul>
<p>在你的package.json中,你可以设置脚本来简化这个过程:</p>
<div class="_2Uzcx_"><button class="VJbwyy" type="button"></button>
<div class="cnblogs_Highlighter">
<pre class="brush:javascript;gutter:true;">{
"scripts": {
"start": "ts-node ./path/to/your/file.ts"
}
}
</pre>
</div>
<p> </p>
</div>
<ul>
<li>3.执行</li>
</ul>
<p>有了以上脚本,你可以轻松运行你的TypeScript文件:</p>
<div class="cnblogs_Highlighter">
<pre class="brush:javascript;gutter:true;">npm start</pre>
</div>
<p>相比之下,<code>Bun</code>提供了一种更简化的方法。它内置了一个<code>JavaScrip</code>t转译器到运行时中。这允许你直接运行<code>.js</code>、<code>.ts</code>、<code>.jsx</code>和<code>.tsx</code>文件。<code>Bun</code>的内置转译器无缝地将这些文件转换为原生<code>JavaScript</code>,无需额外步骤即可立即执行。</p>
<div class="cnblogs_Highlighter">
<pre class="brush:javascript;gutter:true;">bun index.ts</pre>
</div>
<p>当运行TypeScript文件时,速度差异被放大,因为Node.js需要一个转译步骤才能运行。</p>
<div class="image-package">
<div class="image-container">
<div class="image-container-fill">
<p><img src="https://img2024.cnblogs.com/blog/1422254/202408/1422254-20240830100630643-1839943640.png" alt="" loading="lazy"></p>
</div>
</div>
</div>
<blockquote>
<p><code>Bun</code>花费8ms,<code>Node esbuild</code>花费40ms,<code>tsx</code>花费120ms,而<code>tsx</code>花费350ms。</p>
</blockquote>
<h5>ESM和CommonJS兼容性</h5>
<p>模块系统允许开发人员将代码组织成可重用的段。在<code>JavaScript</code>中,两种主要的模块系统是<code>CommonJS</code>和<code>ES</code>模块<code>(ESM)</code>。<code>CommonJS</code>源自<code>Node.js</code>,使用<code>require</code>和<code>module.exports</code>进行同步模块处理,适用于服务器端操作。</p>
<p><code>ESM</code>是在<code>ES6</code>中引入的,它采用<code>import</code>和<code>export</code>语句,提供了一种更静态和异步的方法,针对浏览器和现代构建工具进行了优化。让我们使用<code>colors</code>表示<code>CommonJS</code>,使用<code>chalk</code>表示<code>ESM</code>,这两个流行的包用于将彩色输出添加到控制台,以更好地理解模块系统。</p>
<p>Node.js传统上与CommonJS模块系统相关联。下面是Node.js中的典型用法:</p>
<div class="_2Uzcx_">
<div class="cnblogs_Highlighter">
<pre class="brush:javascript;gutter:true;">// CommonJS in Node.js (index.js)
const colors = require("colors");
console.log(colors.green('Hello, world!'));</pre>
</div>
</div>
<p>对于<code>Node.js</code>中的<code>ES</code>模块,你有两个选择:</p>
<p>你需要在你的<code>package.json</code>中包含<code>"type": "module"</code>。<br>
使用<code>.mjs</code>扩展名。</p>
<div class="_2Uzcx_">
<div class="cnblogs_Highlighter">
<pre class="brush:javascript;gutter:true;">// ESM in Node.js (index.mjs)
import chalk from 'chalk';
console.log(chalk.blue('Hello, world!'));</pre>
</div>
</div>
<p>从<code>CommonJS</code>过渡到<code>ES</code>模块(<code>ESM</code>)是一个复杂的过程。<code>Node.js</code>在<code>ESM</code>引入后5年才支持它,而无需实验性标志。尽管如此,<code>CommonJS</code>仍然在生态系统中普遍存在。</p>
<p><code>Bun</code>通过支持两者而不需要任何特殊配置来简化模块系统。<code>Bun</code>的突出特点是其能够在同一文件中支持<code>import</code>和<code>require()</code>,这在<code>Node.js</code>中是无法原生实现的:</p>
<div class="cnblogs_Highlighter">
<pre class="brush:javascript;gutter:true;">// Mixed modules in Bun (index.js)
import chalk from "chalk";
const colors = require("colors");
console.log(chalk.magenta('Hello from chalk!'));
console.log(colors.cyan('Hello from colors!'));</pre>
</div>
<h5>Web APIs</h5>
<p>作为基于浏览器的应用程序的重要组成部分,<code>Web API</code> 提供了像 <code>fetch</code>和 <code>WebSocket</code> 这样的工具,用于网络交互。尽管这些已经成为浏览器标准,但它们在诸如 <code>Node.js</code>之类的服务器端环境中的支持一直不一致。</p>
<p>在早期的 <code>Node.js</code>版本中,浏览器中常见的 <code>Web</code>标准 <code>API</code>并没有得到原生支持。开发人员不得不依赖第三方包(例如 <code>node-fetch</code>)来复制这些功能。然而,从<code>Node.js v18</code>开始,对<code>fetch API</code>的实验性支持已经存在,这可能消除了对这些包的需求。</p>
<p><code>Bun</code> 通过提供对这些<code>Web</code>标准 <code>API</code>的内置支持来简化这一过程。开发人员可以直接使用稳定的<code>fetch</code>、<code>Request</code>、<code>Response</code>、<code>WebSocket</code> 和其他类似于浏览器的 API,而无需使用额外的包。此外,<code>Bun</code> 对这些 <code>Web API</code> 的本地实现确保了它们与第三方替代方案相比更快、更可靠。</p>
<p>以下是兼容 <code>Node.js</code>(<code>v18</code>及以上版本)和<code>Bun</code>的示例。虽然在<code>Node.js</code>中还处于实验阶段,但在<code>Bun</code>中这个功能已经稳定:</p>
<div class="cnblogs_Highlighter">
<pre class="brush:javascript;gutter:true;">//Experiment fetch in Node.js (v18 and above) and built-in fetch in Bun
async function fetchUserData() {
const response = await fetch("https://jsonplaceholder.typicode.com/users/1");
const user = await response.json();
console.log(user.name);
}
fetchUserData(); // Leanne Graham</pre>
</div>
<h5>Hot reloading</h5>
<p><code>Hot reloading</code>是一项功能,通过在代码更改时自动刷新或重新加载应用程序的部分内容,而无需完全重新启动,从而提高开发人员的生产力。</p>
<p>在<code>Node.js</code>生态系统中,您有几种选项来实现<code>Hot reloading</code>。其中一个流行的工具是 <code>nodemon</code>,它会强制重新启动整个进程:</p>
<div class="_2Uzcx_">
<div class="cnblogs_Highlighter">
<pre class="brush:javascript;gutter:true;">nodemon index.js</pre>
</div>
</div>
<p>另外,从 <code>Node.js v18</code> 开始,引入了一个实验性的 <code>--watch</code> 标志:</p>
<div class="cnblogs_Highlighter">
<pre class="brush:javascript;gutter:true;">node --watch index.js</pre>
</div>
<p>这两种方法都旨在在代码更改时提供应用程序的热更新。然而,它们可能在某些环境或场景中有不同的行为。</p>
<p>例如,<code>nodemon</code> 可能会导致一些干扰,比如中断 <code>HTTP</code> 和<code>WebSocket</code>连接,而实验性的<code>--watch</code> 标志可能不会提供完整的功能集,并且在 <code>GitHub</code>上报告了一些问题。</p>
<p><code>Bun</code> 推进了热更新一步。通过使用<code>--hot</code> 标志运行 <code>Bun</code>,即可启用热重新加载:</p>
<div class="cnblogs_Highlighter">
<pre class="brush:javascript;gutter:true;">bun --hot index.ts</pre>
</div>
<p>与可能需要完全进程重新启动的 <code>Node.js</code>方法不同,<code>Bun</code> 在不终止旧进程的情况下就地重新加载您的代码。这确保了 <code>HTTP</code> 和 <code>WebSocket</code> 连接保持不中断,并且应用程序状态得以保留,从而提供了更流畅的开发体验。</p>
<h5>Node.js 兼容性</h5>
<p>在过渡到新的运行时或环境时,兼容性通常是开发人员的主要关注点。<code>Bun</code> 通过将自己定位为 <code>Node.js</code>的替代品来解决了这个问题。这意味着现有的 <code>Node.js</code>应用程序和 <code>npm</code> 包可以无缝地集成到 <code>Bun</code>中,而无需进行任何修改。确保此兼容性的关键功能包括:</p>
<ul>
<li>支持内置的 <code>Node.js</code> 模块,例如<code>fs</code>、<code>path</code> 和<code>net</code>。</li>
<li>识别全局变量,如<code>__dirname</code>和 <code>process</code>。</li>
<li>遵循 <code>Node.js</code> 模块解析算法,包括熟悉的 <code>node_modules</code> 结构。</li>
</ul>
<blockquote>
<p><code>Bun</code> 仍在不断发展。它旨在增强开发工作流程,是服务器无服务功能等资源有限环境的理想选择。<code>Bun</code>团队正在努力实现全面的 <code>Node.js</code>兼容性,并更好地与普遍存在的框架集成。</p>
</blockquote>
<p>虽然 <code>Bun</code> 确保与 <code>Node.js</code>的兼容性,但它并不止步于此。<code>Bun</code> 附带了高度优化的标准库<code>API</code>,满足开发人员最需要的功能需求。</p>
<h5>Bun APIs</h5>
<ul>
<li>Bun.file()<br>
延迟加载文件并以各种格式访问它们的内容。与其 <code>Node.js</code> 对应方法相比,这个方法速度提高了多达 10 倍。</li>
</ul>
<div class="_2Uzcx_"> </div>
<div class="_2Uzcx_">
<div class="cnblogs_Highlighter">
<pre class="brush:javascript;gutter:true;">// Bun(index.ts)
const file = Bun.file("package.json");
await file.text();</pre>
</div>
</div>
<div class="_2Uzcx_"><button class="VJbwyy" type="button"></button>
<div class="cnblogs_Highlighter">
<pre class="brush:javascript;gutter:true;">// Node.js(index.mjs)
const fs = require("fs/promises");
const fileContents = await fs.readFile("package.json", "utf-8");
</pre>
</div>
<p> </p>
</div>
<ul>
<li>Bun.write()<br>
将数据从字符串到 <code>Blob</code>写入磁盘的多功能 <code>API</code>。它的写入速度比 <code>Node.js</code>快多达 3 倍。</li>
</ul>
<div class="_2Uzcx_">
<div class="cnblogs_Highlighter">
<pre class="brush:javascript;gutter:true;">// Bun(index.ts)
await Bun.write("index.html", "<html/>");
// Node.js(index.mjs)
const fs = require("fs/promises");
await fs.writeFile("index.html", "<html/>");
</pre>
</div>
<p> </p>
</div>
<ul>
<li>Bun.serve()<br>
使用 <code>Web</code>标准 <code>API</code> 设置<code>HTTP</code>服务器或 <code>WebSocket</code> 服务器。它每秒能够提供比 <code>Node.js</code>多达 4 倍的请求数,并处理比<code>Node.js</code>中的<code>ws</code> 包多达 5 倍的 <code>WebSocket</code>消息。这种后端能力类似于开发人员在<code>Node.js</code>中使用 <code>Express</code>,但具有 <code>Bun</code> 性能优化的额外好处。</li>
</ul>
<div class="_2Uzcx_">
<div class="cnblogs_Highlighter">
<pre class="brush:javascript;gutter:true;">// Bun(index.ts)
Bun.serve({
port: 3000,
fetch(request) {
return new Response("Hello from Bun!");
},
});
// Node.js(index.mjs)
import http from "http";
const server = http
.createServer((req, res) => {
res.writeHead(200, { "Content-Type": "text/plain" });
res.end("Hello from Node.js!");
});
server.listen(3000);
</pre>
</div>
<p> </p>
</div>
<p>Bun 还支持 sqlite 和密码内置功能。</p>
<h2>Bun 与 Node.js 对比:包管理器</h2>
<p><code>Bun</code>不仅仅是一个运行时;它还是一个包含强大包管理器的高级工具包。如果您在依赖项安装过程中发现自己需要耐心等待,<code>Bun</code> 提供了一个令人耳目一新的更快速的替代方案。即使您不将<code>Bun</code> 用作运行时,其内置的包管理器也可以加快开发工作流程。</p>
<p>查看下表,比较了<code>Bun</code>命令与<code>npm</code>、<code>Node</code>的包管理器:</p>
<table>
<thead>
<tr><th>Bun</th><th>npm</th><th>Purpose</th></tr>
</thead>
<tbody>
<tr>
<td>bun install</td>
<td>npm install</td>
<td>从 package.json 安装所有依赖项</td>
</tr>
<tr>
<td>bun add <package></td>
<td>npm install <package></td>
<td>向项目添加新包</td>
</tr>
<tr>
<td>bun add <package> --dev</td>
<td>npm install <package> --dev</td>
<td>添加一个仅用于开发的新包</td>
</tr>
<tr>
<td>bun remove <package></td>
<td>npm uninstall <package></td>
<td>从项目中删除一个包</td>
</tr>
<tr>
<td>bun update <package></td>
<td>npm update <package></td>
<td>更新特定包到其最新版本</td>
</tr>
<tr>
<td>bun run <script></td>
<td>npm run <script></td>
<td>从 package.json 执行指定的脚本</td>
</tr>
</tbody>
</table>
<p>乍一看,<code>Bun</code>的命令可能看起来很熟悉,但实际体验却并不平凡。<code>Bun</code> 的安装速度比 <code>npm</code>快上数个数量级。它通过利用全局模块缓存来实现这一点,消除了从<code>npm</code>注册表中下载的冗余文件。此外,<code>Bun</code>使用每个操作系统可用的最快的系统调用,确保了最佳的性能。</p>
<p>以下是从缓存安装 <code>Remix</code>初始项目的依赖项时,Bun 和 npm 的速度比较:</p>
<div class="image-package">
<div class="image-container">
<div class="image-view" data-width="2000" data-height="988">
<p><img src="https://img2024.cnblogs.com/blog/1422254/202408/1422254-20240830100720317-1335516659.png" alt="" loading="lazy"></p>
</div>
</div>
</div>
<p><code>bun CLI</code> 包含一个与 <code>Node.js</code>兼容的包管理器,旨在成为 <code>npm</code>、<code>yarn</code> 和 <code>pnpm</code>的显著更快的替代品</p>
<p>此外,<code>bun run <command></code> 仅需 7 毫秒,而<code>npm run <command></code> 需要 176 毫秒。虽然 <code>Node.js</code> 的 <code>npm</code>多年来一直是 <code>JavaScript</code> 包管理的标准,但 <code>Bun</code>真的是一个速度强大的工具,并提供了一个引人注目的替代方案。</p>
<h2>Bun 与 Node.js 对比:打包工具</h2>
<p>打包是将多个 <code>JavaScript</code>文件合并成一个或多个优化的捆绑包的过程。此过程还可能涉及转换,例如将<code>TypeScript</code>转换为 <code>JavaScript</code>或将代码缩小以减小其大小。</p>
<p>在<code>Node.js</code> 生态系统中,打包通常由第三方工具处理,而不是 <code>Node.js</code>本身。在 <code>Node.js</code> 世界中,一些最流行的打包工具包括 <code>Webpack</code>、<code>Rollup</code>和 <code>Parcel</code>,它们提供了代码分割、树摇和热模块替换等功能。</p>
<p>另一方面,<code>Bun</code> 不仅是一个运行时和一个包管理器,还是一个自己的打包工具。它设计用于为各种平台(包括浏览器中的前端应用程序,如<code>React</code>或 <code>Next.js</code> 应用程序以及 <code>Node.js</code>)打包 <code>JavaScript</code>和 <code>TypeScript</code>代码。</p>
<p>要使用 <code>Bun</code> 进行打包,可以使用简单的命令:</p>
<div class="_2Uzcx_">
<div class="cnblogs_Highlighter">
<pre class="brush:javascript;gutter:true;">bun build ./index.ts --outdir ./build</pre>
</div>
</div>
<p>此命令将 <code>index.ts</code>文件打包,并将结果输出到<code>./build</code> 目录。<code>Bun</code>的打包过程非常快,比 <code>esbuild</code>快了 1.75 倍,并且明显超过了<code>Parcel</code>和 <code>Webpack</code>等其他打包工具。</p>
<div class="image-package">
<div class="image-container">
<div class="image-container-fill">
<p><img src="https://img2024.cnblogs.com/blog/1422254/202408/1422254-20240830100753281-1095961028.png" alt="" loading="lazy"></p>
</div>
</div>
</div>
<blockquote>
<p>Bun耗时0.17秒,esbuild耗时0.3秒,rspack耗时4.45秒,Parcel 2耗时26.32秒,Rollup耗时32秒,Webpack 5耗时38.02秒</p>
</blockquote>
<p><code>Bun</code>的一个突出特点是引入了 <code>JavaScript</code> 宏。这些允许在打包过程中执行 <code>JavaScript</code>函数,并将结果直接内联到最终捆绑包中。此机制为打包提供了一种新的视角。</p>
<p>请看以下示例,在此示例中,<code>Bun</code> 的 <code>JavaScript</code>宏被利用来在打包过程中获取用户名。它不是在运行时执行 <code>API</code>调用,而是在捆绑时间获取数据,将结果直接内联到最终输出中:</p>
<div class="_2Uzcx_">
<div class="cnblogs_Highlighter">
<pre class="brush:javascript;gutter:true;">// users.ts
export async function getUsername() {
const response = await fetch("https://jsonplaceholder.typicode.com/users/1");
const user = await response.json();
return user.name;
}
// index.ts
import { getUsername } from "./users.ts" with { type: "macro" };
const username = await getUsername();
// build/index.js
var user = await "Leanne Graham";
console.log(user);
</pre>
</div>
<p> </p>
</div>
<p>虽然<code>Node.js</code>拥有其成熟的打包工具,但<code>Bun</code>提供了一个集成、更快速和创新的替代方案,可能会改变打包格局。</p>
<h2>Bun 与 Node.js 对比:测试运行器</h2>
<p>测试是软件开发的关键方面,它确保代码的行为符合预期,并在它们进入生产环境之前捕获潜在问题。除了是运行时、</p>
<p>包管理器和打包工具之外,<code>Bun</code> 还是一个测试运行器。</p>
<p>尽管 <code>Node.js</code>开发人员传统上依赖于<code>Jest</code>进行测试,但 <code>Bun</code> 引入了一个内置的测试运行器,该运行器承诺速度快、兼容性好,并具有一系列功能,可满足现代开发工作流程的需求。</p>
<p><code>Bun</code> 的测试运行器 <code>bun:test</code>设计为与<code>Jest</code>完全兼容,<code>Jest</code>是一种以<code>“expect”</code>风格 <code>API</code>而闻名的测试框架。这种兼容性确保了熟悉 <code>Jest</code> 的开发人员可以轻松过渡到<code>Bun</code>,而无需陡峭的学习曲线。</p>
<div class="cnblogs_Highlighter">
<pre class="brush:javascript;gutter:true;">import { test, expect } from "bun:test";
test("2 + 2", () => {
expect(2 + 2).toBe(4);
});</pre>
</div>
<p>使用<code>bun test</code>命令执行测试非常简单。此外,<code>Bun</code> 的运行时直接支持 <code>TypeScript</code> 和 <code>JSX</code>,无需额外的配置或插件。</p>
<h5>从 Jest 或 Vitest 迁移</h5>
<p><code>Bun</code> 对<code>Jest</code>的全局导入的兼容性表现出其对兼容性的承诺。例如,从 <code>@jest/globals</code> 或 <code>vitest</code>导入将在内部重新映射为 <code>bun:test</code>。这意味着现有的测试套件可以在 <code>Bun</code> 上运行,而无需进行任何代码修改。</p>
<div class="cnblogs_Highlighter">
<pre class="brush:javascript;gutter:true;">// index.test.ts
import { test } from "@jest/globals";
describe("test suite", () => {
test("addition", () => {
expect(1 + 1).toBe(2);
});
});
</pre>
</div>
<p> </p>
<h5>性能基准测试</h5>
<p><code>Bun</code>的测试运行器不仅关乎兼容性,还关乎速度。在与<code>Zod</code>的测试套件进行基准测试时,<code>Bun</code> 的速度比 <code>Jest</code> 快 13 倍,比 <code>Vitest</code>快 8 倍。<code>Bun</code> 的匹配器也是用快速的本机代码实现的。例如,在<code>Bun</code>中,<code>expect().toEqual()</code>的速度比<code>Jest</code> 快了惊人的 100 倍,比 <code>Vitest</code> 快了 10 倍。</p>
<p>无论您是要迁移现有测试还是启动新项目,<code>Bun</code>都提供了一个符合现代开发需求的强大测试环境。</p>
<p>结论<br>
<code>Node.js</code>长期以来一直是<code>JavaScript</code>世界的基石,它设定基准并指导开发人员。然而,<code>Bun</code>正在成为一个引人注目的挑战者,打破了界限。</p>
<p>虽然<code>Bun</code>还处于早期阶段,但它所产生的热度是不可否认的。目前,它针对 <code>MacOS</code> 和<code>Linux</code> 进行了优化,虽然 <code>Windows</code>支持正在进行中,但某些功能仍在路上。鉴于它所提供的一切,<code>Bun</code>绝对是一个您应该考虑探索的工具包。</p>
</div><br><br>
来源:https://www.cnblogs.com/ygunoil/p/18388114
頁:
[1]