*(本人github:https://github.com/MichealWayne、博客地址:https://blog.michealwayne.cn/)
在 2020 年起,大家都在谈论 js 的未来发展,其中本人印象最为深刻的就是“js 三时代”一论。大致表达意思是只每隔 10 年,js 就会发生一次变化,而我们正处于 js 第三个时代——整合工具层时期。在 js runtime 这块比较典型的就是Deno,它试图将执行测试、格式化、linting 和捆绑等任务的常用工具合并到一个二进制文件中,使用 TypeScript,甚至包括一个标准库。Rome采取了不同的策略,将所有这些层折叠在 Node.js 之上。
js 第三时代工具的特点:
所有这些的结果是更好的开发人员体验(更快地构建,标准化行业工具)和用户体验(更小的 bundle 包、更快的功能交付)。它是 js 从站点脚本语言到完整应用平台的最终蜕变。
而本文介绍的也是第三阶段演进中近期快速发展的整合 Runtime ——Bun。
Bun——Incredibly fast JavaScript runtime, bundler, transpiler and package manager – all in one. 官网:https://bun.sh/;Bun Github:https://github.com/oven-sh/bun
Bun 是采用 Zig 语言编写的高性能“全家桶” js runtime,官方称其为“all-in-one JavaScript runtime”,它原生(作者自己手撸)实现了数百个 Node.js 和 Web API,包括约 90% 的 node API 函数、fs、path、Buffer 等,并且 Bun 也可以直接运行 TypeScript 文件。
作者 Jarred Sumner,据说因为肝代码而天天都吃包子,所以取名叫 Bun。
支持系统:macOS x64、Silicon、Linux x64、Windows Subsystem for Linux(WSL)
curl https://bun.sh/install | bash
(目前2022.07最新版本 v0.1.4 beta)
*注意 Windows 系统不能像装 Nodejs 一样直接程序安装,Windows 的安装使用可以参照https://juejin.cn/post/7119006461576871973
安装后可以写一个 demo(如官方 http server demo):
// http.js
export default {
port: 3000,
fetch(request) {
return new Response('Welcome to Bun!');
},
};
然后执行:
bun run http.js
然后可以通过 http://localhost:3000
进行访问。
在 Bun 中,天然支持运行运行 TypeScript,无需配置,无需额外安装;
如果你导入一个.ts
或.tsx
文件,Bun 会将它转换成 js。注意 Bun 还会编译node_modules
中的.ts
或.tsx
文件;这是由 Bun 内置了 TypeScript 转译器,且速度很快。
如果你想在全局使用对应的 API,安装 bun-typs 到你的项目即可:
1.安装
bun add -d bun-types
2.在tsconfig.json
中使用
{
"compilerOptions": {
"types": ["bun-types"]
}
}
Bun 目前处于初创和快速迭代器,使用建议看 github 文档(https://github.com/oven-sh/bun#using-bunjs—a-new-javascript-runtime-environment)
与 npm 比较类似:
bun run
:执行 js/ts 脚本,可以执行 package.json 中的 “scripts” 脚本,而且官方说比 npm run 快 30 倍;bun install
:安装模块。官方说 bun install 使用最快的系统调用来复制文件,官方说比 yarn 快 20 倍;
bun remove
:删除一个模块;bun add
:增加安装一个模块;bun create
:创建一个模板项目,如bun create react ./bun-react-demo
创建一个名为 bun-react-demo 的 react 项目bun wiptest
:进行测试,一个类似于 Jest 的测试运行器,用于内置到 bun 的 JavaScript 和 TypeScript 项目。bun upgrade
:升级 bun。bunfig.toml
bunfig.toml
是 bun 的配置文件。
通过配置文件我们可以在 bunfig.toml
加载配置,而不是每次都将参数传递给命令行。在解析命令行参数之前加载配置文件,这意味着命令行参数可以覆盖这个配置。
如官方案例(https://github.com/oven-sh/bun#bunfigtoml):
# Set a default framework to use
# By default, bun will look for an npm package like `bun-framework-${framework}`, followed by `${framework}`
framework = "next"
logLevel = "debug"
# publicDir = "public"
# external = ["jquery"]
[macros]
# Remap any import like this:
# import {graphql} from 'react-relay';
# To:
# import {graphql} from 'macro:bun-macro-relay';
react-relay = { "graphql" = "bun-macro-relay" }
[bundle]
saveTo = "node_modules.bun"
# Don't need this if `framework` is set, but showing it here as an example anyway
entryPoints = ["./app/index.ts"]
[bundle.packages]
# If you're bundling packages that do not actually live in a `node_modules` folder or do not have the full package name in the file path, you can pass this to bundle them anyway
"@bigapp/design-system" = true
[dev]
# Change the default port from 3000 to 5000
# Also inherited by Bun.serve
port = 5000
[define]
# Replace any usage of "process.env.bagel" with the string `lox`.
# The values are parsed as JSON, except single-quoted strings are supported and `'undefined'` becomes `undefined` in JS.
# This will probably change in a future release to be just regular TOML instead. It is a holdover from the CLI argument parsing.
"process.env.bagel" = "'lox'"
[loaders]
# When loading a .bagel file, run the JS parser
".bagel" = "js"
[debug]
# When navigating to a blob: or src: link, open the file in your editor
# If not, it tries $EDITOR or $VISUAL
# If that still fails, it will try Visual Studio Code, then Sublime Text, then a few others
# This is used by Bun.openInEditor()
editor = "code"
# List of editors:
# - "subl", "sublime"
# - "vscode", "code"
# - "textmate", "mate"
# - "idea"
# - "webstorm"
# - "nvim", "neovim"
# - "vim","vi"
# - "emacs"
# - "atom"
# If you pass it a file path, it will open with the file path instead
# It will recognize non-GUI editors, but I don't think it will work yet
其中属性解释:
framework
:指定默认使用的 framework 版本,bun 将根据 bun-framework-${framework}
格式找寻找 npm 包;logLevel
:指定 log 级别(可用值 error 、 warn 、 info 和 debug );publicDir
:指定 public 目录;external
:指定外部扩展,作用等同于 Webpack 的 externals;macros
:宏定义,用于替换 import 路径,比如:import { graphql } from 'react-relay'; 将被转换为 import { graphql } from "macro:bun-macro-relay/bun-macro-relay.tsx";
dev.port
:指定服务的监听端口(默认 3000 );define
:作用等同于 Webpack 的 DefinePlugin;loaders
:指定各类文件的解析器;Input | Loader | Output |
---|---|---|
.js |
JSX + JavaScript | .js |
.jsx |
JSX + JavaScript | .js |
.ts |
TypeScript + JavaScript | .js |
.tsx |
TypeScript + JSX + JavaScript | .js |
.mjs |
JavaScript | .js |
.cjs |
JavaScript | .js |
.mts |
TypeScript | .js |
.cts |
TypeScript | .js |
.toml |
TOML | .js |
.css |
CSS | .css |
.env |
Env | N/A |
.* |
file | string |
Bun 对 Node.js 生态实现了良好兼容:
Bun 的主要优势就是快,那么它快在哪里?
首先是 React 的服务器端渲染速度(每秒的 HTTP 请求数):
加载一个大型数据表:每秒平均查询次数:
FFI:每秒操作数:
按作者推特上的测试:
还有一篇文章中的多项测试(要):
https://betterprogramming.pub/is-bun-the-next-big-thing-after-webpack-d683441f77b9
我们可以用 bun 的一些 demo 自行验证:https://github.com/oven-sh/bun/tree/main/examples
按官方的对比数据,Bun 可以说在性能方面是碾压 Node.js 和 Deno。
不同于 Node.js 和 Deno,Bun 并没有基于 V8 引擎,而是使用了轻量级的 JavaScriptCore 引擎,jsCore 一般用于移动端,它的执行速度往往要比 V8 等更传统引擎要快。
Bun 中一些 Web API 直接用了 Safari 的实现,如 Headers 和 URL,https://github.com/oven-sh/bun/blob/HEAD/src/bun.js/bindings/webcore/JSFetchHeaders.cpp。
Bun.js 使用的是新兴的系统编程语言 ZIG 编写的,ZIG 一般用于嵌入式和系统级编程,使用 ZIG 主要通过手动内存管理对内存进行更细粒度的控制、无隐藏的控制流来提升程序的性能。
Zig 是一门系统级编程语言,专为稳定性、可维护性和性能而设计,是追求替代 C 语言在系统编程上的最佳地位。
其中 C++的代码大部分是 web API 的实现(Safari)
在前两点的前提下,作者重新实现了诸如 JSX/TypeScript 转编器、npm 客户端、SQLite 客户端、HTTP 客户端、WebSocket 客户端等类库。
版本较新,最新版本才 v0.1.4;
star 快速上升,目前 26.2k(至 2022.07.17)。油管上也有多了许多讲解视频;
里程碑:https://github.com/oven-sh/bun/issues/159
综上,Bun 是一个有前景的项目,高效的性能能拓宽 js 的应用边界,但是目前项目仍处理起步阶段,整体并不成熟。因此我们目前不能在业务生产中直接使用 Bun,但我们可以尝试试用 Bun 并对 Bun 保持高度关注。