bun.js一个新的JavaScript运行环境
<h2 id="介绍">介绍</h2><p>Bun 是一个现代的JavaScript运行环境,如Node, Deno。主要特性如下:</p>
<ol>
<li>启动速度快。</li>
<li>更高的性能。</li>
<li>完整的工具(打包器、转码器、包管理)。</li>
</ol>
<p>下面我们来横向对比下框架所说的性能:</p>
<p>相同电脑下, 不同 js 运行环境的每秒操作数</p>
<p><img src="https://img2022.cnblogs.com/blog/1182844/202207/1182844-20220730020440143-380946379.png" alt="" loading="lazy"></p>
<h3 id="更多具体的优点">更多具体的优点</h3>
<ul>
<li>
<p>内置 <code>fetch</code>、<code>WebSocket</code> 和 <code>ReadableStream</code> 等API</p>
</li>
<li>
<p>可以在bun.js中使用npm包。支持ESM和CommonJS,但Bun内部使用ESM。</p>
</li>
<li>
<p>在bun.js中,每个文件都是转译的。TypeScript & JSX就可以使用。</p>
</li>
<li>
<p>bun支持 "paths"、"jsxImportSource" 和更多来自tsconfig.json文件的内容。</p>
</li>
<li>
<p>使用 Bun.write 提供的最快的系统调用来写入、复制、管道、发送文件。</p>
</li>
<li>
<p>bun.js会自动从.env文件中加载环境变量。不再需要 require("dotenv").config()</p>
</li>
<li>
<p>bun内置了一个快速的 SQLite3 客户端 bun:sqlite</p>
</li>
<li>
<p>bun.js实现了大部分的Node-API(N-API)。许多Node.js的本地模块都能正常工作。</p>
</li>
</ul>
<h3 id="加载器">加载器</h3>
<p>目前,bun实现了以下加载器:</p>
<table>
<thead>
<tr>
<th>Input</th>
<th>Loader</th>
<th>Output</th>
</tr>
</thead>
<tbody>
<tr>
<td>.js</td>
<td>JSX + JavaScript</td>
<td>.js</td>
</tr>
<tr>
<td>.jsx</td>
<td>JSX + JavaScript</td>
<td>.js</td>
</tr>
<tr>
<td>.ts</td>
<td>TypeScript + JavaScript</td>
<td>.js</td>
</tr>
<tr>
<td>.tsx</td>
<td>TypeScript + JSX + JavaScript</td>
<td>.js</td>
</tr>
<tr>
<td>.mjs</td>
<td>JavaScript</td>
<td>.js</td>
</tr>
<tr>
<td>.cjs</td>
<td>JavaScript</td>
<td>.js</td>
</tr>
<tr>
<td>.mts</td>
<td>TypeScript</td>
<td>.js</td>
</tr>
<tr>
<td>.cts</td>
<td>TypeScript</td>
<td>.js</td>
</tr>
<tr>
<td>.toml</td>
<td>TOML</td>
<td>.js</td>
</tr>
<tr>
<td>.css</td>
<td>CSS</td>
<td>.css</td>
</tr>
<tr>
<td>.env</td>
<td>Env</td>
<td>N/A</td>
</tr>
<tr>
<td>.*</td>
<td>file</td>
<td>string</td>
</tr>
</tbody>
</table>
<h3 id="实现">实现</h3>
<p>Bun.js 使用的是 JavaScriptCore 引擎,<br>
它的执行速度往往要比 V8 等更传统引擎要快。</p>
<p>而他本身, 是由叫做 Zig 的语言编写而成的, Zig 是一门新的系统级编程语言,相当于加强版 C 语言</p>
<h2 id="配置">配置</h2>
<p><code>bunfig.toml</code> 是 bun 的配置文件。</p>
<p>这里给出一个例子:</p>
<pre><code># 默认框架
# 默认情况下,bun会寻找一个类似于`bun-framework-${framework}的npm包,然后是`${framework}`。
framework = "next"
logLevel = "debug"
# publicDir = "public"
# external = ["jquery"]
# 像这样重新映射的配置:
# import {graphql} from 'react-relay';
# To:
# import {graphql} from 'macro:bun-macro-relay';
react-relay = { "graphql" = "bun-macro-relay" }
saveTo = "node_modules.bun"
# Don't need this if `framework` is set, but showing it here as an example anyway
entryPoints = ["./app/index.ts"]
# 如果设置了`framework',就不需要这个了,在这里作为一个例子展示一下。
"@bigapp/design-system" = true
# dev 的启动端口 3000-5000
port = 5000
# 环境变量
"process.env.bagel" = "'lox'"
# 如果文件后缀是 .bagel 则使用 JS 的解析器
".bagel" = "js"
# 当导航到blob:或src:链接时,在你的编辑器中打开该文件
# 如果没有,它会尝试用$EDITOR或$VISUAL
# 如果仍然失败,它会尝试Visual Studio Code,然后是Sublime Text,然后是其他一些编辑器
# 这是由Bun.openInEditor()使用的
editor = "code"
# List of editors:
# - "subl", "sublime"
# - "vscode", "code"
# - "textmate", "mate"
# - "idea"
# - "webstorm"
# - "nvim", "neovim"
# - "vim","vi"
# - "emacs"
# - "atom"
</code></pre>
<h2 id="使用">使用</h2>
<p>首先我们下载 cli</p>
<p>在终端执行如下指令即可进行下载:</p>
<pre><code>curl https://bun.sh/install | bash
</code></pre>
<h3 id="启用服务">启用服务</h3>
<p>先尝试实现类似于 node 的相关功能:</p>
<p>新建文件 http.js</p>
<pre><code class="language-js">export default {
port: 3000,
fetch(request) {
return new Response("Welcome to Bun!");
},
};
</code></pre>
<p>之后在终端执行:</p>
<pre><code class="language-shell">bun run http.js
</code></pre>
<p>之后打开浏览器地址 <code>http://localhost:3000/</code> 即可查看到对应页面的返回 <code>Welcome to Bun!</code></p>
<p>如果运行中有错误处理, 可以这样判断:</p>
<pre><code class="language-js">export default {
fetch(req) {
// if(...)
throw new Error("woops!");
},
error(error: Error) {
// 类似与 catch 到fetch 抛出的错误
return new Response("Uh oh!!\n" + error.toString(), { status: 500 });
},
}
</code></pre>
<h3 id="创建项目">创建项目</h3>
<p>我们先尝试使用它默认的 react 模板项目来创建:</p>
<pre><code class="language-shell">bun create react ./app
</code></pre>
<p>运行指令之后的终端部分输出:</p>
<p><img src="https://img2022.cnblogs.com/blog/1182844/202207/1182844-20220730020458196-827166658.png" alt="" loading="lazy"></p>
<p>之后便出现如下目录:</p>
<p><img src="https://img2022.cnblogs.com/blog/1182844/202207/1182844-20220730020506247-1290634747.png" alt="" loading="lazy"></p>
<p>在项目中, 通过指令 <code>bun dev</code> 即可运行</p>
<p>这就是他的官方 react 项目模板, 当然他还可以扩展:</p>
<pre><code class="language-shell">bun create github-user/repo-name destination
bun create local-example-or-remote-example destination
bun create /absolute/path/to-template-folder destination
bun create https://github.com/github-user/repo-name destination
bun create github.com/github-user/repo-name destination
</code></pre>
<p>通过初始化本地路径, github 地址, gitlab 地址来初始化项目</p>
<h3 id="bun-create-工作流程">bun create 工作流程</h3>
<p>当我们运行 <code>bun create ${template} ${destination}</code> 的时候会出现以下判断</p>
<ol>
<li>判断远程模板
<ol>
<li>请求 <code>registry.npmjs.org</code> 相关路径, 下载tgz</li>
<li>解压缩, 提取文件</li>
</ol>
</li>
<li>如果是 GitHub
<ol>
<li>通过 GitHub API 下载</li>
<li>解析并提取文件</li>
</ol>
</li>
<li>如果是本地模板
<ol>
<li>打开本地文件夹</li>
<li>清空已有名称的文件</li>
<li>递归复制文件</li>
<li>解析 package, 执行 hook, 下载依赖, 初始化 git</li>
</ol>
</li>
</ol>
<h3 id="包管理">包管理</h3>
<p>bun 有他自己的包公里工具: <code>bun install</code>, 可以在 <code>bunfig.toml</code>配置文件中对其进行 <code>registry</code>, <code>dev</code>, <code>cache</code> 等配置</p>
<p><code>bun install</code> 对等依赖的处理方式与 <code>yarn</code> 类似。不会自动安装对等依赖,会尝试选择一个现有的依赖。</p>
<h3 id="lock-文件">lock 文件</h3>
<p><code>bun.lockb</code> 是 <code>bun</code> 的二进制 lock 文件格式, 至于为什么选择二进制, 直接的原因就是为了性能, 和更多的存储</p>
<h4 id="快速的原因">快速的原因</h4>
<p>它对所有数据使用线性数组。包是由一个自动递增的整数 ID 或者包名的哈希值引用的。超过8个字符的字符串会被去掉。<br>
在保存在磁盘之前,lock 文件通过 garbage collection (GC)和遍历包的树形结构确定顺序 ,再按依赖关系下载包。</p>
<h3 id="脚本运行器">脚本运行器</h3>
<p><code>bun run</code>是一个快速的 <code>package.json</code> 脚本运行器</p>
<p><code>bun run ${script-name}</code> 运行相当于 <code>npm run script-name</code> 的内容。例如,<code>bun run dev</code> 运行 <code>package.json</code> 中的 <code>dev</code> 脚本。</p>
<p>bun 运行会自动从 <code>.env</code> 中加载环境变量到 <code>shell/task</code> 中。<code>.env </code>文件的加载优先级与 <code>bun</code> 的其他部分相同:</p>
<ol>
<li>.env.local 最先加载</li>
<li>if ($NODE_ENV === "production") .env.production else .env.development</li>
<li>.env</li>
</ol>
<p>如果有什么问题,你可以运行 <code>bun run env</code> 来得到一个环境变量的列表。</p>
<h2 id="问题">问题</h2>
<p>目前存在的问题</p>
<h3 id="zig-的问题">Zig 的问题</h3>
<p>Zig 是一个较新(2016 年)的语言, 他的生态,安全性值得考虑</p>
<p>同时如果底层出现什么问题, 会这门语言的人是非常少的, 就很容易卡主, 过于被动</p>
<h3 id="issue-的问题">Issue 的问题</h3>
<p>目前存在了 284 个 Issue(2022.07.27), 有一些是特别重要且影响性能的</p>
<h3 id="生态问题">生态问题</h3>
<p>很多常用的, 较为重要的功能还未支持, 例如:</p>
<ul>
<li>treeShaking</li>
<li>Source maps</li>
<li>Code splitting</li>
<li>CSS 压缩</li>
</ul>
<p>具体可查看 此处</p>
<h2 id="总结">总结</h2>
<p>目前来说 bun 已经拥有的功能还不能满足正常的生产需求, 我们只能在开发一些小工具的时候使用它来尝尝鲜</p>
<p>他的结构, 专门的下载器, TypeScript & JSX 的开箱即用, 内置的node API 等等目前看来是挺香的, 然后也同样地存在我上面说的一些问题</p>
<p>bun 的饼是很大很圆, 但是未来能不能真正吃上, 就一起等着看吧</p><br><br>
来源:https://www.cnblogs.com/Grewer/p/16534170.html
頁:
[1]