Bun 的新 Bundler:比 webpack 快 220 倍?( 二 )


Developer experience 开发人员体验
查看现有捆绑器的 API , 我们看到了很多改进的空间 。没有人喜欢与捆绑器配置搏斗 。Bun 的捆绑器 API 被设计为明确且不足为奇 。说到这里...
The API
该 API 目前在设计上是最小的 。我们在此初始版本中的目标是实现一个最小功能集 , 该功能集快速、稳定 , 并适应大多数现代用例 , 而不会牺牲性能 。
以下是当前存在的 API:
interface Bun {build(options: BuildOptions): Promise<BuildOutput>;}interface BuildOptions {entrypoints: string[]; // requiredoutdir?: string; // default: no write (in-memory only)target?: "browser" | "bun" | "node"; // "browser"format?: "esm"; // later: "cjs" | "iife"splitting?: boolean; // default falseplugins?: BunPlugin[]; // [] // see https://bun.sh/docs/bundler/pluginsloader?: { [k in string]: string }; // see https://bun.sh/docs/bundler/loadersexternal?: string[]; // default []sourcemap?: "none" | "inline" | "external"; // default "none"root?: string; // default: computed from entrypointspublicPath?: 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 };}
其他捆绑器在追求功能完整性时做出了糟糕的架构决策 , 最终导致性能下降;这是我们小心翼翼地试图避免的错误 。
Module systems
目前仅支持 format: "esm"。我们计划添加对其他模块系统和目标的支持 , 如 iife。如果有足够多的人问 , 我们也会添加 cjs otuput 支持(支持 CommonJS 输入 , 但不支持输出) 。
Targets
支持三个“目标”: "browser" (默认值)、 "bun" 和 "node"。
browser

  • TypeScript 和 JSX 会自动转换为原版 JavaScript 。
  • 模块在可用时使用 "browser" package.json "exports" 条件解析
  • 当在浏览器中导入某些 Node.js API 时 , Bun 会自动填充某些 Node API , 例如 node:crypto  , 类似于 Webpack 4 的行为 。Bun 自己的 API 目前被禁止导入 , 但我们将来可能会重新审视这一点 。
bun
  • Bun 和 Node.js API 受支持且保持不变 。
  • 模块使用 Bun 运行时使用的默认解析算法进行解析 。
  • 生成的捆绑包用特殊的 // @bun 杂注注释标记 , 以指示它们是由 Bun 生成的 。这向 Ban 的运行时表明 , 在执行之前不需要重新转译文件 。协同!
node
目前 , 这与 target: "bun" 相同 。将来 , 我们计划自动填充 Bun API , 例如 Bun 全局模块和 bun:* 内置模块 。
File types
捆绑器支持以下文件类型:
  • .js .jsx .ts .tsx - JavaScript 和 TypeScript 文件 。咄 。
  • .txt — 纯文本文件 。这些作为字符串内联 。
  • .json .toml — 这些在编译时解析并内联为 JSON 。

其他一切都被视为资产 。资产按原样复制到 outdir 中 , 导入将替换为文件的相对路径或 URL , 例如 /images/logo.png .
Input
Output
import logo from "./images/logo.png";console.log(logo);Plugins
与运行时本身一样 , 捆绑器被设计为可通过插件进行扩展 。事实上 , 运行时插件和捆绑器插件之间根本没有区别 。
import YamlPlugin from "bun-plugin-yaml";const plugin = YamlPlugin();// register a runtime pluginBun.plugin(plugin);// register a bundler pluginBun.build({entrypoints: ["./src/index.ts"],plugins: [plugin],});Build outputs
Bun.build 函数返回一个 Promise<BuildOutput>  , 定义为:
interface BuildOutput {outputs: BuildArtifact[];success: boolean;logs: Array<object>; // see docs for details}interface BuildArtifact extends Blob {kind: "entry-point" | "chunk" | "asset" | "sourcemap";path: string;loader: Loader;hash: string | null;sourcemap: BuildArtifact | null;}
outputs 数组包含生成生成的所有文件 。每个项目都实现 Blob 接口 。
const build = await Bun.build({/* */});for (const output of build.outputs) {output.size; // file size in bytesoutput.type; // MIME type of fileawait output.arrayBuffer(); // => ArrayBufferawait output.text(); // string}


推荐阅读