يعرض Bun المحول البرمجي الداخلي الخاص به عبر فئة Bun.Transpiler. لإنشاء مثيل من المحول البرمجي في Bun:
const transpiler = new Bun.Transpiler({
loader: "tsx", // "js | "jsx" | "ts" | "tsx"
});.transformSync()
حوّل الكود بشكل متزامن مع طريقة .transformSync(). لا يتم حل الوحدات النمطية ولا يتم تنفيذ الكود. النتيجة هي سلسلة من كود JavaScript العادي.
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,
);لتجاوز المحمل الافتراضي المحدد في منشئ new Bun.Transpiler()، مرر الوسيطة الثانية إلى .transformSync().
transpiler.transformSync("<div>hi!</div>", "tsx");التفاصيل الدقيقة">
عند استدعاء .transformSync، يتم تشغيل المحول البرمجي في نفس السلسلة مثل الكود الذي يتم تنفيذه حاليًا.
إذا تم استخدام ماكرو، فسيتم تشغيله في نفس السلسلة مثل المحول البرمجي، لكن في حلقة أحداث منفصلة عن بقية تطبيقك. حاليًا، يتم مشاركة globals بين الماكرو والكود العادي، مما يعني أنه من الممكن (لكن غير موصى به) مشاركة الحالات بين الماكرو والكود العادي. محاولة استخدام عقد AST خارج الماكرو هي سلوك غير محدد.
.transform()
طريقة transform() هي نسخة غير متزامنة من .transformSync() ترجع Promise<string>.
const transpiler = new Bun.Transpiler({ loader: "jsx" });
const result = await transpiler.transform("<div>hi!</div>");
console.log(result);ما لم تكن تحول العديد من الملفات الكبيرة، يجب عليك استخدام Bun.Transpiler.transformSync. تكلفة threadpool غالبًا ما تستغرق وقتًا أطول من تحويل الكود فعليًا.
await transpiler.transform("<div>hi!</div>", "tsx");التفاصيل الدقيقة">
تعمل طريقة .transform() المحول البرمجي في threadpool العامل في Bun، لذا إذا قمت بتشغيله 100 مرة، فسيتم تشغيله عبر Math.floor($cpu_count * 0.8) من السلاسل، بدون حظر سلسلة JavaScript الرئيسية.
إذا كان الكود الخاص بك يستخدم ماكرو، فسيتم إنشاء نسخة جديدة من بيئة تشغيل JavaScript في Bun في تلك السلسلة الجديدة.
.scan()
يمكن لمثيل Transpiler أيضًا مسح بعض الكود المصدري وإرجاع قائمة بالواردات والصادرات، بالإضافة إلى بيانات وصفية إضافية حول كل منها. يتم تجاهل الواردات والصادرات من نوع النوع فقط.
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"
}
]
}كل وارد في مصفوفة imports له path و kind. يصنف Bun الواردات إلى الفئات التالية:
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()
للحساسية للأداء، يمكنك استخدام طريقة .scanImports() للحصول على قائمة بالواردات. إنها أسرع من .scan() (خاصة للملفات الكبيرة) لكنها أقل دقة بشكل هامشي بسبب بعض تحسينات الأداء.
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"
}
]المرجع
type Loader = "jsx" | "js" | "ts" | "tsx";
interface TranspilerOptions {
// استبدال المفتاح بالقيمة. يجب أن تكون القيمة سلسلة JSON.
// { "process.env.NODE_ENV": "\"production\"" }
define?: Record<string, string>,
// المحمل الافتراضي لهذا المحول البرمجي
loader?: Loader,
// المنصة الافتراضية المستهدفة
// يؤثر هذا على كيفية استخدام import و/أو require
target?: "browser" | "bun" | "node",
// تحديد ملف tsconfig.json كـ JSON مسلسلة أو كائن
// استخدم هذا لتعيين مصنع JSX مخصص أو fragment أو مصدر استيراد
// على سبيل المثال، إذا كنت تريد استخدام Preact بدلاً من React. أو إذا كنت تريد استخدام Emotion.
tsconfig?: string | TSConfig,
// استبدال الواردات بالماكرو
macro?: MacroMap,
// تحديد مجموعة من الصادرات لإزالتها
// أو إعادة تسمية بعض الصادرات
exports?: {
eliminate?: string[];
replace?: Record<string, string>;
},
// ما إذا كان يجب إزالة الواردات غير المستخدمة من الملف المحول
// الافتراضي: false
trimUnusedImports?: boolean,
// ما إذا كان يجب تمكين مجموعة من تحسينات JSX
// jsxOptimizationInline ...,
// تصغير المساحات البيضاء التجريبي
minifyWhitespace?: boolean,
// ما إذا كان يجب تضمين القيم الثابتة
// عادةً ما يحسن الأداء ويقلل حجم الحزمة
// الافتراضي: true
inline?: boolean,
}
// تعيين مسارات الاستيراد إلى الماكرو
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'; في JavaScript
| "import-statement"
// require("foo") في JavaScript
| "require-call"
// require.resolve("foo") في JavaScript
| "require-resolve"
// Dynamic import() في JavaScript
| "dynamic-import"
// @import() في CSS
| "import-rule"
// url() في CSS
| "url-token"
// تم حقن الاستيراد بواسطة Bun
| "internal"
// نقطة الدخول (غير شائعة)
| "entry-point-build"
| "entry-point-run"
}
const transpiler = new Bun.Transpiler({ loader: "jsx" });