or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

basic-config.mdextension-utilities.mdindex.mdnative-config.mdnode-config.mdtypescript-analysis.mdweb-config.md
tile.json

extension-utilities.mddocs/

Extension Utilities

Utility functions and constants for computing platform-specific file extensions used internally by ESLint Config Universe. These utilities are primarily for advanced customization and understanding how the configurations handle React Native and Expo platform-specific files.

Capabilities

Extension Constants

Pre-defined arrays of file extensions for different languages and platforms.

const { jsExtensions, tsExtensions, platformSubextensions } = require('eslint-config-universe/shared/extensions');

// JavaScript file extensions
jsExtensions: ['.js', '.jsx']

// TypeScript file extensions  
tsExtensions: ['.ts', '.tsx', '.d.ts']

// Platform-specific sub-extensions for React Native/Expo
platformSubextensions: ['.android', '.ios', '.web', '.native']

Extension Computation Function

Function that computes all possible file extension combinations for Expo and React Native projects.

const { computeExpoExtensions } = require('eslint-config-universe/shared/extensions');

/**
 * Computes all possible Expo file extensions by combining base extensions 
 * with platform sub-extensions and optional .expo prefix
 * @param baseExtensions - Array of base file extensions (e.g., ['.js', '.ts'])
 * @param platformSubextensions - Array of platform-specific extensions (e.g., ['.android', '.ios'])
 * @returns Array of all computed extension combinations
 */
function computeExpoExtensions(baseExtensions: string[], platformSubextensions: string[]): string[];

Usage Examples:

const { 
  jsExtensions,
  tsExtensions, 
  platformSubextensions,
  computeExpoExtensions
} = require('eslint-config-universe/shared/extensions');

// Get all JavaScript extensions
console.log(jsExtensions);
// Output: ['.js', '.jsx']

// Get all TypeScript extensions
console.log(tsExtensions);
// Output: ['.ts', '.tsx', '.d.ts']

// Get platform sub-extensions
console.log(platformSubextensions);
// Output: ['.android', '.ios', '.web', '.native']

// Compute all possible extensions for JavaScript
const jsExpoExtensions = computeExpoExtensions(jsExtensions, platformSubextensions);
console.log(jsExpoExtensions);
// Output: [
//   '.js', '.jsx',                    // Base extensions
//   '.android.js', '.android.jsx',    // Android-specific
//   '.ios.js', '.ios.jsx',           // iOS-specific
//   '.web.js', '.web.jsx',           // Web-specific
//   '.native.js', '.native.jsx',     // Native-specific
//   '.expo.js', '.expo.jsx',         // Expo base
//   '.expo.android.js', '.expo.android.jsx', // Expo + Android
//   '.expo.ios.js', '.expo.ios.jsx', // Expo + iOS
//   '.expo.web.js', '.expo.web.jsx', // Expo + Web
//   '.expo.native.js', '.expo.native.jsx' // Expo + Native
// ]

// Compute all possible extensions for both JS and TS
const allExtensions = computeExpoExtensions(
  [...jsExtensions, ...tsExtensions],
  platformSubextensions
);
console.log(allExtensions.length); // 30 different extension combinations

Extension Resolution Logic

The computeExpoExtensions function uses the following algorithm:

// Simplified implementation logic
function computeExpoExtensions(baseExtensions, platformSubextensions) {
  const expoExtensions = [];
  
  // For each expo prefix (.expo or none)
  for (const expo of ['.expo', '']) {
    // For each platform (or none)
    for (const platform of [...platformSubextensions, '']) {
      // For each base extension
      for (const base of baseExtensions) {
        // Combine: [expo][platform][base]
        expoExtensions.push(`${expo}${platform}${base}`);
      }
    }
  }
  
  return expoExtensions;
}

Platform-Specific File Resolution

Understanding how React Native and Expo resolve platform-specific files:

Resolution Priority

React Native resolves files in the following order:

  1. Platform-specific with exact match: Component.ios.js
  2. Platform-specific with native fallback: Component.native.js
  3. Platform-agnostic: Component.js

Expo Extensions

Expo adds an additional layer with .expo prefix:

  1. Expo + platform-specific: Component.expo.ios.js
  2. Expo platform-agnostic: Component.expo.js
  3. Standard React Native resolution continues...

Common Patterns

// File resolution examples:

// For iOS build of Expo app:
// 1. Button.expo.ios.tsx    (Expo iOS-specific TypeScript)
// 2. Button.ios.tsx         (iOS-specific TypeScript)
// 3. Button.native.tsx      (Native-specific TypeScript)
// 4. Button.expo.tsx        (Expo-specific TypeScript)
// 5. Button.tsx             (Generic TypeScript)

// For web build of Expo app:
// 1. Button.expo.web.tsx    (Expo web-specific)
// 2. Button.web.tsx         (Web-specific)
// 3. Button.expo.tsx        (Expo-specific)
// 4. Button.tsx             (Generic)

// For Android React Native app (no Expo):
// 1. Button.android.tsx     (Android-specific)
// 2. Button.native.tsx      (Native-specific)
// 3. Button.tsx             (Generic)

Custom Configuration Usage

Using extension utilities for custom ESLint configurations:

// Custom ESLint config using extension utilities
const { computeExpoExtensions, jsExtensions, tsExtensions } = require('eslint-config-universe/shared/extensions');

const customPlatforms = ['.mobile', '.desktop', '.tablet'];
const allExtensions = computeExpoExtensions(
  [...jsExtensions, ...tsExtensions],
  customPlatforms
);

module.exports = {
  extends: ['universe'],
  settings: {
    'import/extensions': allExtensions,
    'import/resolver': {
      node: { extensions: allExtensions }
    }
  },
  overrides: [
    {
      files: ['**/*.mobile.*'],
      rules: {
        // Mobile-specific rules
        'no-console': 'error'
      }
    },
    {
      files: ['**/*.desktop.*'],
      env: { electron: true },
      rules: {
        // Desktop-specific rules
        'node/no-unsupported-features/node-builtins': 'off'
      }
    }
  ]
};

Internal Usage

These utilities are used internally by the universe configurations:

Native Configuration Usage

// From native.js
const { computeExpoExtensions, jsExtensions, tsExtensions, platformSubextensions } = require('./shared/extensions');

const allExtensions = computeExpoExtensions(
  [...jsExtensions, ...tsExtensions],
  platformSubextensions
);

// Used in import resolver settings
settings: {
  'import/extensions': allExtensions,
  'import/resolver': {
    node: { extensions: allExtensions }
  }
}

Core Configuration Usage

// From shared/core.js
const { jsExtensions } = require('./extensions');

// Used for basic import resolution
settings: {
  'import/extensions': jsExtensions,
  'import/resolver': {
    node: { extensions: jsExtensions }
  }
}

Flat Configuration Support

Extension utilities work identically in both traditional and flat configurations:

// Flat config usage
const { computeExpoExtensions, jsExtensions, tsExtensions, platformSubextensions } = require('eslint-config-universe/flat/shared/extensions');

// Same API, same functionality
const allExtensions = computeExpoExtensions(
  [...jsExtensions, ...tsExtensions], 
  platformSubextensions
);

Note: The flat configuration versions are located in flat/shared/extensions.js but provide identical functionality to the traditional configuration versions.