Transform plugins for Metro bundler that provide code optimization and platform-specific transformations for React Native applications
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
Utility functions for Metro code generation including parameter injection, pseudoglobal variable management, and cache key generation for build optimization.
Simple utility for adding additional parameters to Metro's define() calls in generated bundle code.
/**
* Adds additional parameters to the end of define calls in Metro bundle code
* @param code - The source code containing a define() call
* @param paramsToAdd - Additional parameters to append
* @returns Modified code with additional parameters
*/
function addParamsToDefineCall(
code: string,
...paramsToAdd: Array<mixed>
): string;Usage Examples:
const { addParamsToDefineCall } = require("metro-transform-plugins");
// Basic usage - add metadata to define call
const originalCode = `define(['dep1', 'dep2'], function(a, b) {
return a + b;
});`;
const enhanced = addParamsToDefineCall(
originalCode,
{ meta: true, version: '1.0.0' },
['extra', 'data'],
undefined,
null
);
// Result:
// define(['dep1', 'dep2'], function(a, b) {
// return a + b;
// },{"meta":true,"version":"1.0.0"},["extra","data"],undefined,null);
// Practical use case - adding dependency map
const withDependencyMap = addParamsToDefineCall(
moduleCode,
dependencyMap,
inverseDependencies
);Handles different parameter types with proper JSON serialization:
/**
* Parameter serialization rules:
* - Objects and arrays: JSON.stringify()
* - undefined: 'undefined' (string literal)
* - null: 'null' (JSON serialized)
* - Other values: JSON.stringify()
*/
// Examples of parameter handling:
addParamsToDefineCall(code,
{ key: 'value' }, // → {"key":"value"}
['array', 'data'], // → ["array","data"]
undefined, // → undefined (literal)
null, // → null
'string', // → "string"
42, // → 42
true // → true
);Shortens long parameter names in Metro's module wrapper functions to reduce bundle size.
/**
* Normalizes and shortens pseudoglobal variable names in Metro modules
* @param ast - Babel AST of the module
* @param options - Configuration options
* @returns Array of renamed parameter names
*/
function normalizePseudoglobals(
ast: BabelNode,
options?: NormalizePseudoGlobalsOptions
): ReadonlyArray<string>;
interface NormalizePseudoGlobalsOptions {
/** Array of names that cannot be shortened */
reservedNames: ReadonlyArray<string>;
}Usage Examples:
const babel = require("@babel/core");
const { normalizePseudoglobals } = require("metro-transform-plugins");
// Original Metro module wrapper
const moduleCode = `
(function(XMLHttpRequest, FileSystemInterface, DatabaseConnection) {
// Module code using long parameter names
const xhr = new XMLHttpRequest();
const fs = FileSystemInterface.create();
const db = DatabaseConnection.connect();
});
`;
const ast = babel.parseSync(moduleCode);
const renamedParams = normalizePseudoglobals(ast, {
reservedNames: ['require', 'module', 'exports']
});
// Result: ['x', 'f', 'd'] - shortened semantic names
// Transformed code:
// (function(x, f, d) {
// const xhr = new x();
// const fs = f.create();
// const db = d.connect();
// });Generates meaningful short names based on original parameter names:
/**
* Semantic name generation algorithm
* Extracts meaningful characters from original names
*/
// Examples of name shortening:
'XMLHttpRequest' → 'x' // First letter
'FileSystemInterface' → 'f' // First letter of each word
'DatabaseConnection' → 'd' // First letter
'React' → 'r' // Simple first letter
'MyCustomUtility' → 'm' // First letter
'HTTPClient' → 'h' // First letter
// Pattern matching (case insensitive):
// - ^[^A-Za-z]*([A-Za-z]) - First letter after non-letters
// - ([A-Z])[a-z] - Capital letter followed by lowercase
// - ([A-Z])[A-Z]+$ - Capital letter in all-caps sequenceHandles naming conflicts and reserved names:
/**
* Conflict resolution strategy
* Ensures unique names and respects reserved names
*/
// When conflicts occur:
'XMLHttpRequest' → 'x'
'XMLParser' → 'x2' // generateUid creates unique name
// Reserved names are never used:
const options = { reservedNames: ['r', 'x', 'm'] };
'React' → 'r2' // 'r' is reserved, so generates alternative
// Scope-aware renaming:
// Uses Babel's scope.rename() to properly update all references
// Handles nested scopes correctly
// Updates program scope references and UIDsProvides file paths for Metro's cache key generation system:
/**
* Returns array of file paths used for transform plugin cache keys
* @returns Array of absolute file paths for cache key generation
*/
function getTransformPluginCacheKeyFiles(): ReadonlyArray<string>;Usage Examples:
const { getTransformPluginCacheKeyFiles } = require("metro-transform-plugins");
// Get cache key files for Metro configuration
const cacheKeyFiles = getTransformPluginCacheKeyFiles();
// Result array contains paths to:
// - /path/to/metro-transform-plugins/src/index.js
// - /path/to/metro-transform-plugins/src/constant-folding-plugin.js
// - /path/to/metro-transform-plugins/src/import-export-plugin.js
// - /path/to/metro-transform-plugins/src/inline-plugin.js
// - /path/to/metro-transform-plugins/src/inline-requires-plugin.js
// - /path/to/metro-transform-plugins/src/normalizePseudoglobals.js
// Use in Metro configuration:
module.exports = {
transformer: {
babelTransformerPath: require.resolve('./custom-transformer'),
// Include plugin files in cache key calculation
additionalFiles: getTransformPluginCacheKeyFiles()
}
};Correctly identifies Metro's module wrapper function structure:
/**
* Metro module wrapper pattern detection
* Identifies the specific AST structure of Metro modules
*/
// Expected Metro module structure:
// Program
// └── ExpressionStatement
// └── CallExpression (function invocation)
// └── FunctionExpression (module wrapper)
// ├── params[] (pseudoglobal parameters)
// └── body (module content)
// Only processes modules matching this exact structure
// Safely ignores non-Metro code patternsHandles the specific parameter patterns used by Metro:
// Typical Metro pseudoglobal parameters:
['__d', 'global', 'require', 'module', 'exports', 'XMLHttpRequest', 'fetch', ...]
// Processing logic:
// 1. Extract parameter names from function signature
// 2. Filter out reserved names (like 'require', 'module', 'exports')
// 3. Generate semantic short names for remaining parameters
// 4. Check for conflicts and resolve using generateUid
// 5. Rename all references using Babel scope manipulation
// 6. Return array of final shortened namesProvides sophisticated variable renaming capabilities:
/**
* Advanced scope-aware renaming
* Handles complex variable binding scenarios
*/
// Checks multiple binding types:
scope.hasLabel(name) // Label declarations (label:)
scope.hasBinding(name) // Variable bindings (var, let, const)
scope.hasGlobal(name) // Global variable references
scope.hasReference(name) // Any reference to the name
// Program scope management:
// Updates program scope references map
// Updates program scope UIDs map
// Ensures Metro's module system compatibility
// Graceful handling of edge cases:
// - Names that can't be shortened (throws descriptive errors)
// - Duplicate semantic matches (generates unique alternatives)
// - Reserved name conflicts (uses generateUid for alternatives)