Bun

什么是 Bun?

Bun 是一个用于 JavaScript 和 TypeScript 应用的一体化工具包。它作为一个单独的可执行文件发布,名为 bun。

Bun 的核心是Bun运行时,它是一个快速的 JavaScript 运行时,旨在取代 Node.js。它是用 Zig 语言编写的,并在底层由 JavaScriptCore 提供支持,大大减少了启动时间和内存使用。

bun run index.tsx   # TS and JSX supported out of the box

bun 命令行工具还实现了测试运行器、脚本运行器和与Node.js兼容的包管理器。相比现有的工具,它更快,并且可以在现有的 Node.js 项目中使用,几乎不需要任何修改。

bun run start                 # run the `start` script
bun install <pkg>             # install a package
bun build ./index.tsx         # bundle a project for browsers
bun test                      # run tests
bunx cowsay "Hello, world!"   # execute a package

什么是运行时

JavaScript(或者更正式地说,ECMAScript)只是一种编程语言的规范。任何人都可以编写一个JavaScript引擎来获取有效的 JavaScript 程序并执行它。目前使用的两个最流行的引擎是 V8 (由Google开发) 和 JavaScriptCore (由 Apple 开发),这两个引擎都是开源的。

Browsers

大多数 JavaScript 程序都不是在孤立的环境中运行的,它们需要与外部世界进行交互以执行有用的任务。这就是运行时的作用所在。运行时提供了额外的API,供JavaScript程序使用。需要注意的是,浏览器提供的JavaScript运行时实现了一组特定于Web的API,这些API通过全局窗口对象进行公开。任何在浏览器中执行的JavaScript代码都可以使用这些API来实现与当前网页上下文的交互或动态行为。

Node.js

类似地,Node.js 是一个在非浏览器环境(如服务器)中使用的 JavaScript 运行时。通过 Node.js 执行的 JavaScript 程序可以访问一组特定于 Node.js 的全局变量,例如 Buffer、process 和 __dirname,以及用于执行操作系统级任务的内置模块,例如读写文件(node:fs)和网络(node:net、node:http)。此外,Node.js 还实现了一个基于 CommonJS 的模块系统和解析算法,早于 JavaScript 的原生模块系统。

Bun 设计的初衷是成为更快、更精简、更现代的 Node.js 替代品。

Bun 的一些特性

  • 速度  -  目前,Bun进程的启动速度比 Node.js 快4倍

  • TypeScript 和 JSX支持  -  你可以直接执行 jsx、ts 和 tsx文件,Bun 的转译器在执行之前将这些转换为普通 JavaScript。

  • ESM 和 CommonJS 兼容性  -  世界正在转向ES模块 (ESM),但 npm 上的数百万包仍然需要 CommonJS。Bun 推荐 ES 模块,但支持 CommonJS。

  • web 标准 api  -  Bun实现了标准的 Web api,如 fetch、WebSocket 和 ReadableStream。Bun 由苹果为 Safari 开发的 JavaScriptCore 引擎提供支持,因此 header 和 URL 等一些 api 直接使用了 Safari 的实现。

  • node.js兼容性  -  除了支持 node 风格的模块解析,Bun 完全兼容内置的 Node.js 全局变量 (process, Buffer) 和模块 (path, fs, http等) 等相关工作正在进行中。

Bun 不仅仅是一个运行时。长期目标是成为一个内聚的基础设施工具包,用于使用 JavaScript / TypeScript 构建应用程序,包括包管理器、转译器、打包器、脚本运行器、测试运行器等等。

#上手入门

使用内置的 Bun 编写一个简单的HTTP服务器。服务API。首先,创建一个新目录。

mkdir quickstart
cd quickstart

运行 bun init 来构建一个新项目。在 enter point 时会自动匹配 js 或 ts 来对应生成配置文件。

bun init
bun init helps you get started with a minimal project and tries to
# guess sensible defaults. Press ^C anytime to quit.

# package name (quickstart):
# entry point (index.ts):

# Done! A package.json file was saved in the current directory.
# + index.ts
# + .gitignore
# + tsconfig.json (for editor auto-complete)
# + README.md

# To get started, run:
# bun run index.ts

打开 index.ts ,敲一个 http server。

const server = Bun.serve({
  port: 3000,
  fetch(req) {
    return new Response(`Bun!`);
  },
});

console.log(`Listening on http://localhost:${server.port}...`);

接着启动它。

bun index.ts

和 node.js 一样,非常简单。

支持 JSX 、TSX、Text、JSON、TOML

Bun 本身就支持开箱即用的 TypeScript。所有文件在执行之前都由 Bun 的快速本机转译器动态编译。与其他构建工具类似,Bun 不执行类型检查,它只是从文件中删除类型注释。

bun index.js
bun index.jsx
bun index.ts
bun index.tsx

JSX

react.tsx

function Component(props: {message: string}) {
  return (
    <body>
      <h1 style={
    
    {color: 'red'}}>{props.message}</h1>
    </body>
  );
}

console.log(<Component message="Hello world!" />);

Bun 为 JSX 实现了特殊的日志记录,使调试更容易。

bun run react.tsx
// => <Component message="Hello world!" />

是的,终于可以单独调试某个组件了。

Text

import text from "./text.txt";

console.log(text);
// => "Hello world!"

JSON 和 TOML

JSON 和 TOML文件可以直接从源文件导入,没什么区别。

import pkg from "./package.json";
import data from "./data.toml";

WASM

从 v0.5.2开始,对WASI (WebAssembly 系统接口)的实验性支持。

自定义 Loader

对于上面没提到的一些文件类型,Bun 支持 plugins 的形式对其进行扩展。

Bun 打包工具

性能

使用内置的 bun .build() 函数或bun build CLI命令来构建前端应用。

Bun.build({
  entrypoints: ['./src/index.tsx'],
  outdir: './build',
  minify: true,
  // additional config
});
b4cd1183d0264c7489f0dc9b8d230658.png

打包 10 个 three.js 副本,包含 sourcemaps 和 minification


在基准测试中(来源于 esbuild 的 three.js 基准测试),Bun 比 esbuild 快 1.75 倍,比 Parcel 2 快 150 倍,比 Rollup Terser 快 180 倍,比 Webpack 快 220 倍。

API

bun 的目标是实现一个最小的功能集,它快速、稳定,并在不牺牲性能的情况下适应大多数现代用例,API 如下:

interface Bun {
  build(options: BuildOptions): Promise<BuildOutput>;
}

interface BuildOptions {
  entrypoints: string[]; // required
  outdir?: string; // default: no write (in-memory only)
  target?: "browser" | "bun" | "node"; // "browser"
  format?: "esm"; // later: "cjs" | "iife"
  splitting?: boolean; // default false
  plugins?: BunPlugin[]; // [] // see https://bun.sh/docs/bundler/plugins
  loader?: { [k in string]: string }; // see https://bun.sh/docs/bundler/loaders
  external?: string[]; // default []
  sourcemap?: "none" | "inline" | "external"; // default "none"
  root?: string; // default: computed from entrypoints
  publicPath?: string; // e.g. http://mydomain.com/
  naming?:
    | string // equivalent to naming.entry
    | { entry?: string; chunk?: string; asset?: string };
  minify?:
    | boolean // default false
    | { identifiers?: boolean; whitespace?: boolean; syntax?: boolean };
}

引用 Jarred Sumner 的原话,“其他打包工具在追求功能完整性的过程中做出了糟糕的架构决策,最终导致性能受损,这是我们小心翼翼地试图避免的错误”。

模块系统

目前支持 ES、Common,推荐使用 ES,未来将会添加其他。

文件类型

目前支持以下文件类型:.js .jsx .ts .tsx - JavaScript and TypeScript files. Duh..txt — Plain text files. These are inlined as strings..json .toml — These are parsed at compile time and inlined as JSON.


其他一切都被视为静态资源。静态资源被原样复制到 outdir 中,导入被替换为文件的相对路径或URL,例如 /images/logo.png。

input:

import logo from "./images/logo.png";

output:

var logo = "./images/logo.png";

Plugins

与运行时本身一样,打包器被设计为可以通过插件进行扩展。事实上,运行时插件和打包器插件之间没有任何区别。

import YamlPlugin from "bun-plugin-yaml";

const plugin = YamlPlugin();

// register a runtime plugin
Bun.plugin(plugin);

// register a bundler plugin
Bun.build({
  entrypoints: ["./src/index.ts"],
  plugins: [plugin],
});

还有一些现代打包工具的“标配”, 例如 Tree shaking、Source maps 等,Bun 也是支持的。

最后,篇幅有限,其他方面就不在过多介绍了,感兴趣的小伙伴,可以自行查阅官网。

官网:https://bun.sh/

猜你喜欢

转载自blog.csdn.net/qiwoo_weekly/article/details/131650909
Bun