or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

build-automation.mdcore-bundling.mdindex.mdplugins.mdtransformation.md
tile.json

transformation.mddocs/

Code Transformation

FuseBox provides a comprehensive TypeScript/JavaScript transformation system with support for modern language features, JSX, custom transforms, and testing utilities. The transformation pipeline handles TypeScript compilation, modern JavaScript features, and custom code transformations.

Main Transformation Functions

initCommonTransform

function initCommonTransform(props: {
  code: string;
  compilerOptions?: ICompilerOptions;
  jsx?: boolean;
  props?: ISerializableTransformationContext;
  transformers: Array<ITransformer>;
}): {
  code: string;
  requireStatementCollection: ITransformerRequireStatementCollection;
};

This function applies a series of transformers to TypeScript/JavaScript code and returns the transformed code along with collected require statements for dependency analysis.

testTransform

function testTransform(props: {
  code: string;
  compilerOptions?: ICompilerOptions;
  jsx?: boolean;
  props?: ISerializableTransformationContext;
  transformers: Array<ITransformer>;
}): {
  code: string;
  requireStatementCollection: ITransformerRequireStatementCollection;
};

The testTransform function is an alias for initCommonTransform specifically designed for testing and development purposes. It provides the same transformation capabilities with identical API, making it convenient for unit tests and code experimentation.

Base Transformers

const BASE_TRANSFORMERS: Array<ITransformer>;

The BASE_TRANSFORMERS constant contains the core set of transformers that handle:

  • TypeScript features (enums, classes, decorators, parameter properties)
  • Modern JavaScript (optional chaining, nullish coalescing)
  • JSX transformation
  • Import/export handling
  • Dynamic imports
  • Browser polyfills and environment variables

Transformer Interfaces

Core Transformer Interface

interface ITransformer {
  commonVisitors?: (props: ITransformerCommon) => ITransformerVisitors;
}

interface ITransformerCommon {
  onRequireCallExpression: (importType: ImportType, statement: ASTNode) => void;
  transformationContext: ISerializableTransformationContext;
}

interface ITransformerVisitors {
  onEach?: (node: ASTNode) => ASTNode | void;
  onEnter?: (node: ASTNode) => ASTNode | void;
  onLeave?: (node: ASTNode) => ASTNode | void;
}

Transformation Context

interface ISerializableTransformationContext {
  compilerOptions?: ICompilerOptions;
  fileAbsPath?: string;
  module?: {
    isEntry?: boolean;
    isServerEntry?: boolean;
  };
  packageName?: string;
  packageType?: PackageType;
  target?: ITarget;
}

interface ICompilerOptions {
  target?: string;
  module?: string;
  lib?: string[];
  declaration?: boolean;
  outDir?: string;
  rootDir?: string;
  strict?: boolean;
  esModuleInterop?: boolean;
  skipLibCheck?: boolean;
  forceConsistentCasingInFileNames?: boolean;
  experimentalDecorators?: boolean;
  emitDecoratorMetadata?: boolean;
  jsx?: "preserve" | "react" | "react-jsx" | "react-jsxdev";
  jsxFactory?: string;
  jsxFragmentFactory?: string;
}

Import Types and AST

enum ImportType {
  REQUIRE = "require",
  IMPORT = "import", 
  DYNAMIC_IMPORT = "dynamic_import"
}

interface ASTNode {
  type: string;
  start?: number;
  end?: number;
  loc?: {
    start: { line: number; column: number };
    end: { line: number; column: number };
  };
  [key: string]: any;
}

type ITransformerRequireStatementCollection = Array<{
  importType: ImportType;
  statement: ASTNode;
}>;

Available Transformers

TypeScript Transformers

  • EnumTransformer: Transforms TypeScript enums to JavaScript
  • ClassConstructorPropertyTransformer: Handles parameter properties in constructors
  • CommonTSfeaturesTransformer: General TypeScript to JavaScript transformations

Modern JavaScript Transformers

  • OptionalChainingTransformer: Transforms optional chaining (?.) for older browsers
  • NullishCoalescingTransformer: Transforms nullish coalescing (??) for older browsers

Import/Export Transformers

  • ImportTransformer: Transforms ES6 imports to require statements
  • ExportTransformer: Transforms ES6 exports to CommonJS exports
  • DynamicImportTransformer: Handles dynamic import() expressions

Framework Transformers

  • JSXTransformer: Transforms JSX to JavaScript function calls

Bundle Transformers

  • RequireStatementInterceptor: Intercepts and modifies require statements
  • BrowserProcessTransformer: Provides Node.js process polyfill for browsers
  • BuildEnvTransformer: Injects build environment variables
  • BundlePolyfillTransformer: Adds necessary polyfills for target environments

Usage Examples

Basic Code Transformation

import { initCommonTransform, testTransform, BASE_TRANSFORMERS } from "fuse-box";

const result = initCommonTransform({
  code: `
    interface User {
      name: string;
      age?: number;
    }
    
    const user: User = { name: "Alice" };
    export { user };
  `,
  transformers: BASE_TRANSFORMERS,
  compilerOptions: {
    target: "ES2018",
    module: "CommonJS"
  }
});

console.log(result.code); // Transformed JavaScript
console.log(result.requireStatementCollection); // Collected dependencies

Testing Code Transformations

import { testTransform, BASE_TRANSFORMERS } from "fuse-box";

// Use testTransform for unit tests and development
const testResult = testTransform({
  code: `
    enum Color { RED, GREEN, BLUE }
    const color: Color = Color.RED;
  `,
  transformers: BASE_TRANSFORMERS
});

// Verify transformation results in tests
expect(testResult.code).toContain('var Color');
expect(testResult.requireStatementCollection).toHaveLength(0);

JSX Transformation

import { initCommonTransform, BASE_TRANSFORMERS } from "fuse-box";

const result = initCommonTransform({
  code: `
    import React from 'react';
    
    const Component = ({ title }: { title: string }) => {
      return <div className="title">{title}</div>;
    };
    
    export default Component;
  `,
  jsx: true,
  transformers: BASE_TRANSFORMERS,
  compilerOptions: {
    jsx: "react",
    jsxFactory: "React.createElement"
  }
});

Custom Transformation Context

import { initCommonTransform, BASE_TRANSFORMERS } from "fuse-box";

const result = initCommonTransform({
  code: sourceCode,
  transformers: BASE_TRANSFORMERS,
  props: {
    fileAbsPath: "/path/to/file.ts",
    packageName: "my-package",
    target: "browser",
    module: {
      isEntry: true
    },
    compilerOptions: {
      target: "ES2020",
      module: "ESNext",
      strict: true,
      experimentalDecorators: true
    }
  }
});

TypeScript Enum Transformation

// Input TypeScript code
const tsCode = `
  enum Status {
    PENDING = "pending",
    COMPLETED = "completed",
    FAILED = "failed"
  }
  
  export { Status };
`;

const result = initCommonTransform({
  code: tsCode,
  transformers: BASE_TRANSFORMERS
});

// Outputs JavaScript with enum transformed to object

Modern JavaScript Feature Transformation

// Input code with modern features
const modernCode = `
  const user = data?.user?.profile;
  const name = user?.name ?? "Unknown";
  
  class UserService {
    private cache = new Map();
    
    async getUser(id: string) {
      return this.cache.get(id) ?? await this.fetchUser(id);
    }
  }
`;

const result = initCommonTransform({
  code: modernCode,
  transformers: BASE_TRANSFORMERS,
  compilerOptions: {
    target: "ES5" // Transform to ES5 compatible code
  }
});

Bundle Environment Transformation

// Code with environment variables
const envCode = `
  if (process.env.NODE_ENV === "development") {
    console.log("Debug mode enabled");
  }
  
  const API_URL = process.env.API_URL || "https://api.example.com";
`;

const result = initCommonTransform({
  code: envCode,
  transformers: BASE_TRANSFORMERS,
  props: {
    target: "browser" // Will polyfill process.env for browser
  }
});

Custom Transformers

You can create custom transformers for specialized code transformations:

import { ITransformer, ASTNode } from "fuse-box";

const customTransformer: ITransformer = {
  commonVisitors: (props) => ({
    onEnter: (node: ASTNode) => {
      // Custom transformation logic
      if (node.type === "Identifier" && node.name === "OLD_API") {
        node.name = "NEW_API";
      }
    }
  })
};

const result = initCommonTransform({
  code: sourceCode,
  transformers: [...BASE_TRANSFORMERS, customTransformer]
});

Integration with Build Process

The transformation system is automatically integrated into FuseBox's build process:

import { fusebox } from "fuse-box";

const fuse = fusebox({
  target: "browser",
  entry: "src/index.ts",
  compilerOptions: {
    target: "ES2018",
    jsx: "react",
    experimentalDecorators: true
  }
});

// Transformations are applied automatically during bundling
const result = await fuse.runProd();

The transformation pipeline ensures that all TypeScript and modern JavaScript features are properly compiled for the target environment while maintaining source maps and preserving the original code structure where possible.