Bun espone il suo transpiler interno tramite la classe Bun.Transpiler. Per creare un'istanza del transpiler di Bun:
const transpiler = new Bun.Transpiler({
loader: "tsx", // "js | "jsx" | "ts" | "tsx"
});.transformSync()
Transpila il codice sincronamente con il metodo .transformSync(). I moduli non vengono risolti e il codice non viene eseguito. Il risultato è una stringa di codice JavaScript vanilla.
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,
);Per sovrascrivere il loader predefinito specificato nel costruttore new Bun.Transpiler(), passa un secondo argomento a .transformSync().
transpiler.transformSync("<div>hi!</div>", "tsx");Dettli tecnici">
Quando viene chiamato .transformSync, il transpiler viene eseguito nello stesso thread del codice attualmente in esecuzione.
Se viene usata una macro, verrà eseguita nello stesso thread del transpiler, ma in un event loop separato dal resto della tua applicazione. Attualmente, le variabili globali tra le macro e il codice regolare sono condivise, il che significa che è possibile (ma non consigliato) condividere stati tra le macro e il codice regolare. Tentare di usare nodi AST al di fuori di una macro è un comportamento non definito.
.transform()
Il metodo transform() è una versione asincrona di .transformSync() che restituisce una Promise<string>.
const transpiler = new Bun.Transpiler({ loader: "jsx" });
const result = await transpiler.transform("<div>hi!</div>");
console.log(result);A meno che tu non stia transpilando molti file grandi, dovresti probabilmente usare Bun.Transpiler.transformSync. Il costo del threadpool spesso richiederà più tempo del tempo effettivo per transpilare il codice.
await transpiler.transform("<div>hi!</div>", "tsx");Dettli tecnici">
Il metodo .transform() esegue il transpiler nel threadpool dei worker di Bun, quindi se lo esegui 100 volte, lo eseguirà attraverso Math.floor($cpu_count * 0.8) thread, senza bloccare il thread JavaScript principale.
Se il tuo codice usa una macro, potrebbe potenzialmente spawnare una nuova copia dell'ambiente di runtime JavaScript di Bun in quel nuovo thread.
.scan()
L'istanza del Transpiler può anche scansionare del codice sorgente e restituire un lista dei suoi import ed export, oltre a metadati aggiuntivi su ciascuno. Gli import e export solo tipo vengono ignorati.
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"
}
]
}Ogni import nell'array imports ha un path e un kind. Bun categorizza gli import nei seguenti tipi:
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()
Per codice sensibile alle prestazioni, puoi usare il metodo .scanImports() per ottenere una lista degli import. È più veloce di .scan() (specialmente per file grandi) ma marginally meno preciso a causa di alcune ottimizzazioni delle prestazioni.
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"
}
]Riferimento
type Loader = "jsx" | "js" | "ts" | "tsx";
interface TranspilerOptions {
// Sostituisci key con value. Value deve essere una stringa JSON.
// { "process.env.NODE_ENV": "\"production\"" }
define?: Record<string, string>,
// Loader predefinito per questo transpiler
loader?: Loader,
// Piattaforma predefinita da targettare
// Questo influenza come import e/o require vengono usati
target?: "browser" | "bun" | "node",
// Specifica un file tsconfig.json come JSON stringificato o un oggetto
// Usalo per impostare una factory JSX personalizzata, un fragment, o un import source
// Ad esempio, se vuoi usare Preact invece di React. O se vuoi usare Emotion.
tsconfig?: string | TSConfig,
// Sostituisci import con macro
macro?: MacroMap,
// Specifica un insieme di export da eliminare
// O rinomina alcune export
exports?: {
eliminate?: string[];
replace?: Record<string, string>;
},
// Se rimuovere gli import non usati dal file transpilato
// Default: false
trimUnusedImports?: boolean,
// Se abilitare un insieme di ottimizzazioni JSX
// jsxOptimizationInline ...,
// Minificazione sperimentale degli spazi bianchi
minifyWhitespace?: boolean,
// Se inlineare valori costanti
// Tipicamente migliora le prestazioni e diminuisce la dimensione del bundle
// Default: true
inline?: boolean,
}
// Mappa percorsi import a macro
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"
// L'import è stato iniettato da Bun
| "internal"
// Entry point (non comune)
| "entry-point-build"
| "entry-point-run"
}
const transpiler = new Bun.Transpiler({ loader: "jsx" });