Bun stellt seinen internen Transpiler über die Bun.Transpiler-Klasse bereit. So erstellen Sie eine Instanz von Bun's Transpiler:
const transpiler = new Bun.Transpiler({
loader: "tsx", // "js | "jsx" | "ts" | "tsx"
});.transformSync()
Transpilieren Sie Code synchron mit der .transformSync()-Methode. Module werden nicht aufgelöst und der Code wird nicht ausgeführt. Das Ergebnis ist ein String mit einfachem JavaScript-Code.
const transpiler = new Bun.Transpiler({
loader: 'tsx',
});
const code = `
import * as whatever from "./whatever.ts"
export function Home(props: {title: string}){
return <p>{props.title}</p>;
}`;
const result = transpiler.transformSync(code);import { __require as require } from "bun:wrap";
import * as JSX from "react/jsx-dev-runtime";
var jsx = require(JSX).jsxDEV;
export default jsx(
"div",
{
children: "hi!",
},
undefined,
false,
undefined,
this,
);Um den im new Bun.Transpiler()-Konstruktor angegebenen Standard-Loader zu überschreiben, übergeben Sie ein zweites Argument an .transformSync().
transpiler.transformSync("<div>hi!</div>", "tsx");Details">
Wenn .transformSync aufgerufen wird, wird der Transpiler im gleichen Thread wie der aktuell ausgeführte Code ausgeführt.
Wenn ein Makro verwendet wird, wird es im gleichen Thread wie der Transpiler ausgeführt, jedoch in einer separaten Event-Loop vom Rest Ihrer Anwendung. Derzeit werden Globals zwischen Makros und regulärem Code geteilt, was bedeutet, dass es möglich (aber nicht empfohlen) ist, Zustände zwischen Makros und regulärem Code zu teilen. Der Versuch, AST-Knoten außerhalb eines Makros zu verwenden, ist undefiniertes Verhalten.
.transform()
Die transform()-Methode ist eine asynchrone Version von .transformSync(), die ein Promise<string> zurückgibt.
const transpiler = new Bun.Transpiler({ loader: "jsx" });
const result = await transpiler.transform("<div>hi!</div>");
console.log(result);Es sei denn, Sie transpilieren viele große Dateien, sollten Sie wahrscheinlich Bun.Transpiler.transformSync verwenden. Die Kosten des Thread-Pools sind oft höher als das eigentliche Transpilieren von Code.
await transpiler.transform("<div>hi!</div>", "tsx");Details">
Die .transform()-Methode führt den Transpiler in Bun's Worker-Thread-Pool aus. Wenn Sie sie also 100-mal ausführen, wird sie über Math.floor($cpu_count * 0.8) Threads ausgeführt, ohne den Haupt-JavaScript-Thread zu blockieren.
Wenn Ihr Code ein Makro verwendet, wird potenziell eine neue Kopie von Bun's JavaScript-Laufzeitumgebung in diesem neuen Thread erstellt.
.scan()
Die Transpiler-Instanz kann auch Quelldaten scannen und eine Liste seiner Importe und Exporte sowie zusätzliche Metadaten über jeden zurückgeben. Nur-Typ Importe und Exporte werden ignoriert.
const transpiler = new Bun.Transpiler({
loader: "tsx",
});
const code = `
import React from 'react';
import type {ReactNode} from 'react';
const val = require('./cjs.js')
import('./loader');
export const name = "hello";
`;
const result = transpiler.scan(code);{
"exports": ["name"],
"imports": [
{
"kind": "import-statement",
"path": "react"
},
{
"kind": "import-statement",
"path": "remix"
},
{
"kind": "dynamic-import",
"path": "./loader"
}
]
}Jeder Import im imports-Array hat einen path und eine kind. Bun kategorisiert Importe in die folgenden Arten:
import-statement:import React from 'react'require-call:const val = require('./cjs.js')require-resolve:require.resolve('./cjs.js')dynamic-import:import('./loader')import-rule:@import 'foo.css'url-token:url('./foo.png')
.scanImports()
Für performance-kritischen Code können Sie die .scanImports()-Methode verwenden, um eine Liste der Importe zu erhalten. Sie ist schneller als .scan() (insbesondere für große Dateien), aber aufgrund einiger Performance-Optimierungen geringfügig weniger genau.
const transpiler = new Bun.Transpiler({
loader: "tsx",
});
const code = `
import React from 'react';
import type {ReactNode} from 'react';
const val = require('./cjs.js')
import('./loader');
export const name = "hello";
`;
const result = transpiler.scanImports(code);[
{
"kind": "import-statement",
"path": "react"
},
{
"kind": "require-call",
"path": "./cjs.js"
},
{
"kind": "dynamic-import",
"path": "./loader"
}
]Referenz
type Loader = "jsx" | "js" | "ts" | "tsx";
interface TranspilerOptions {
// Schlüssel durch Wert ersetzen. Wert muss ein JSON-String sein.
// { "process.env.NODE_ENV": "\"production\"" }
define?: Record<string, string>,
// Standard-Loader für diesen Transpiler
loader?: Loader,
// Standard-Plattform als Ziel
// Dies beeinflusst, wie import und/oder require verwendet werden
target?: "browser" | "bun" | "node",
// Eine tsconfig.json-Datei als JSON-String oder Objekt angeben
// Verwenden Sie dies, um eine benutzerdefinierte JSX-Fabrik, Fragment oder Import-Quelle festzulegen
// Zum Beispiel, wenn Sie Preact anstelle von React verwenden möchten. Oder wenn Sie Emotion verwenden möchten.
tsconfig?: string | TSConfig,
// Importe durch Makros ersetzen
macro?: MacroMap,
// Eine Reihe von zu eliminierenden Exporten angeben
// Oder bestimmte Exporte umbenennen
exports?: {
eliminate?: string[];
replace?: Record<string, string>;
},
// Ob ungenutzte Importe aus der transpilierten Datei entfernt werden sollen
// Standard: false
trimUnusedImports?: boolean,
// Ob eine Reihe von JSX-Optimierungen aktiviert werden sollen
// jsxOptimizationInline ...,
// Experimentelle Leerzeichen-Minifizierung
minifyWhitespace?: boolean,
// Ob konstante Werte inline eingefügt werden sollen
// Verbessert typischerweise die Performance und verringert die Bundle-Größe
// Standard: true
inline?: boolean,
}
// Import-Pfade auf Makros abbilden
interface MacroMap {
// {
// "react-relay": {
// "graphql": "bun-macro-relay/bun-macro-relay.tsx"
// }
// }
[packagePath: string]: {
[importItemName: string]: string,
},
}
class Bun.Transpiler {
constructor(options: TranspilerOptions)
transform(code: string, loader?: Loader): Promise<string>
transformSync(code: string, loader?: Loader): string
scan(code: string): {exports: string[], imports: Import}
scanImports(code: string): Import[]
}
type Import = {
path: string,
kind:
// import foo from 'bar'; in JavaScript
| "import-statement"
// require("foo") in JavaScript
| "require-call"
// require.resolve("foo") in JavaScript
| "require-resolve"
// Dynamic import() in JavaScript
| "dynamic-import"
// @import() in CSS
| "import-rule"
// url() in CSS
| "url-token"
// Der Import wurde von Bun injiziert
| "internal"
// Einstiegspunkt (nicht häufig)
| "entry-point-build"
| "entry-point-run"
}
const transpiler = new Bun.Transpiler({ loader: "jsx" });