文件类型
Bun 的打包器和运行时支持的文件类型和加载器
Bun 打包器实现了一组默认加载器。一般来说,打包器和运行时支持相同的文件类型集合。
.js .cjs .mjs .mts .cts .ts .tsx .jsx .css .json .jsonc .json5 .toml .yaml .yml .xml .txt .text .md .markdown .wasm .node .html .sh
Bun 使用文件扩展名来选择解析文件的内置 加载器。每个加载器都有一个名称,例如 js、tsx 或 json。在构建扩展 Bun 功能的插件时,会使用这些名称。
若要显式指定加载器,请使用 type 导入属性。
import my_toml from "./my_file" with { type: "toml" };
// 或者通过动态导入
const { default: my_toml } = await import("./my_file", { with: { type: "toml" } });
内置加载器
js
JavaScript。.cjs 和 .mjs 的默认加载器。
解析代码并应用一组默认转换,例如死代码消除和树摇。Bun 不会向下转换语法。
jsx
JavaScript + JSX。.js 和 .jsx 的默认加载器。
与 js 加载器相同,但支持 JSX 语法。默认情况下,Bun 会将 JSX 向下转换为纯 JavaScript;具体行为取决于 tsconfig.json 中的 jsx* 编译器选项。请参阅 TypeScript 文档中关于 JSX 的内容。
ts
TypeScript 加载器。.ts、.mts 和 .cts 的默认加载器。
剥离所有 TypeScript 语法,然后行为与 js 加载器相同。Bun 不做类型检查。
tsx
TypeScript + JSX 加载器。.tsx 的默认加载器。将 TypeScript 和 JSX 转译为普通 JavaScript。
json
JSON 加载器。.json 的默认加载器。
JSON 文件可以直接导入。
import pkg from "./package.json";
pkg.name; // => "my-package"
打包时,Bun 会将解析后的 JSON 作为 JavaScript 对象内联到打包文件中。
var pkg = {
name: "my-package",
// ... 其他字段
};
pkg.name;
如果将 .json 文件作为入口点传递给打包器,Bun 会将其转换为 .js 模块,并通过 export default 导出解析后的对象。
{
"name": "John Doe",
"age": 35,
"email": "johndoe@example.com"
}
export default {
name: "John Doe",
age: 35,
email: "johndoe@example.com",
};
jsonc
带注释的 JSON 加载器。.jsonc 的默认加载器。
JSONC(带注释的 JSON)文件可以直接导入。Bun 会解析这些文件,并移除注释和尾随逗号。
import config from "./config.jsonc";
console.log(config);
打包时,Bun 会将解析后的 JSONC 作为 JavaScript 对象内联到打包文件中,其行为与 json 加载器相同。
var config = {
option: "value",
};
toml
TOML 加载器。.toml 的默认加载器。
TOML 文件可以直接导入。Bun 使用其快速的原生 TOML 解析器解析这些文件。
import config from "./bunfig.toml";
config.logLevel; // => "debug"
// 使用导入属性:
// import myCustomTOML from './my.config' with {type: "toml"};
打包时,Bun 会将解析后的 TOML 作为 JavaScript 对象内联到打包文件中。
var config = {
logLevel: "debug",
// ...其他字段
};
config.logLevel;
如果将 .toml 文件作为入口点传递,Bun 会将其转换为 .js 模块,并通过 export default 导出解析后的对象。
name = "John Doe"
age = 35
email = "johndoe@example.com"
export default {
name: "John Doe",
age: 35,
email: "johndoe@example.com",
};
yaml
YAML 加载器。.yaml 和 .yml 的默认加载器。
YAML 文件可以直接导入。Bun 使用其快速的原生 YAML 解析器解析这些文件。
import config from "./config.yaml";
console.log(config);
// 使用导入属性:
import data from "./data.txt" with { type: "yaml" };
打包时,Bun 会将解析后的 YAML 作为 JavaScript 对象内联到打包文件中。
var config = {
name: "my-app",
version: "1.0.0",
// ...其他字段
};
如果将 .yaml 或 .yml 文件作为入口点传递,Bun 会将其转换为 .js 模块,并通过 export default 导出解析后的对象。
name: John Doe
age: 35
email: johndoe@example.com
export default {
name: "John Doe",
age: 35,
email: "johndoe@example.com",
};
json5
JSON5 加载器。.json5 的默认加载器。
JSON5 文件可以直接导入。Bun 使用其快速的原生 JSON5 解析器解析这些文件。JSON5 是 JSON 的超集,增加了注释、尾随逗号、未加引号的键、单引号字符串等特性。
import config from "./config.json5";
console.log(config);
// 通过导入属性:
import data from "./data.txt" with { type: "json5" };
打包时,Bun 会将解析后的 JSON5 作为 JavaScript 对象内联到打包文件中。
var config = {
name: "my-app",
version: "1.0.0",
// ...其他字段
};
如果将 .json5 文件作为入口点传递,Bun 会将其转换为 .js 模块,并通过 export default 导出解析后的对象。
{
// 配置
name: "John Doe",
age: 35,
email: "johndoe@example.com",
}
export default {
name: "John Doe",
age: 35,
email: "johndoe@example.com",
};
xml
XML 加载器。.xml 的默认加载器。
XML 文件可以直接导入。Bun 使用其原生 XML 1.0 解析器,将其解析为 Bun.XML.parse 所使用的紧凑对象结构:
- 根元素对应一个键
- 属性对应
"@name"键 - 重复的子元素对应数组
- 属性或子元素旁的文本对应
"#text" - 所有值均为字符串
import doc from "./config.xml";
console.log(doc.config["@version"]);
// 通过导入属性:
import feed from "./export.rss" with { type: "xml" };
打包时,Bun 会将解析后的 XML 作为 JavaScript 对象内联到打包文件中。
var doc = {
config: {
"@version": "2",
// ...other fields
},
};
如果将 .xml 文件作为入口点传递,Bun 会将其转换为 .js 模块,并通过 export default 导出解析后的对象。
<user id="1">
<name>John Doe</name>
<email>johndoe@example.com</email>
<role>admin</role>
<role>editor</role>
</user>
export default {
user: {
"@id": "1",
name: "John Doe",
email: "johndoe@example.com",
role: ["admin", "editor"],
},
};
text
文本加载器。.txt 和 .text 的默认加载器。
文本文件可以直接导入。Bun 会读取文件,并将其作为字符串返回。
import contents from "./file.txt";
console.log(contents); // => "Hello, world!"
// 以文本形式导入 html 文件
// 可以通过 'type' 属性覆盖默认加载器。
import html from "./index.html" with { type: "text" };
构建过程中引用该文件时,Bun 会将文件内容作为字符串内联到打包文件中。
var contents = `Hello, world!`;
console.log(contents);
如果将 .txt 文件作为入口点传递,Bun 会将其转换为 .js 模块,并通过 export default 导出文件内容。
Hello, world!
export default "Hello, world!";
md
Markdown 加载器。.md 和 .markdown 的默认加载器。
Markdown 文件可以直接导入。Bun 会将文件渲染为 HTML,并将 HTML 作为字符串返回。
import html from "./README.md";
console.log(html); // => "<h1>Title</h1>\n"
// 通过导入属性(`markdown` 是 `md` 的别名):
import notes from "./notes.txt" with { type: "md" };
打包时,Bun 会将渲染后的 HTML 作为字符串内联到打包文件中。
napi
本地扩展加载器。.node 的默认加载器。
运行时可以直接导入本地扩展。
import addon from "./addon.node";
console.log(addon);
在打包器中,Bun 使用 file 加载器处理 .node 文件。
sqlite
SQLite 加载器。with { "type": "sqlite" } 导入属性。
在运行时和打包器中,可以直接导入 SQLite 数据库。Bun 使用 bun:sqlite 加载数据库。
import db from "./my.db" with { type: "sqlite" };
仅当 target 为 bun 时,才支持 sqlite 加载器。
默认情况下,数据库不会打包进包中:Bun 不会将磁盘上的数据库文件打包到最终输出中,因此你可以使用从其他位置加载的数据库。
你可以通过 "embed" 属性改变这个行为:
// 将数据库嵌入包中
import db from "./my.db" with { type: "sqlite", embed: "true" };
使用独立可执行文件时,Bun 会将数据库嵌入单文件可执行文件中。
否则,嵌入数据库会被复制到 outdir,并使用哈希后的文件名。
html
html 加载器会处理 HTML 文件并打包所有引用的资源。它:
- 打包并哈希引用的 JavaScript 文件(
<script src="...">) - 打包并哈希引用的 CSS 文件(
<link rel="stylesheet" href="...">) - 哈希引用的图像(
<img src="...">) - 保留外部 URL(默认情况下,任何以
http://或https://开头的 URL)
示例,假设有如下 HTML 文件:
<!DOCTYPE html>
<html>
<body>
<img src="./image.jpg" alt="Local image" />
<img src="https://example.com/image.jpg" alt="External image" />
<script type="module" src="./script.js"></script>
</body>
</html>
Bun 会输出一个包含已打包资源的新 HTML 文件:
<!DOCTYPE html>
<html>
<body>
<img src="./image-HASHED.jpg" alt="Local image" />
<img src="https://example.com/image.jpg" alt="External image" />
<script type="module" src="./output-ALSO-HASHED.js"></script>
</body>
</html>
该加载器使用 lol-html 将 script 和 link 标签提取为入口点,并将其他资源作为外部资源处理。
选择器列表如下:
audio[src]img[src]img[srcset]link[as='font'][href], link[type^='font/'][href]link[as='image'][href]link[as='style'][href]link[as='video'][href], link[as='audio'][href]link[as='worker'][href]link[rel='icon'][href], link[rel='apple-touch-icon'][href]link[rel='manifest'][href]link[rel='stylesheet'][href]script[src]source[src]source[srcset]video[poster]video[src]
css
CSS 加载器。.css 的默认加载器。
CSS 文件可以直接导入。这在打包 HTML时尤为有用,此时 CSS 会与 HTML 一起打包。
import "./styles.css";
导入不会返回任何值;它仅用于其副作用。
sh 加载器
Bun Shell 加载器。.sh 文件的默认加载器。
此加载器解析 Bun Shell 脚本。它仅在启动 Bun 本身时受支持,因此在打包器或运行时中不可用。
bun run ./script.sh
file
文件加载器。所有未识别文件类型的默认加载器。
文件加载器将导入解析为被导入文件的 路径/URL,通常用来引用媒体或字体资源。
import logo from "./logo.svg";
console.log(logo);
在运行时,Bun 会检查 logo.svg 文件是否存在,并将导入解析为磁盘上的绝对路径。
bun run logo.ts
/path/to/project/logo.svg
在打包器中,Bun 会将文件原样复制到 outdir,导入则解析为指向已复制文件的相对路径。
var logo = "./logo.svg";
console.log(logo);
如果设置了 publicPath,导入会使用其值作为前缀来构造绝对路径/URL。
| 公共路径 | 解析后的导入 |
|---|---|
""(默认) | ./logo.svg |
"/assets/" | /assets/logo.svg |
"https://cdn.example.com/" | https://cdn.example.com/logo.svg |
此加载器复制文件到 outdir,复制文件名由
naming.asset 的值确定。
解决 TypeScript 导入错误
如果你使用 TypeScript,可能会遇到类似错误:
// TypeScript 错误
// 无法找到模块 './logo.svg' 或其对应的类型声明。
要解决此问题,请在项目中的任意位置创建一个 *.d.ts 文件(文件名任意),内容如下:
declare module "*.svg" {
const content: string;
export default content;
}
这会告诉 TypeScript,将从 .svg 文件进行的任何默认导入视为字符串。