A set of utility functions commonly used by Rollup plugins
—
Essential utilities for handling file paths, extensions, and filtering in Rollup plugin workflows. These functions provide cross-platform file handling and pattern-based filtering capabilities.
Constructs a filter function to determine which modules should be processed by a plugin, using picomatch glob patterns.
/**
* Creates a filter function for determining which modules should be processed
* @param include - Patterns for files to include (if omitted, all files included by default)
* @param exclude - Patterns for files to exclude (takes precedence over include)
* @param options - Configuration options for pattern resolution
* @returns Filter function that returns true if the file should be processed
*/
function createFilter(
include?: FilterPattern,
exclude?: FilterPattern,
options?: { resolve?: string | false | null }
): (id: string | unknown) => boolean;
type FilterPattern = ReadonlyArray<string | RegExp> | string | RegExp | null;Parameters:
include (FilterPattern, optional): Picomatch patterns for files to include. Can be a string, RegExp, or array of patterns. If omitted or empty, defaults to including all files.exclude (FilterPattern, optional): Picomatch patterns for files to exclude. Takes precedence over include patterns.options.resolve (string | false | null, optional): Base directory for pattern resolution:
string: Use as base directory (relative paths resolved against process.cwd())false: Don't resolve patterns (useful for virtual module names)null or omitted: Use process.cwd() as baseUsage Examples:
import { createFilter } from "@rollup/pluginutils";
// Basic usage with include/exclude patterns
const filter = createFilter(
["src/**/*.js", "src/**/*.ts"], // include JS and TS files in src
["**/*.test.*", "**/*.spec.*"], // exclude test files
{ resolve: process.cwd() }
);
// Use in plugin
export default function myPlugin(options = {}) {
const filter = createFilter(options.include, options.exclude);
return {
transform(code, id) {
if (!filter(id)) return; // Skip files that don't match
// Process matching files...
return { code: processCode(code) };
}
};
}
// Virtual modules (no path resolution)
const virtualFilter = createFilter(
["virtual:*"],
null,
{ resolve: false }
);
// RegExp patterns
const regexFilter = createFilter([/\.worker\.js$/]);Adds a file extension to a filename if one doesn't already exist.
/**
* Adds an extension to a module ID if one does not exist
* @param filename - The filename to potentially add an extension to
* @param ext - The extension to add (defaults to '.js')
* @returns The filename with extension added if needed
*/
function addExtension(filename: string, ext?: string): string;Parameters:
filename (string): The filename to check and potentially modifyext (string, optional): The extension to add. Defaults to '.js'Usage Examples:
import { addExtension } from "@rollup/pluginutils";
// Basic usage - adds .js if no extension exists
addExtension('foo'); // 'foo.js'
addExtension('foo.js'); // 'foo.js' (unchanged)
addExtension('foo.bar'); // 'foo.bar' (unchanged)
// Custom extension
addExtension('foo', '.mjs'); // 'foo.mjs'
addExtension('foo.js', '.mjs'); // 'foo.js' (unchanged - already has extension)
// Use in plugin resolveId hook
export default function myPlugin() {
return {
resolveId(id) {
// Ensure all imports have .js extension
return addExtension(id);
}
};
}Converts Windows backslash path separators to forward slashes for cross-platform compatibility.
/**
* Converts path separators to forward slash for cross-platform compatibility
* @param filename - The file path to normalize
* @returns Path with forward slashes
*/
function normalizePath(filename: string): string;Parameters:
filename (string): The file path to normalizeUsage Examples:
import { normalizePath } from "@rollup/pluginutils";
// Windows paths converted to POSIX style
normalizePath('src\\components\\Button.js'); // 'src/components/Button.js'
normalizePath('C:\\Users\\dev\\project\\index.js'); // 'C:/Users/dev/project/index.js'
// POSIX paths unchanged
normalizePath('src/components/Button.js'); // 'src/components/Button.js'
// Use in plugin for consistent path handling
export default function myPlugin() {
return {
transform(code, id) {
const normalizedId = normalizePath(id);
// Use normalized path for logging, caching, etc.
console.log(`Processing: ${normalizedId}`);
return { code };
}
};
}import { createFilter, addExtension, normalizePath } from "@rollup/pluginutils";
export default function myPlugin(options = {}) {
const filter = createFilter(options.include, options.exclude);
return {
resolveId(id, importer) {
// Normalize paths for consistent handling
const normalizedId = normalizePath(id);
// Add extension if missing
const resolvedId = addExtension(normalizedId);
return resolvedId;
},
load(id) {
const normalizedId = normalizePath(id);
// Only load files that match our filter
if (!filter(normalizedId)) return null;
// Load and return file content...
},
transform(code, id) {
const normalizedId = normalizePath(id);
// Filter files for transformation
if (!filter(normalizedId)) return null;
// Transform the code...
return { code: transformedCode };
}
};
}import { createFilter } from "@rollup/pluginutils";
// Multiple include patterns with complex exclusions
const complexFilter = createFilter(
[
"src/**/*.{js,ts,jsx,tsx}", // Source files
"lib/**/*.js", // Library files
/\.worker\.(js|ts)$/ // Worker files (RegExp)
],
[
"**/*.test.*", // Test files
"**/*.spec.*", // Spec files
"**/node_modules/**", // Dependencies
"**/*.d.ts" // Type definitions
],
{ resolve: "/project/root" } // Custom base directory
);
// Use with custom options from plugin configuration
export default function myPlugin(options = {}) {
const filter = createFilter(
options.include || ["**/*.{js,ts}"],
options.exclude || ["node_modules/**"],
{ resolve: options.baseDir || process.cwd() }
);
return {
transform(code, id) {
if (!filter(id)) return;
// Process file...
}
};
}Install with Tessl CLI
npx tessl i tessl/npm-rollup--pluginutils