Skip to content

El bundler de Bun implementa un conjunto de loaders predeterminados fuera de la caja. Como regla general, el bundler y el runtime soportan el mismo conjunto de tipos de archivos fuera de la caja.

.js .cjs .mjs .mts .cts .ts .tsx .jsx .css .json .jsonc .toml .yaml .yml .txt .wasm .node .html .sh

Bun usa la extensión del archivo para determinar qué loader incorporado debe usarse para analizar el archivo. Cada loader tiene un nombre, como js, tsx, o json. Estos nombres se usan al construir plugins que extienden Bun con loaders personalizados.

Puedes especificar explícitamente qué loader usar usando el atributo de importación 'type'.

ts
import my_toml from "./my_file" with { type: "toml" };
// o con importaciones dinámicas
const { default: my_toml } = await import("./my_file", { with: { type: "toml" } });

Loaders incorporados

js

JavaScript. Predeterminado para .cjs y .mjs.

Analiza el código y aplica un conjunto de transformaciones predeterminadas como eliminación de código muerto y tree shaking. Ten en cuenta que Bun no intenta convertir sintaxis hacia abajo en este momento.

jsx

JavaScript + JSX. Predeterminado para .js y .jsx.

Igual que el loader js, pero se soporta sintaxis JSX. Por defecto, JSX se convierte a JavaScript plano; los detalles de cómo se hace esto dependen de las opciones del compilador jsx* en tu tsconfig.json. Consulta la documentación de TypeScript sobre JSX para más información.

ts

Loader de TypeScript. Predeterminado para .ts, .mts, y .cts.

Elimina toda la sintaxis de TypeScript, luego se comporta idénticamente al loader js. Bun no realiza verificación de tipos.

tsx

Loader de TypeScript + JSX. Predeterminado para .tsx. Transpila tanto TypeScript como JSX a JavaScript vanilla.

json

Loader JSON. Predeterminado para .json.

Los archivos JSON se pueden importar directamente.

ts
import pkg from "./package.json";
pkg.name; // => "mi-paquete"

Durante la compilación, el JSON analizado se inserta en el bundle como un objeto de JavaScript.

ts
var pkg = {
  name: "mi-paquete",
  // ... otros campos
};
pkg.name;

Si un archivo .json se pasa como punto de entrada al bundler, se convertirá en un módulo .js que hace export default del objeto analizado.

json
{
  "name": "John Doe",
  "age": 35,
  "email": "johndoe@example.com"
}
ts
export default {
  name: "John Doe",
  age: 35,
  email: "johndoe@example.com",
};

jsonc

Loader JSON con Comentarios. Predeterminado para .jsonc.

Los archivos JSONC (JSON con Comentarios) se pueden importar directamente. Bun los analizará, eliminando comentarios y comas finales.

ts
import config from "./config.jsonc";
console.log(config);

Durante la compilación, el JSONC analizado se inserta en el bundle como un objeto de JavaScript, idéntico al loader json.

ts
var config = {
  option: "valor",
};

NOTE

Bun usa automáticamente el loader `jsonc` para archivos `tsconfig.json`, `jsconfig.json`, `package.json`, y `bun.lock`.

toml

Loader TOML. Predeterminado para .toml.

Los archivos TOML se pueden importar directamente. Bun los analizará con su rápido analizador TOML nativo.

ts
import config from "./bunfig.toml";
config.logLevel; // => "debug"

// mediante atributo de importación:
// import myCustomTOML from './my.config' with {type: "toml"};

Durante la compilación, el TOML analizado se inserta en el bundle como un objeto de JavaScript.

ts
var config = {
  logLevel: "debug",
  // ...otros campos
};
config.logLevel;

Si un archivo .toml se pasa como punto de entrada, se convertirá en un módulo .js que hace export default del objeto analizado.

toml
name = "John Doe"
age = 35
email = "johndoe@example.com"
ts
export default {
  name: "John Doe",
  age: 35,
  email: "johndoe@example.com",
};

yaml

Loader YAML. Predeterminado para .yaml y .yml.

Los archivos YAML se pueden importar directamente. Bun los analizará con su rápido analizador YAML nativo.

ts
import config from "./config.yaml";
console.log(config);

// mediante atributo de importación:
import data from "./data.txt" with { type: "yaml" };

Durante la compilación, el YAML analizado se inserta en el bundle como un objeto de JavaScript.

ts
var config = {
  name: "mi-app",
  version: "1.0.0",
  // ...otros campos
};

Si un archivo .yaml o .yml se pasa como punto de entrada, se convertirá en un módulo .js que hace export default del objeto analizado.

yaml
name: John Doe
age: 35
email: johndoe@example.com
ts
export default {
  name: "John Doe",
  age: 35,
  email: "johndoe@example.com",
};

text

Loader de texto. Predeterminado para .txt.

El contenido del archivo de texto se lee y se inserta en el bundle como una cadena. Los archivos de texto se pueden importar directamente. El archivo se lee y se devuelve como una cadena.

ts
import contents from "./file.txt";
console.log(contents); // => "¡Hola, mundo!"

// Para importar un archivo html como texto
// El atributo "type" se puede usar para anular el loader predeterminado.
import html from "./index.html" with { type: "text" };

Cuando se hace referencia durante una compilación, el contenido se inserta en el bundle como una cadena.

ts
var contents = `¡Hola, mundo!`;
console.log(contents);

Si un archivo .txt se pasa como punto de entrada, se convertirá en un módulo .js que hace export default del contenido del archivo.

txt
¡Hola, mundo!
ts
export default "¡Hola, mundo!";

napi

Loader de addon nativo. Predeterminado para .node.

En el runtime, los addons nativos se pueden importar directamente.

ts
import addon from "./addon.node";
console.log(addon);

En el bundler, los archivos .node se manejan usando el loader file.

sqlite

Loader SQLite. Atributo de importación with { "type": "sqlite" }

En el runtime y bundler, las bases de datos SQLite se pueden importar directamente. Esto cargará la base de datos usando bun:sqlite.

ts
import db from "./my.db" with { type: "sqlite" };

Esto solo se soporta cuando el target es bun.

Por defecto, la base de datos es externa al bundle (para que potencialmente puedas usar una base de datos cargada en otro lugar), por lo que el archivo de base de datos en disco no se incluirá en el bundle final.

Puedes cambiar este comportamiento con el atributo "embed":

ts
// incrustar la base de datos en el bundle
import db from "./my.db" with { type: "sqlite", embed: "true" };

Cuando usas un ejecutable independiente, la base de datos se incrusta en el ejecutable de un solo archivo.

De lo contrario, la base de datos a incrustar se copia en el outdir con un nombre de archivo con hash.

html

El loader html procesa archivos HTML y agrupa cualquier activo referenciado. Hará:

  • Agrupar y hashear archivos JavaScript referenciados (<script src="...">)
  • Agrupar y hashear archivos CSS referenciados (<link rel="stylesheet" href="...">)
  • Hashear imágenes referenciadas (<img src="...">)
  • Preservar URLs externas (por defecto, cualquier cosa que comience con http:// o https://)

Por ejemplo, dado este archivo HTML:

html
<!DOCTYPE html>
<html>
  <body>
    <img src="./image.jpg" alt="Imagen local" />
    <img src="https://example.com/image.jpg" alt="Imagen externa" />
    <script type="module" src="./script.js"></script>
  </body>
</html>

Producirá un nuevo archivo HTML con los activos agrupados:

html
<!DOCTYPE html>
<html>
  <body>
    <img src="./image-HASHED.jpg" alt="Imagen local" />
    <img src="https://example.com/image.jpg" alt="Imagen externa" />
    <script type="module" src="./output-ALSO-HASHED.js"></script>
  </body>
</html>

Bajo el capó, usa lol-html para extraer etiquetas de script y enlace como puntos de entrada, y otros activos como externos.

Actualmente, la lista de selectores es:

  • audio[src]
  • iframe[src]
  • img[src]
  • img[srcset]
  • link:not([rel~='stylesheet']):not([rel~='modulepreload']):not([rel~='manifest']):not([rel~='icon']):not([rel~='apple-touch-icon'])[href]
  • 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]

NOTE

Comportamiento del Loader HTML en Diferentes Contextos

El loader html se comporta de manera diferente dependiendo de cómo se use:

  1. Compilación Estática: Cuando ejecutas bun build ./index.html, Bun produce un sitio estático con todos los activos agrupados y hasheados.

  2. Runtime: Cuando ejecutas bun run server.ts (donde server.ts importa un archivo HTML), Bun agrupa activos sobre la marcha durante el desarrollo, habilitando características como reemplazo de módulo en caliente.

  3. Compilación Full-stack: Cuando ejecutas bun build --target=bun server.ts (donde server.ts importa un archivo HTML), la importación se resuelve a un objeto de manifiesto que Bun.serve usa para servir eficientemente activos pre-agrupados en producción.

css

Loader CSS. Predeterminado para .css.

Los archivos CSS se pueden importar directamente. Esto es principalmente útil para aplicaciones full-stack donde CSS se agrupa junto con HTML.

ts
import "./styles.css";

No hay ningún valor devuelto por la importación, solo se usa para efectos secundarios.

Loader sh

Loader Bun Shell. Predeterminado para archivos .sh

Este loader se usa para analizar scripts de Bun Shell. Solo se soporta al iniciar Bun mismo, por lo que no está disponible en el bundler o en el runtime.

sh
bun run ./script.sh

file

Loader de archivos. Predeterminado para todos los tipos de archivos no reconocidos.

El loader de archivos resuelve la importación como una ruta/URL al archivo importado. Se usa comúnmente para referenciar activos de medios o fuentes.

ts
import logo from "./logo.svg";
console.log(logo);

En el runtime, Bun verifica que el archivo logo.svg exista y lo convierte a una ruta absoluta a la ubicación de logo.svg en disco.

bash
bun run logo.ts
/ruta/al/proyecto/logo.svg

En el bundler, las cosas son ligeramente diferentes. El archivo se copia en outdir tal cual, y la importación se resuelve como una ruta relativa que apunta al archivo copiado.

ts
var logo = "./logo.svg";
console.log(logo);

Si se especifica un valor para publicPath, la importación usará ese valor como prefijo para construir una ruta/URL absoluta.

Ruta públicaImportación resuelta
"" (predeterminado)/logo.svg
"/assets"/assets/logo.svg
"https://cdn.example.com/"https://cdn.example.com/logo.svg

NOTE

La ubicación y nombre del archivo copiado está determinado por el valor de [`naming.asset`](/es/bundler#naming).
Este loader se copia en el `outdir` tal cual. El nombre del archivo copiado se determina usando el valor de `naming.asset`.

Corregir errores de importación de TypeScript

Si estás usando TypeScript, puedes obtener un error como este:

ts
// Error de TypeScript
// No se puede encontrar el módulo './logo.svg' o sus declaraciones de tipo correspondientes.

Esto se puede corregir creando un archivo *.d.ts en cualquier lugar de tu proyecto (cualquier nombre funcionará) con el siguiente contenido:

ts
declare module "*.svg" {
  const content: string;
  export default content;
}

Esto le dice a TypeScript que cualquier importación predeterminada desde .svg debe tratarse como una cadena.

Bun por www.bunjs.com.cn editar