*(本人github:https://github.com/MichealWayne、博客地址:https://blog.michealwayne.cn/)

在 2020 年起,大家都在谈论 js 的未来发展,其中本人印象最为深刻的就是“js 三时代”一论。大致表达意思是只每隔 10 年,js 就会发生一次变化,而我们正处于 js 第三个时代——整合工具层时期。在 js runtime 这块比较典型的就是Deno,它试图将执行测试、格式化、linting 和捆绑等任务的常用工具合并到一个二进制文件中,使用 TypeScript,甚至包括一个标准库。Rome采取了不同的策略,将所有这些层折叠在 Node.js 之上。

js 第三时代工具的特点:

  • 更快
  • ESM 优先
  • 折叠层(一个工具做好很多事情,而不是很多工具做好一件事)
  • Typesafe-er(以强类型语言为核心构建,并以零配置支持用户代码中的 TS)
  • Secure-er(来自依赖攻击,或宽松的权限)
  • 多语种
  • Neo-Isomorphic(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 进行访问。

TypeScript 使用

在 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 :指定各类文件的解析器;

支持情况

  • Web API 支持:对 fetch、WebSocket、 ReadableStream 等 API 都提供了内置支持;
  • Node.js 模块:Bun 实现了 Node.js 的模块解析算法,,以便我们可以在 Bun 中使用 npm 包,同时支持 ESM 和 CommonJS,但 Bun 内部使用 ESM;
  • Bun.js 实现了大部分 Node-API (N-API),大部分 Node.js 原生模块及全局变量(比如 Buffer 和 process)都可以正常工作;
  • 自动加载环境变量 .env 文件,不需要再 require(“dotenv”).load();
  • 附带一个内置的快速 SQLite3 户端 bun:sqlite;
  • 内置 JavaScript、TypeScript、JSX 等(见下表)各种转译器;
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 生态实现了良好兼容:

  • 内置了 fetch、WebSocket、ReadableStream 等 Web API;
  • 实现了 Node.js 核心模块(比如 fs、path、Buffer 等)及全局变量(比如 process);
  • 实现了 Node.js 的模块解析算法,以便我们可以在 Bun 中使用 npm 包;
  • 支持 ESM 和 CommonJS(Bun 内部默认使用 ESM)。

有多快

Bun 的主要优势就是快,那么它快在哪里?

官方对比数据

首先是 React 的服务器端渲染速度(每秒的 HTTP 请求数):

加载一个大型数据表:每秒平均查询次数:

FFI:每秒操作数:

按作者推特上的测试:

还有一篇文章中的多项测试(要翻墙):
https://betterprogramming.pub/is-bun-the-next-big-thing-after-webpack-d683441f77b9

与 npm 对比:

与 babel 对比:

与 webpack 对比:

与 vite、swc 对比:

我们可以用 bun 的一些 demo 自行验证:https://github.com/oven-sh/bun/tree/main/examples

按官方的对比数据,Bun 可以说在性能方面是碾压 Node.js 和 Deno。

为什么快

1.js 引擎差异

不同于 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。

2.开发语言差异

Bun.js 使用的是新兴的系统编程语言 ZIG 编写的,ZIG 一般用于嵌入式和系统级编程,使用 ZIG 主要通过手动内存管理对内存进行更细粒度的控制、无隐藏的控制流来提升程序的性能。

Zig 是一门系统级编程语言,专为稳定性、可维护性和性能而设计,是追求替代 C 语言在系统编程上的最佳地位。

其中 C++的代码大部分是 web API 的实现(Safari)

3.独立实现工具

在前两点的前提下,作者重新实现了诸如 JSX/TypeScript 转编器、npm 客户端、SQLite 客户端、HTTP 客户端、WebSocket 客户端等类库。

使用评估

优势

  • 性能。主要亮点、核心竞争力。至少短期 Node/Deno 是难以超越 Bun;
  • 效率。集成各类工具,能大幅提高开发效率,这也是 js 第三阶段产物的典型特征。

劣势

  • 是起步项目,目前存在内存泄露等问题,连作者也不建议在生产使用;
  • 是个人项目,目前仍有 200+个 issue 待解决
  • 部分 npm 包不兼容

其他

  • 版本较新,最新版本才 v0.1.4;

  • star 快速上升,目前 26.2k(至 2022.07.17)。油管上也有多了许多讲解视频;

  • 社区维护:https://bun.sh/discord

  • 里程碑:https://github.com/oven-sh/bun/issues/159

综上,Bun 是一个有前景的项目,高效的性能能拓宽 js 的应用边界,但是目前项目仍处理起步阶段,整体并不成熟。因此我们目前不能在业务生产中直接使用 Bun,但我们可以尝试试用 Bun 并对 Bun 保持高度关注。


相关链接

  • 《The Third Age of JavaScript》https://www.swyx.io/js-third-age/
  • 《Windows 下安装 Bun》https://juejin.cn/post/7119006461576871973
  • 《Is Bun the Next Big Thing After Webpack?》https://betterprogramming.pub/is-bun-the-next-big-thing-after-webpack-d683441f77b9

越来越快的jsRuntime——Bun相关推荐

  1. setInterval和setTimeout的区别以及setInterval越来越快问题的解决方法

    setInterval和setTimeout的区别以及setInterval越来越快问题的解决方法 参考文章: (1)setInterval和setTimeout的区别以及setInterval越来越 ...

  2. js中按钮去触发定时器,那么多次点击这个定时器会越来越快,解决方法

    并不是越来越快, 而是越来越多; $('button:first').click(function(){ // 记录ID var timerId = setInterval(function(){ c ...

  3. 计算机cpu的速度越来越快 这导致,计算机一级笔试模拟题(1-6)

    计算机一级笔试模拟题(1-6) <计算机知识及应用初步>笔试模拟题(一) (考试时间60分钟) 班级 学号 姓名 说明: ① 本试卷全部为选择题,每题可供选择的答案中,只有一个正确答案. ...

  4. javascript中setInterval越来越快的问题解决方法

    setInterval越来越快,经过一番测试,找到一种方法,就是每次执行都要清空计时,再次重新调用. var timer function do(){//clearInterval要放在方法开始,不然 ...

  5. 搭上Python号小火箭,程序运行越来越快!

    点击上方 "程序员小乐"关注, 星标或置顶一起成长 每天凌晨00点00分, 第一时间与你相约 每日英文 Some memories, are doomed to be unable ...

  6. 知识更新越来越快,但是学习起来越来越困

    这里是Z哥的个人公众号 每周五11:45 按时送达 当然了,也会时不时加个餐- 我的第「140」篇原创敬上 大家好,我是Z哥,先祝大家节日快乐.不知道这个假期你打算出门吗?Z哥我是打算不出远门了,怕死 ...

  7. 小米手机电量消耗越来越快了,输入这几个数字,续航强劲如新机

    秉承为发烧而生的小米手机,自上市依赖便博得了众多用户的眼球,满足了数码发烧友的基本需求,但也出现了安卓手机最常见的问题,越用电量消耗越快. 很多小伙伴都怀疑是电池出现了问题,但是又无法判断,其实很简单 ...

  8. 小米八android耗电比例很大,小米手机电量消耗越来越快了,输入这几个数字,续航强劲如新机...

    秉承为发烧而生的小米手机,自上市依赖便博得了众多用户的眼球,满足了数码发烧友的基本需求,但也出现了安卓手机最常见的问题,越用电量消耗越快. 很多小伙伴都怀疑是电池出现了问题,但是又无法判断,其实很简单 ...

  9. 定时器执行速度越来越快

    执行定时器前先清除!! 每个 setTimeout 产生的任务会直接 push 到任务队列中:而 setInterval 在每次把任务 push 到任务队列前,都要进行一下判断(看上次的任务是否仍在队 ...

最新文章

  1. FM:代谢无机硫化合物的古菌Ferroplasma可介导细胞外电子传递
  2. table row设置cell的html,css中display设置为table、table-row、table-cell后的作用及其注意点...
  3. 【渝粤教育】国家开放大学2019年春季 2732土地利用规划 参考试题
  4. idea中每次push/pull都需要输入账号密码
  5. Django web开发笔记
  6. (LINQ 学习系列)(6)Linq教程实例: 使用自写类代码来访问数据
  7. 读书节第二日丨数据大咖来荐读,互动荐书赢好礼!
  8. 095 issubclass和isinstance
  9. 计算机键盘fn,笔记本键盘fn键有什么用 笔记本键盘fn键使用说明大全
  10. 七夕到了 —— 属于 Java 的浪漫,拿去吧~ 祝表白成功
  11. ThinkAdmin基本操作
  12. 华硕飞行堡垒键盘背光灯无法显示怎么办?
  13. TTS语音播报模块UNV6288的使用方法
  14. 分享一个600块钱的Python私活单,金融Excel数据清洗
  15. 中国工业互联网行业发展预测及行业趋势调研报告2022-2028年版
  16. 老板让我做研发负责人,谈谈我的想法和认知
  17. 第 9 章 Part / Chapter / Section
  18. Android 11省电模式开启
  19. Elasticsearch实战-实现Hotel索引库的自动补全、拼音搜索功能
  20. Nginx解决端口问题

热门文章

  1. android rom 制作工具,ROM工具箱(ROM Toolbox Pro)
  2. 云漫圈 | 什么是DNS?什么是DNS污染?什么又是DNS劫持?
  3. 新手小白入门编程第3讲 JAVA入门案例
  4. php 多核cpu,paip.提升性能--多核cpu中的java/.net/php/c++编程
  5. 武林外传之同福奇缘 【安卓游戏】
  6. 前端实现文件在线预览
  7. php跳转到qq界面,PHP实现QQ登录的开原理和实现过程
  8. CSS DIV 滚动(CSS,HTML)
  9. c语言让程序等待鼠标点击,C语言模拟鼠标事件
  10. 深度学习推荐系统_深度推荐系统