CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-babel-plugin-minify-constant-folding

A Babel plugin for constant folding optimization that evaluates compile-time expressions and replaces them with their computed values

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

babel-plugin-minify-constant-folding

A Babel plugin that performs constant folding optimization during JavaScript compilation. It evaluates expressions at compile-time that can be computed statically and replaces them with their literal values, reducing runtime computation and improving performance.

Package Information

  • Package Name: babel-plugin-minify-constant-folding
  • Package Type: npm
  • Language: JavaScript
  • Installation: npm install babel-plugin-minify-constant-folding --save-dev

Core Imports

As a Babel plugin, this package is typically imported and used through Babel configuration:

const constantFoldingPlugin = require("babel-plugin-minify-constant-folding");

Dependencies:

  • babel-helper-evaluate-path: Used internally for safe expression evaluation

Basic Usage

Via .babelrc (Recommended)

.babelrc

{
  "plugins": ["minify-constant-folding"]
}

Via CLI

babel --plugins minify-constant-folding script.js

Via Node API

const babel = require("@babel/core");

const result = babel.transform("code", {
  plugins: ["minify-constant-folding"]
});

Configuration Options

// With options
{
  "plugins": [
    ["minify-constant-folding", { "tdz": true }]
  ]
}

Architecture

The plugin operates through Babel's visitor pattern, transforming AST nodes during compilation:

  • Expression Evaluation: Uses babel-helper-evaluate-path to determine if expressions can be safely computed
  • Binary Expression Optimization: Combines adjacent string literals in concatenation expressions
  • Method Call Replacement: Replaces array and string methods with computed values when inputs are static
  • Member Access Replacement: Replaces property access on static arrays and strings with their values

Capabilities

Transformation Examples

The plugin performs various compile-time optimizations as demonstrated in these examples:

Basic arithmetic and string concatenation:

// Input
"a" + "b";        // → "ab"
2 * 3;            // → 6
4 | 3;            // → 7
"b" + a + "c" + "d" + g + z + "f" + "h" + "z";  // → "b" + a + "cd" + g + z + "fhz"

Array literal optimizations:

// Input
[1, 2, 3].length;     // → 3
[1, 2, 3][1];         // → 2
[1, 2, 3].join();     // → "1,2,3"
["a", "b", "c"].join("@");  // → "a@b@c"
[1, 2, 3].pop();      // → 3
[1, 2, 3].shift();    // → 2 (new length after removing first element)
[1, 2, 3].slice(0, 2); // → [1, 2]

String literal optimizations:

// Input
"abc"[0];             // → "a"
"abc".charAt(1);      // → "b"
"abc".charCodeAt(1);  // → 98
"abc".length;         // → 3
"a,b,c".split(",");   // → ["a", "b", "c"]

Plugin Factory Function

The main export that creates a Babel plugin configuration. The plugin uses a replacement system to handle array and string literal optimizations.

/**
 * Creates a Babel plugin for constant folding optimization
 * @param {object} babel - Babel core object containing types and utilities
 * @returns {object} Plugin configuration with name and visitor methods
 */
function constantFoldingPlugin(babel);

/** Symbol used to mark processed nodes and prevent infinite recursion */
const SEEN_SYMBOL: symbol;

/** Symbol used as fallback handler for dynamic property access */
const FALLBACK_HANDLER: symbol;

Returns: Plugin configuration object with the following structure:

interface PluginConfig {
  name: "minify-constant-folding";
  visitor: {
    BinaryExpression: (path: NodePath) => void;
    Expression: (path: NodePath, state: { opts?: PluginOptions }) => void;
    CallExpression: (path: NodePath) => void;
    MemberExpression: (path: NodePath) => void;
  };
}

Plugin Options

interface PluginOptions {
  /** Account for Temporal Dead Zone when evaluating expressions (default: false) */
  tdz?: boolean;
}

Expression Optimization

The plugin optimizes various types of expressions:

Binary Expressions

  • String concatenation: "a" + "b""ab"
  • Arithmetic operations: 2 * 36
  • Bitwise operations: 4 | 37
  • Complex concatenation: "b" + a + "c" + "d""b" + a + "cd"

Array Method Calls

Array methods are replaced with computed values when the array is static:

// Array method optimizations (when array has no spread elements)
interface ArrayOptimizations {
  /** ["a", "b", "c"].join() → "a,b,c" */
  join(separator?: string): string;
  /** [1, 2, 3].length → 3 */
  length: number;
  /** [1, 2, 3][1] → 2 */
  [index: number]: any;
  /** [1, 2, 3].slice(0, 2) → [1, 2] */
  slice(start?: number, end?: number): any[];
  /** [1, 2, 3].shift() → returns new length after removing first element (2) */
  shift(): number | undefined;
  /** [a, b, c].pop() → c */
  pop(): any;
  /** [a, b, c].reverse() → [c, b, a] */
  reverse(): any[];
  /** [a, b, c].push(d, e) → returns new length */
  push(...items: any[]): number;
  /** [1, 2, 3].splice(1) → [2, 3], [1, 2, 3, 4].splice(1, 2) → [2, 3] */
  splice(start: number, deleteCount?: number, ...items: any[]): any[];
}

String Method Calls

String methods are replaced with computed values when the string is static:

// String method optimizations
interface StringOptimizations {
  /** "abc".length → 3 */
  length: number;
  /** "abc"[0] → "a", "abc"[4] → undefined */
  [index: number]: string | undefined;
  /** "abc".charAt() → "a", "abc".charAt(1) → "b" */
  charAt(index?: number): string;
  /** "abc".charCodeAt() → 97, "abc".charCodeAt(1) → 98 */
  charCodeAt(index?: number): number;
  /** "abc".codePointAt() → 97, "abc".codePointAt(1) → 98 */
  codePointAt(index?: number): number;
  /** "a,b,c".split(",") → ["a", "b", "c"], "a,b,c".split() → ["a,b,c"] */
  split(separator?: string | undefined): string[];
}

Safety Constraints

The plugin includes several safety mechanisms to prevent incorrect optimizations:

  • Pure Expression Check: Only optimizes expressions that have no side effects
  • Export Specifier Protection: Avoids replacing values in export specifiers
  • Negative Zero Preservation: Maintains -0 vs 0 distinction
  • Unary Expression Handling: Preserves !0/!1 patterns and void 0 for undefined
  • Fraction Avoidance: Skips non-integer results to avoid precision issues
  • Object Literal Skipping: Avoids converting objects to prevent environment-specific issues
  • Temporal Dead Zone: Optional TDZ consideration for safer transformations
  • Infinite Recursion Prevention: Uses internal symbol marking to avoid re-processing already optimized nodes

Replacement System Architecture

The plugin uses a sophisticated replacement system to handle array and string method optimizations:

interface ReplacementSystem {
  /** Handlers for ArrayExpression nodes */
  ArrayExpression: {
    /** Check if array can be safely replaced (no spread elements) */
    canReplace(): boolean;
    /** Member access handlers (length, [index]) */
    members: Record<string | symbol, Function>;
    /** Method call handlers (join, push, pop, etc.) */
    calls: Record<string, Function>;
  };
  /** Handlers for StringLiteral nodes */
  StringLiteral: {
    /** Member access handlers (length, [index]) */
    members: Record<string | symbol, Function>;
    /** Method call handlers (split, charAt, etc.) */
    calls: Record<string, Function>;
  };
}

/** Fallback handler for dynamic property access */
interface FallbackHandler {
  /** Called when specific property handler not found */
  [FALLBACK_HANDLER]: (propertyName: string | number) => any;
}

Types

/** Babel NodePath representing an AST node */
interface NodePath {
  node: any;
  parent: any;
  replaceWith(node: any): void;
  get(key: string): NodePath;
  isLiteral(): boolean;
  isPure(): boolean;
  isBinaryExpression(opts?: object): boolean;
  isStringLiteral(): boolean;
  // ... other Babel NodePath methods
}

/** Babel types utility object */
interface BabelTypes {
  stringLiteral(value: string): any;
  numericLiteral(value: number): any;
  arrayExpression(elements: any[]): any;
  unaryExpression(operator: string, argument: any, prefix?: boolean): any;
  valueToNode(value: any): any;
  isMemberExpression(node: any): boolean;
  isExportSpecifier(node: any): boolean;
  isUnaryExpression(node: any, opts?: object): boolean;
  isNumericLiteral(node: any, opts?: object): boolean;
  isIdentifier(node: any, opts?: object): boolean;
  // ... other Babel type methods
}
Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/babel-plugin-minify-constant-folding@0.5.x
Publish Source
CLI
Badge
tessl/npm-babel-plugin-minify-constant-folding badge