mirror of
https://github.com/oxc-project/oxc.git
synced 2026-11-04 10:29:58 +00:00
feat(transform-react): expose TypeScript transform options
Original PR: #26899 Closes #26864
This commit is contained in:
1 parent
224f4ddd08
commit
8dd67a61c0
17 files changed
+342
No files matched your search
Vendored
+29
@@ -360,6 +360,12 @@ export interface TransformOptions {
|
||||
* @see <https://oxc.rs/docs/guide/usage/transformer/jsx>
|
||||
*/
|
||||
jsx?: 'preserve' | JsxOptions
|
||||
/**
|
||||
* Configure how Typescript is transformed.
|
||||
*
|
||||
* @see <https://oxc.rs/docs/guide/usage/transformer/typescript>
|
||||
*/
|
||||
typescript?: TypeScriptOptions
|
||||
/**
|
||||
* Configure React Compiler, or disable it with `false`.
|
||||
*
|
||||
@@ -397,3 +403,26 @@ export interface TransformResult {
|
||||
* removed and configured JSX transforms run afterwards.
|
||||
*/
|
||||
export declare function transformSync(filename: string, sourceText: string, options?: TransformOptions | undefined | null): TransformResult
|
||||
|
||||
/**
|
||||
* Configure how Typescript is transformed.
|
||||
*
|
||||
* @see <https://oxc.rs/docs/guide/usage/transformer/typescript>
|
||||
*/
|
||||
export interface TypeScriptOptions {
|
||||
/**
|
||||
* Inlines const enum values and removes the declaration.
|
||||
*
|
||||
* @default false
|
||||
*/
|
||||
optimizeConstEnums?: boolean
|
||||
/**
|
||||
* Inlines regular (non-const) enum member accesses when all members
|
||||
* satisfy const enum constraints (i.e., their values are statically evaluable).
|
||||
* Non-exported enum declarations are also removed when all members are
|
||||
* evaluable and no references to the enum as a runtime value exist.
|
||||
*
|
||||
* @default false
|
||||
*/
|
||||
optimizeEnums?: boolean
|
||||
}
|
||||
@@ -36,6 +36,12 @@ pub struct TransformOptions {
|
||||
#[napi(ts_type = "'preserve' | JsxOptions")]
|
||||
pub jsx: Option<Either<String, JsxOptions>>,
|
||||
|
||||
/// Configure how Typescript is transformed.
|
||||
///
|
||||
/// @see <https://oxc.rs/docs/guide/usage/transformer/typescript>
|
||||
#[napi(ts_type = "TypeScriptOptions")]
|
||||
pub typescript: Option<TypeScriptOptions>,
|
||||
|
||||
/// Configure React Compiler, or disable it with `false`.
|
||||
///
|
||||
/// @default true
|
||||
@@ -188,6 +194,26 @@ pub struct JsxOptions {
|
||||
pub refresh: Option<Either<bool, ReactRefreshOptions>>,
|
||||
}
|
||||
|
||||
/// Configure how Typescript is transformed.
|
||||
///
|
||||
/// @see <https://oxc.rs/docs/guide/usage/transformer/typescript>
|
||||
#[napi(object)]
|
||||
#[derive(Debug)]
|
||||
pub struct TypeScriptOptions {
|
||||
/// Inlines const enum values and removes the declaration.
|
||||
///
|
||||
/// @default false
|
||||
pub optimize_const_enums: Option<bool>,
|
||||
|
||||
/// Inlines regular (non-const) enum member accesses when all members
|
||||
/// satisfy const enum constraints (i.e., their values are statically evaluable).
|
||||
/// Non-exported enum declarations are also removed when all members are
|
||||
/// evaluable and no references to the enum as a runtime value exist.
|
||||
///
|
||||
/// @default false
|
||||
pub optimize_enums: Option<bool>,
|
||||
}
|
||||
|
||||
/// React Fast Refresh options.
|
||||
#[napi(object)]
|
||||
#[derive(Debug)]
|
||||
@@ -313,10 +339,16 @@ impl TransformOptions {
|
||||
Some(Either::B(options)) => oxc::transformer::JsxOptions::from(options),
|
||||
};
|
||||
|
||||
let typescript: oxc::transformer::TypeScriptOptions = match self.typescript {
|
||||
None => oxc::transformer::TypeScriptOptions::default(),
|
||||
Some(options) => oxc::transformer::TypeScriptOptions::from(options),
|
||||
};
|
||||
|
||||
Ok((
|
||||
react_compiler,
|
||||
oxc::transformer::TransformOptions {
|
||||
jsx,
|
||||
typescript,
|
||||
..oxc::transformer::TransformOptions::default()
|
||||
},
|
||||
))
|
||||
@@ -426,6 +458,19 @@ impl From<JsxOptions> for oxc::transformer::JsxOptions {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<TypeScriptOptions> for oxc::transformer::TypeScriptOptions {
|
||||
fn from(options: TypeScriptOptions) -> Self {
|
||||
let defaults = Self::default();
|
||||
Self {
|
||||
optimize_const_enums: options
|
||||
.optimize_const_enums
|
||||
.unwrap_or(defaults.optimize_const_enums),
|
||||
optimize_enums: options.optimize_enums.unwrap_or(defaults.optimize_enums),
|
||||
..defaults
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ReactRefreshOptions> for oxc::transformer::ReactRefreshOptions {
|
||||
fn from(options: ReactRefreshOptions) -> Self {
|
||||
let defaults = Self::default();
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
import { existsSync, readdirSync, readFileSync } from "node:fs";
|
||||
import { join } from "node:path";
|
||||
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
import { transformSync, type TransformOptions, type TransformResult } from "../index";
|
||||
|
||||
const fixturesDir = join(import.meta.dirname, "fixtures");
|
||||
const fixtures = readdirSync(fixturesDir).sort();
|
||||
|
||||
function render(result: TransformResult): string {
|
||||
const errors = result.errors.map((error) => `${error.severity}: ${error.message}`).join("\n");
|
||||
return `## Code\n\n${result.code}\n## Errors\n\n${errors || "(none)"}\n\n## Fatal\n\n${result.fatal}\n`;
|
||||
}
|
||||
|
||||
describe("fixtures", () => {
|
||||
it.each(fixtures)("%s", async (name) => {
|
||||
const dir = join(fixturesDir, name);
|
||||
const input = readdirSync(dir).find((file) => file.startsWith("input."));
|
||||
if (input === undefined) throw new Error(`${name} has no input file`);
|
||||
const optionsPath = join(dir, "options.json");
|
||||
const options: TransformOptions = existsSync(optionsPath)
|
||||
? JSON.parse(readFileSync(optionsPath, "utf8"))
|
||||
: {};
|
||||
const result = transformSync(input, readFileSync(join(dir, input), "utf8"), options);
|
||||
await expect(render(result)).toMatchFileSnapshot(join(dir, "output.snap"));
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,16 @@
|
||||
enum Direction {
|
||||
Up = 1,
|
||||
Down = 2,
|
||||
}
|
||||
|
||||
const enum Status {
|
||||
Active = "active",
|
||||
}
|
||||
|
||||
export function App() {
|
||||
return (
|
||||
<div>
|
||||
{Direction.Up}:{Status.Active}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"reactCompiler": false
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
## Code
|
||||
|
||||
import { jsxs as _jsxs } from "react/jsx-runtime";
|
||||
var Direction = /* @__PURE__ */ function(Direction) {
|
||||
Direction[Direction["Up"] = 1] = "Up";
|
||||
Direction[Direction["Down"] = 2] = "Down";
|
||||
return Direction;
|
||||
}(Direction || {});
|
||||
var Status = /* @__PURE__ */ function(Status) {
|
||||
Status["Active"] = "active";
|
||||
return Status;
|
||||
}(Status || {});
|
||||
export function App() {
|
||||
return /* @__PURE__ */ _jsxs("div", { children: [
|
||||
Direction.Up,
|
||||
":",
|
||||
Status.Active
|
||||
] });
|
||||
}
|
||||
|
||||
## Errors
|
||||
|
||||
(none)
|
||||
|
||||
## Fatal
|
||||
|
||||
false
|
||||
@@ -0,0 +1,16 @@
|
||||
enum Direction {
|
||||
Up = 1,
|
||||
Down = 2,
|
||||
}
|
||||
|
||||
const enum Status {
|
||||
Active = "active",
|
||||
}
|
||||
|
||||
export function App() {
|
||||
return (
|
||||
<div>
|
||||
{Direction.Up}:{Status.Active}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"reactCompiler": false,
|
||||
"typescript": {
|
||||
"optimizeConstEnums": true,
|
||||
"optimizeEnums": false
|
||||
}
|
||||
}
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
## Code
|
||||
|
||||
import { jsxs as _jsxs } from "react/jsx-runtime";
|
||||
var Direction = /* @__PURE__ */ function(Direction) {
|
||||
Direction[Direction["Up"] = 1] = "Up";
|
||||
Direction[Direction["Down"] = 2] = "Down";
|
||||
return Direction;
|
||||
}(Direction || {});
|
||||
export function App() {
|
||||
return /* @__PURE__ */ _jsxs("div", { children: [
|
||||
Direction.Up,
|
||||
":",
|
||||
"active"
|
||||
] });
|
||||
}
|
||||
|
||||
## Errors
|
||||
|
||||
(none)
|
||||
|
||||
## Fatal
|
||||
|
||||
false
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
enum Direction {
|
||||
Up = 1,
|
||||
Down = 2,
|
||||
}
|
||||
|
||||
const enum Status {
|
||||
Active = "active",
|
||||
}
|
||||
|
||||
export function App() {
|
||||
return (
|
||||
<div>
|
||||
{Direction.Up}:{Status.Active}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Vendored
+6
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"typescript": {
|
||||
"optimizeConstEnums": true,
|
||||
"optimizeEnums": true
|
||||
}
|
||||
}
|
||||
Vendored
+27
@@ -0,0 +1,27 @@
|
||||
## Code
|
||||
|
||||
import { c as _c } from "react/compiler-runtime";
|
||||
import { jsxs as _jsxs } from "react/jsx-runtime";
|
||||
export function App() {
|
||||
const $ = _c(1);
|
||||
let t0;
|
||||
if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
|
||||
t0 = /* @__PURE__ */ _jsxs("div", { children: [
|
||||
1,
|
||||
":",
|
||||
"active"
|
||||
] });
|
||||
$[0] = t0;
|
||||
} else {
|
||||
t0 = $[0];
|
||||
}
|
||||
return t0;
|
||||
}
|
||||
|
||||
## Errors
|
||||
|
||||
(none)
|
||||
|
||||
## Fatal
|
||||
|
||||
false
|
||||
@@ -0,0 +1,16 @@
|
||||
enum Direction {
|
||||
Up = 1,
|
||||
Down = 2,
|
||||
}
|
||||
|
||||
const enum Status {
|
||||
Active = "active",
|
||||
}
|
||||
|
||||
export function App() {
|
||||
return (
|
||||
<div>
|
||||
{Direction.Up}:{Status.Active}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"reactCompiler": false,
|
||||
"typescript": {
|
||||
"optimizeConstEnums": true,
|
||||
"optimizeEnums": true
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
## Code
|
||||
|
||||
import { jsxs as _jsxs } from "react/jsx-runtime";
|
||||
export function App() {
|
||||
return /* @__PURE__ */ _jsxs("div", { children: [
|
||||
1,
|
||||
":",
|
||||
"active"
|
||||
] });
|
||||
}
|
||||
|
||||
## Errors
|
||||
|
||||
(none)
|
||||
|
||||
## Fatal
|
||||
|
||||
false
|
||||
@@ -355,6 +355,12 @@ export interface TransformOptions {
|
||||
* @see <https://oxc.rs/docs/guide/usage/transformer/jsx>
|
||||
*/
|
||||
jsx?: 'preserve' | JsxOptions
|
||||
/**
|
||||
* Configure how Typescript is transformed.
|
||||
*
|
||||
* @see <https://oxc.rs/docs/guide/usage/transformer/typescript>
|
||||
*/
|
||||
typescript?: TypeScriptOptions
|
||||
/**
|
||||
* Configure React Compiler, or disable it with `false`.
|
||||
*
|
||||
@@ -392,3 +398,26 @@ export interface TransformResult {
|
||||
* removed and configured JSX transforms run afterwards.
|
||||
*/
|
||||
export declare function transformSync(filename: string, sourceText: string, options?: TransformOptions | undefined | null): TransformResult
|
||||
|
||||
/**
|
||||
* Configure how Typescript is transformed.
|
||||
*
|
||||
* @see <https://oxc.rs/docs/guide/usage/transformer/typescript>
|
||||
*/
|
||||
export interface TypeScriptOptions {
|
||||
/**
|
||||
* Inlines const enum values and removes the declaration.
|
||||
*
|
||||
* @default false
|
||||
*/
|
||||
optimizeConstEnums?: boolean
|
||||
/**
|
||||
* Inlines regular (non-const) enum member accesses when all members
|
||||
* satisfy const enum constraints (i.e., their values are statically evaluable).
|
||||
* Non-exported enum declarations are also removed when all members are
|
||||
* evaluable and no references to the enum as a runtime value exist.
|
||||
*
|
||||
* @default false
|
||||
*/
|
||||
optimizeEnums?: boolean
|
||||
}
|
||||
@@ -355,6 +355,12 @@ export interface TransformOptions {
|
||||
* @see <https://oxc.rs/docs/guide/usage/transformer/jsx>
|
||||
*/
|
||||
jsx?: 'preserve' | JsxOptions
|
||||
/**
|
||||
* Configure how Typescript is transformed.
|
||||
*
|
||||
* @see <https://oxc.rs/docs/guide/usage/transformer/typescript>
|
||||
*/
|
||||
typescript?: TypeScriptOptions
|
||||
/**
|
||||
* Configure React Compiler, or disable it with `false`.
|
||||
*
|
||||
@@ -392,3 +398,26 @@ export interface TransformResult {
|
||||
* removed and configured JSX transforms run afterwards.
|
||||
*/
|
||||
export declare function transformSync(filename: string, sourceText: string, options?: TransformOptions | undefined | null): TransformResult
|
||||
|
||||
/**
|
||||
* Configure how Typescript is transformed.
|
||||
*
|
||||
* @see <https://oxc.rs/docs/guide/usage/transformer/typescript>
|
||||
*/
|
||||
export interface TypeScriptOptions {
|
||||
/**
|
||||
* Inlines const enum values and removes the declaration.
|
||||
*
|
||||
* @default false
|
||||
*/
|
||||
optimizeConstEnums?: boolean
|
||||
/**
|
||||
* Inlines regular (non-const) enum member accesses when all members
|
||||
* satisfy const enum constraints (i.e., their values are statically evaluable).
|
||||
* Non-exported enum declarations are also removed when all members are
|
||||
* evaluable and no references to the enum as a runtime value exist.
|
||||
*
|
||||
* @default false
|
||||
*/
|
||||
optimizeEnums?: boolean
|
||||
}
|
||||
Reference in new issue
Block a user