CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-rollup--pluginutils

A set of utility functions commonly used by Rollup plugins

Pending
Overview
Eval results
Files

regex-utilities.mddocs/

Regular Expression Utilities

Pattern matching utilities for creating precise RegExp patterns, commonly used in plugin hook filters and string matching operations. These functions automatically escape special characters and provide consistent anchoring behavior.

Capabilities

exactRegex

Creates a RegExp that matches strings exactly by anchoring at both the beginning and end of the string.

/**
 * Constructs a RegExp that matches the exact string specified
 * Automatically escapes special regex characters and anchors with ^ and $
 * @param str - The string(s) to match exactly
 * @param flags - Optional RegExp flags (e.g., 'i', 'g', 'm')
 * @returns RegExp with exact matching (^pattern$)
 */
function exactRegex(str: string | string[], flags?: string): RegExp;

Parameters:

  • str (string | string[]): The string or array of strings to match exactly. Special regex characters are automatically escaped.
  • flags (string, optional): Standard RegExp flags like 'i' (case-insensitive), 'g' (global), 'm' (multiline)

Returns: RegExp with ^ and $ anchors for exact matching

Usage Examples:

import { exactRegex } from "@rollup/pluginutils";

// Basic exact matching
exactRegex('foobar'); // /^foobar$/
exactRegex('hello world'); // /^hello world$/

// Multiple alternatives
exactRegex(['foo', 'bar']); // /^(?:foo|bar)$/
exactRegex(['index.js', 'main.js']); // /^(?:index\.js|main\.js)$/

// With flags
exactRegex('FooBar', 'i'); // /^FooBar$/i (case-insensitive)

// Automatic escaping of special characters
exactRegex('foo(bar)'); // /^foo\(bar\)$/
exactRegex('app.config.js'); // /^app\.config\.js$/
exactRegex('$special^chars'); // /^\$special\^chars$/

// Use in plugin hooks
export default function myPlugin() {
  const entryPattern = exactRegex(['index.js', 'main.js', 'app.js']);
  
  return {
    buildStart() {
      // Filter entry files
      const entries = this.getModuleIds().filter(id => 
        entryPattern.test(id.split('/').pop())
      );
      console.log('Entry files:', entries);
    }
  };
}

// Virtual module matching
export default function virtualPlugin() {
  const virtualPattern = exactRegex(['virtual:config', 'virtual:env']);
  
  return {
    resolveId(id) {
      if (virtualPattern.test(id)) {
        return id;
      }
    }
  };
}

prefixRegex

Creates a RegExp that matches strings with a specific prefix by anchoring only at the beginning of the string.

/**
 * Constructs a RegExp that matches a value that has the specified prefix
 * Automatically escapes special regex characters and anchors with ^
 * @param str - The string(s) to match as prefix
 * @param flags - Optional RegExp flags (e.g., 'i', 'g', 'm')
 * @returns RegExp with prefix matching (^pattern)
 */
function prefixRegex(str: string | string[], flags?: string): RegExp;

Parameters:

  • str (string | string[]): The string or array of strings to match as prefix
  • flags (string, optional): Standard RegExp flags

Returns: RegExp with ^ anchor for prefix matching

Usage Examples:

import { prefixRegex } from "@rollup/pluginutils";

// Basic prefix matching
prefixRegex('foo'); // /^foo/
prefixRegex('src/'); // /^src\//

// Multiple prefixes
prefixRegex(['src/', 'lib/']); // /^(?:src\/|lib\/)/
prefixRegex(['@scope/', 'my-']); // /^(?:@scope\/|my-)/

// With flags
prefixRegex('HTTP', 'i'); // /^HTTP/i

// Automatic escaping
prefixRegex('src/components/'); // /^src\/components\//
prefixRegex('@rollup/'); // /^@rollup\//

// Use for module filtering
export default function myPlugin() {
  const srcPattern = prefixRegex(['src/', 'lib/', 'components/']);
  
  return {
    transform(code, id) {
      // Only transform files in source directories
      if (srcPattern.test(id)) {
        return { code: transformCode(code) };
      }
    }
  };
}

// Package scope filtering
export default function scopePlugin(options = {}) {
  const { allowedScopes = ['@mycompany/', '@utils/'] } = options;
  const scopePattern = prefixRegex(allowedScopes);
  
  return {
    resolveId(id) {
      if (scopePattern.test(id)) {
        // Allow imports from specified scopes
        return null; // Continue with normal resolution
      } else {
        // Block other scoped packages
        return false;
      }
    }
  };
}

// Environment-based file matching
const devPattern = prefixRegex(['dev/', 'development/']);
const prodPattern = prefixRegex(['prod/', 'production/']);

export default function envPlugin(options = {}) {
  const { environment = 'production' } = options;
  const pattern = environment === 'development' ? devPattern : prodPattern;
  
  return {
    load(id) {
      if (pattern.test(id)) {
        // Load environment-specific files
        return fs.readFileSync(id, 'utf-8');
      }
    }
  };
}

suffixRegex

Creates a RegExp that matches strings with a specific suffix by anchoring only at the end of the string.

/**
 * Constructs a RegExp that matches a value that has the specified suffix
 * Automatically escapes special regex characters and anchors with $
 * @param str - The string(s) to match as suffix
 * @param flags - Optional RegExp flags (e.g., 'i', 'g', 'm')
 * @returns RegExp with suffix matching (pattern$)
 */
function suffixRegex(str: string | string[], flags?: string): RegExp;

Parameters:

  • str (string | string[]): The string or array of strings to match as suffix
  • flags (string, optional): Standard RegExp flags

Returns: RegExp with $ anchor for suffix matching

Usage Examples:

import { suffixRegex } from "@rollup/pluginutils";

// Basic suffix matching
suffixRegex('.js'); // /\.js$/
suffixRegex('.test.js'); // /\.test\.js$/

// Multiple suffixes
suffixRegex(['.js', '.ts']); // /(?:\.js|\.ts)$/
suffixRegex(['.worker.js', '.worker.ts']); // /(?:\.worker\.js|\.worker\.ts)$/

// With flags
suffixRegex('.JS', 'i'); // /\.JS$/i

// Automatic escaping
suffixRegex('.d.ts'); // /\.d\.ts$/
suffixRegex('.(test|spec).js'); // /\.\(test\|spec\)\.js$/

// File extension filtering
export default function myPlugin() {
  const jsPattern = suffixRegex(['.js', '.jsx', '.ts', '.tsx']);
  const testPattern = suffixRegex(['.test.js', '.spec.js', '.test.ts', '.spec.ts']);
  
  return {
    transform(code, id) {
      // Only transform JavaScript files
      if (jsPattern.test(id) && !testPattern.test(id)) {
        return { code: transformCode(code) };
      }
    }
  };
}

// Worker file detection
export default function workerPlugin() {
  const workerPattern = suffixRegex(['.worker.js', '.worker.ts']);
  
  return {
    load(id) {
      if (workerPattern.test(id)) {
        // Special handling for worker files
        return `
          const workerCode = ${JSON.stringify(fs.readFileSync(id, 'utf-8'))};
          export default () => new Worker(URL.createObjectURL(
            new Blob([workerCode], { type: 'application/javascript' })
          ));
        `;
      }
    }
  };
}

// Asset file handling
export default function assetPlugin() {
  const imagePattern = suffixRegex(['.png', '.jpg', '.jpeg', '.gif', '.svg']);
  const fontPattern = suffixRegex(['.woff', '.woff2', '.ttf', '.eot']);
  
  return {
    load(id) {
      if (imagePattern.test(id)) {
        // Emit image as asset
        const referenceId = this.emitFile({
          type: 'asset',
          name: path.basename(id),
          source: fs.readFileSync(id)
        });
        
        return `export default import.meta.ROLLUP_FILE_URL_${referenceId};`;
      }
      
      if (fontPattern.test(id)) {
        // Handle font files
        return handleFontFile(id);
      }
    }
  };
}

Common Patterns

Plugin Hook Filters

import { exactRegex, prefixRegex, suffixRegex } from "@rollup/pluginutils";

export default function comprehensivePlugin(options = {}) {
  const {
    entryFiles = ['index.js', 'main.js'],
    sourceDirectories = ['src/', 'lib/'],
    fileExtensions = ['.js', '.ts', '.jsx', '.tsx'],
    excludePatterns = ['.test.', '.spec.', '.stories.']
  } = options;
  
  // Create patterns
  const entryPattern = exactRegex(entryFiles);
  const sourcePattern = prefixRegex(sourceDirectories);
  const extensionPattern = suffixRegex(fileExtensions);
  const excludePattern = new RegExp(excludePatterns.map(p => 
    p.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
  ).join('|'));
  
  return {
    buildStart() {
      console.log('Entry pattern:', entryPattern);
      console.log('Source pattern:', sourcePattern);
      console.log('Extension pattern:', extensionPattern);
    },
    
    transform(code, id) {
      const fileName = path.basename(id);
      const isEntry = entryPattern.test(fileName);
      const isSource = sourcePattern.test(id);
      const hasValidExtension = extensionPattern.test(id);
      const isExcluded = excludePattern.test(id);
      
      if (hasValidExtension && (isEntry || isSource) && !isExcluded) {
        return { code: transformCode(code, { isEntry }) };
      }
    }
  };
}

Virtual Module Router

import { exactRegex, prefixRegex } from "@rollup/pluginutils";

export default function virtualModulePlugin() {
  const exactVirtualPattern = exactRegex([
    'virtual:config',
    'virtual:env',
    'virtual:version'
  ]);
  
  const prefixVirtualPattern = prefixRegex(['virtual:generated-']);
  
  return {
    resolveId(id) {
      if (exactVirtualPattern.test(id) || prefixVirtualPattern.test(id)) {
        return id;
      }
    },
    
    load(id) {
      // Handle exact virtual modules
      if (exactVirtualPattern.test(id)) {
        switch (id) {
          case 'virtual:config':
            return 'export default { apiUrl: "https://api.example.com" };';
          case 'virtual:env':
            return `export const NODE_ENV = "${process.env.NODE_ENV}";`;
          case 'virtual:version':
            return `export const version = "${packageJson.version}";`;
        }
      }
      
      // Handle prefixed virtual modules
      if (prefixVirtualPattern.test(id)) {
        const type = id.replace('virtual:generated-', '');
        return generateVirtualModule(type);
      }
    }
  };
}

File Type Router

import { suffixRegex } from "@rollup/pluginutils";

export default function fileTypePlugin() {
  const patterns = {
    scripts: suffixRegex(['.js', '.ts', '.jsx', '.tsx']),
    styles: suffixRegex(['.css', '.scss', '.sass', '.less']),
    images: suffixRegex(['.png', '.jpg', '.jpeg', '.gif', '.svg']),
    fonts: suffixRegex(['.woff', '.woff2', '.ttf', '.eot']),
    data: suffixRegex(['.json', '.yaml', '.yml', '.xml'])
  };
  
  return {
    load(id) {
      if (patterns.scripts.test(id)) {
        return handleScriptFile(id);
      }
      
      if (patterns.styles.test(id)) {
        return handleStyleFile(id);
      }
      
      if (patterns.images.test(id)) {
        return handleImageFile(id);
      }
      
      if (patterns.fonts.test(id)) {
        return handleFontFile(id);
      }
      
      if (patterns.data.test(id)) {
        return handleDataFile(id);
      }
    }
  };
}

Install with Tessl CLI

npx tessl i tessl/npm-rollup--pluginutils

docs

ast-analysis.md

code-generation.md

file-processing.md

index.md

regex-utilities.md

tile.json