CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-parcel--transformer-babel

A Parcel transformer plugin that transforms JavaScript code using Babel with automatic configuration discovery and intelligent defaults for modern JavaScript, TypeScript, JSX, and Flow.

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

utilities.mddocs/

Utility Functions

Internal helper functions for target conversion, JSX detection, Flow configuration, and AST manipulation that support the core Babel transformation functionality. These functions are not directly exported but are used internally by the transformer.

Capabilities

Target Conversion

Converts Parcel's engine specifications to Babel preset-env targets format.

/**
 * Converts Parcel's engine specifications to Babel preset-env targets
 * Handles browser targets, Node.js versions, and ES module output optimization
 * @param env - Parcel environment object with engine specifications
 * @returns BabelTargets object compatible with @babel/preset-env
 * @internal - Used internally by the configuration system
 */
function enginesToBabelTargets(env: Environment): BabelTargets;

interface Environment {
  engines: { [engineName: string]: string };  // Engine version specifications
  outputFormat: string;                       // Output format (esm, cjs, etc.)
  isBrowser(): boolean;                       // Browser environment check
}

interface BabelTargets {
  [engineName: string]: string | boolean | Array<string>;
  browsers?: string | Array<string>;          // Browser target queries
  esmodules?: boolean;                        // ES modules target flag
}

Supported Target Names:

const TargetNames = {
  node: 'node',
  chrome: 'chrome', 
  opera: 'opera',
  edge: 'edge',
  firefox: 'firefox',
  safari: 'safari',
  ie: 'ie',
  ios: 'ios',
  android: 'android',
  electron: 'electron',
  samsung: 'samsung',
  rhino: 'rhino'
};

ES Module Browser Exclusions:

const ESMODULE_BROWSERS = [
  'not ie <= 11',
  'not edge < 16', 
  'not firefox < 60',
  'not chrome < 61',
  'not safari < 11',
  'not opera < 48',
  'not ios_saf < 11',
  'not op_mini all',
  'not android < 76',
  'not blackberry > 0',
  'not op_mob > 0',
  'not and_chr < 76',
  'not and_ff < 68',
  'not ie_mob > 0',
  'not and_uc > 0',
  'not samsung < 8.2',
  'not and_qq > 0',
  'not baidu > 0',
  'not kaios > 0'
];

Usage Examples:

// Convert Parcel engines to Babel targets
const env = {
  engines: {
    node: '>=16.0.0',
    browsers: ['> 1%', 'last 2 versions']
  },
  outputFormat: 'cjs',
  isBrowser: () => false
};

const targets = enginesToBabelTargets(env);
// Result: { node: '16.0.0', browsers: ['> 1%', 'last 2 versions'] }

// ES module output with browser targets
const esmEnv = {
  engines: { browsers: '> 1%' },
  outputFormat: 'esmodule',
  isBrowser: () => true
};

const esmTargets = enginesToBabelTargets(esmEnv);
// Result: { browsers: ['> 1%', 'not ie <= 11', 'not edge < 16', ...] }

JSX Detection

Determines if a file likely contains JSX syntax based on file extension and project dependencies.

/**
 * Detects if an asset likely contains JSX syntax
 * Checks file extensions and React-like dependencies in package.json
 * @param options - Plugin options for dependency resolution
 * @param config - Parcel configuration object
 * @returns Promise resolving to true if JSX is likely present
 * @internal - Used internally by the configuration system
 */
async function isJSX(
  options: PluginOptions,
  config: Config
): Promise<boolean>;

JSX Detection Logic:

  1. Non-Source Files: Returns false for node_modules files
  2. File Extension Check: Automatically true for .jsx and .tsx files
  3. React Alias Check: Detects React aliases in package.json
  4. Dependency Check: Searches for React-like libraries in dependencies

Supported Extensions:

const JSX_EXTENSIONS = new Set(['.jsx', '.tsx']);

Detected Libraries:

const JSX_LIBRARIES = ['react', 'preact', 'nervejs', 'hyperapp'];

Usage Examples:

// Check if file contains JSX
const hasJSX = await isJSX(pluginOptions, parcelConfig);

// File extension detection
// Button.jsx -> true
// Component.tsx -> true  
// utils.js -> depends on dependencies

// Dependency detection
// package.json with "react": "^18.0.0" -> true for .js files
// package.json with "preact": "^10.0.0" -> true for .js files
// No React-like deps -> false for .js files

// Alias detection
// package.json: { "alias": { "react": "preact/compat" } } -> true

Flow Configuration

Generates Babel configuration for stripping Flow type annotations when Flow is detected in the project.

/**
 * Generates Babel configuration for Flow type stripping
 * Only applies when flow-bin is detected as a project dependency
 * @param config - Parcel configuration object
 * @param options - Plugin options for dependency resolution  
 * @returns Promise resolving to BabelConfig for Flow or null if not needed
 * @internal - Used internally by the configuration system
 */
async function getFlowOptions(
  config: Config,
  options: PluginOptions
): Promise<BabelConfig | null>;

interface BabelConfig {
  plugins?: Array<any>;
  presets?: Array<any>;
}

Flow Detection Process:

  1. Non-Source Files: Returns null for node_modules files
  2. Test Environment Exception: Special handling for @parcel/error-overlay in tests
  3. Dependency Check: Searches for flow-bin in dependencies or devDependencies
  4. Plugin Configuration: Creates Flow strip types plugin configuration
  5. Dependency Installation: Ensures required Babel plugins are available

Usage Examples:

// Generate Flow configuration
const flowConfig = await getFlowOptions(parcelConfig, pluginOptions);

// With flow-bin dependency:
// {
//   plugins: [
//     ['@babel/plugin-transform-flow-strip-types', { requireDirective: true }]
//   ]
// }

// Without flow-bin dependency:
// null

// Example Flow code transformation:
// Input:  function add(a: number, b: number): number { return a + b; }
// Output: function add(a, b) { return a + b; }

AST Location Remapping

Remaps AST node locations using source maps for accurate debugging information.

/**
 * Remaps AST node locations using source map for accurate sourcemap generation
 * Improves sourcemap accuracy and fixes sourcemaps when scope-hoisting
 * @param t - Babel types utility object
 * @param ast - Babel AST file node
 * @param map - Source map for location mapping
 * @internal - Used internally by the Babel processing engine
 */
function remapAstLocations(
  t: BabelTypes,
  ast: BabelNodeFile, 
  map: SourceMap
): void;

interface BabelNodeFile {
  program: any;           // AST program node
}

interface SourceMap {
  findClosestMapping(line: number, column: number): Mapping | null;
}

interface Mapping {
  original: {
    line: number;         // Original source line
    column: number;       // Original source column
  };
  source: string;         // Original source file name
}

Remapping Process:

  1. AST Traversal: Visits all nodes in the AST recursively
  2. Location Check: Processes nodes with location information
  3. Mapping Lookup: Finds closest source map mapping for each location
  4. Location Update: Updates start and end positions with original coordinates
  5. Filename Update: Sets original source filename on nodes
  6. Null Mapping Handling: Removes location for unmappable positions

Usage Examples:

// Remap AST locations after transformation
const sourceMap = await asset.getMap();
if (sourceMap && transformedAST) {
  remapAstLocations(babelTypes, transformedAST, sourceMap);
}

// Before remapping (compiled locations):
// Node at line 10, column 5 in compiled output

// After remapping (original locations):  
// Node at line 8, column 2 in original source
// Filename: 'src/components/Button.jsx'

Internal Tree Traversal

Helper function for traversing all nodes in an AST tree.

/**
 * Recursively traverses all nodes in an AST tree
 * Used internally by remapAstLocations for complete tree processing
 * @param t - Babel types utility object
 * @param node - Current AST node to traverse
 * @param visitor - Visitor function called for each node
 */
function traverseAll(
  t: BabelTypes,
  node: Node,
  visitor: (node: Node) => void
): void;

Traversal Features:

  • Recursive Processing: Handles nested node structures
  • Visitor Pattern: Calls visitor function for each node
  • Type-Aware: Uses Babel's VISITOR_KEYS for proper traversal
  • Array Handling: Processes arrays of nodes correctly
  • Null Safety: Handles null/undefined nodes gracefully

Constants and Configuration

Version Requirements

const BABEL_CORE_RANGE = '^7.12.0';  // Required @babel/core version

File Extensions

const TYPESCRIPT_EXTNAME_RE = /\.tsx?$/;  // TypeScript file detection
const JS_EXTNAME_RE = /^\.(js|cjs|mjs)$/; // JavaScript file detection

Error Handling

All utility functions include appropriate error handling:

  • Dependency Resolution: Graceful handling of missing dependencies
  • File System Access: Safe file reading with fallbacks
  • Version Compatibility: Validation of Babel version requirements
  • Configuration Validation: Proper handling of invalid configurations

Performance Considerations

  • Lazy Loading: Dependencies loaded only when needed
  • Caching: Results cached where appropriate
  • Efficient Traversal: Optimized AST traversal algorithms
  • Minimal Processing: Only processes when transformations are needed

Install with Tessl CLI

npx tessl i tessl/npm-parcel--transformer-babel

docs

babel-processing.md

configuration.md

error-handling.md

index.md

transformer.md

utilities.md

tile.json