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");
细节
.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
。线程池的开销通常比实际转换代码的时间更长。
await transpiler.transform("<div>hi!</div>", "tsx");
细节
.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 {
// Replace key with value. Value must be a JSON string.
// { "process.env.NODE_ENV": "\"production\"" }
define?: Record<string, string>,
// Default loader for this transpiler
loader?: Loader,
// Default platform to target
// This affects how import and/or require is used
target?: "browser" | "bun" | "node",
// Specify a tsconfig.json file as stringified JSON or an object
// Use this to set a custom JSX factory, fragment, or import source
// For example, if you want to use Preact instead of React. Or if you want to use Emotion.
tsconfig?: string | TSConfig,
// Replace imports with macros
macro?: MacroMap,
// Specify a set of exports to eliminate
// Or rename certain exports
exports?: {
eliminate?: string[];
replace?: Record<string, string>;
},
// Whether to remove unused imports from transpiled file
// Default: false
trimUnusedImports?: boolean,
// Whether to enable a set of JSX optimizations
// jsxOptimizationInline ...,
// Experimental whitespace minification
minifyWhitespace?: boolean,
// Whether to inline constant values
// Typically improves performance and decreases bundle size
// Default: true
inline?: boolean,
}
// Map import paths to macros
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"
// The import was injected by Bun
| "internal"
// Entry point (not common)
| "entry-point"
}
const transpiler = new Bun.Transpiler({ loader: "jsx" });