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
Transforms ES6 import/export statements into CommonJS require/exports for Metro's module system, enabling modern JavaScript syntax while maintaining compatibility with Metro's bundling pipeline.
Converts ES6 modules to CommonJS format with customizable import/export handling.
/**
* Creates a Babel plugin that transforms ES6 import/export to CommonJS
* @param context - Babel plugin context with types utility
* @returns Babel plugin object with comprehensive import/export handling
*/
function importExportPlugin(context: {
types: Types
}): PluginObj<State>;
interface ImportExportPluginOptions {
/** Name of the default import function (e.g., 'require') */
importDefault: string;
/** Name of the import all function (e.g., 'require') */
importAll: string;
/** Whether to resolve module paths to absolute paths */
resolve: boolean;
/** Output metadata object to track ES module status */
out?: { isESModule: boolean };
}
interface State {
exportAll: Array<{ file: string; loc?: BabelSourceLocation }>;
exportDefault: Array<{ local: string; loc?: BabelSourceLocation }>;
exportNamed: Array<{ local: string; remote: string; loc?: BabelSourceLocation }>;
imports: Array<{ node: Statement }>;
importDefault: BabelNode;
importAll: BabelNode;
opts: ImportExportPluginOptions;
}Usage Examples:
const babel = require("@babel/core");
const { importExportPlugin } = require("metro-transform-plugins");
const code = `
import React, { useState } from 'react';
import * as Utils from './utils';
export default function MyComponent() {
return <div>Hello</div>;
}
export const version = '1.0.0';
`;
const transformed = babel.transformSync(code, {
plugins: [
importExportPlugin({
types: babel.types,
opts: {
importDefault: 'require',
importAll: 'require',
resolve: false
}
})
]
});
// Result:
// Object.defineProperty(exports, '__esModule', {value: true});
// var React = require('react');
// var useState = require('react').useState;
// var Utils = require('./utils');
// function MyComponent() { return React.createElement('div', null, 'Hello'); }
// var version = '1.0.0';
// exports.default = MyComponent;
// exports.version = version;Handles all ES6 import patterns and converts them to CommonJS require calls:
/**
* Import declaration processing
* Converts various import patterns to require() calls
*/
// Default imports: import React from 'react'
// → var React = require('react');
// Named imports: import { useState, useEffect } from 'react'
// → var useState = require('react').useState;
// → var useEffect = require('react').useEffect;
// Namespace imports: import * as React from 'react'
// → var React = require('react');
// Side effect imports: import './styles.css'
// → require('./styles.css');
// Mixed imports: import React, { useState } from 'react'
// → var React = require('react');
// → var useState = require('react').useState;Converts ES6 export syntax to CommonJS exports:
/**
* Export declaration processing
* Handles default, named, and re-exports
*/
// Default exports: export default function() {}
// → function _default() {}
// → exports.default = _default;
// Named exports: export const value = 42;
// → const value = 42;
// → exports.value = value;
// Export from: export { something } from './other'
// → var _temp = require('./other');
// → exports.something = _temp.something;
// Export all: export * from './other'
// → var _required = require('./other');
// → for (var key in _required) { exports[key] = _required[key]; }Uses Babel templates for consistent and reliable code generation:
/**
* Babel templates used internally for code generation
*/
// Import template: var LOCAL = IMPORT(FILE);
const importTemplate = template.statement(`var LOCAL = IMPORT(FILE);`);
// Named import template: var LOCAL = require(FILE).REMOTE;
const importNamedTemplate = template.statement(`var LOCAL = require(FILE).REMOTE;`);
// Side effect template: require(FILE);
const importSideEffectTemplate = template.statement(`require(FILE);`);
// Export template: exports.REMOTE = LOCAL;
const exportTemplate = template.statement(`exports.REMOTE = LOCAL;`);
// ES module marker: Object.defineProperty(exports, '__esModule', {value: true});
const esModuleExportTemplate = template.statement(`
Object.defineProperty(exports, '__esModule', {value: true});
`);Optional module path resolution to fully-qualified paths:
/**
* Path resolution functionality
* @param node - The module specifier node
* @param resolve - Whether to resolve to absolute path
* @returns Expression node with resolved path or original node
*/
function resolvePath<TNode extends Node>(
node: TNode,
resolve: boolean
): BabelNodeExpression | TNode;
// When resolve: true
// import './utils' → require(require.resolve('./utils'))
// import 'lodash' → require(require.resolve('lodash'))Optimizes multiple named imports from the same module:
// Before optimization
import { a, b, c, d } from 'large-module';
// After optimization
var _largeModule = require('large-module');
var a = _largeModule.a;
var b = _largeModule.b;
var c = _largeModule.c;
var d = _largeModule.d;Automatically marks transformed modules as ES modules:
/**
* ES Module metadata tracking
* Adds __esModule property when exports are detected
*/
// When any exports are found:
Object.defineProperty(exports, '__esModule', {value: true});
// Updates options.out.isESModule if provided
if (state.opts.out) {
state.opts.out.isESModule = true; // or false if no exports
}Maintains source location information for debugging and source maps:
/**
* Source location preservation
* @param node - AST node or array of nodes
* @param loc - Source location to apply
* @returns Node(s) with preserved location information
*/
function withLocation<TNode extends BabelNode>(
node: TNode | ReadonlyArray<TNode>,
loc?: BabelNodeSourceLocation
): TNode | Array<TNode>;Renames conflicting variables to avoid namespace collisions:
// Automatically renames variables that might conflict with Metro's module wrapper:
// - 'module' → '_module'
// - 'global' → '_global'
// - 'exports' → '_exports'
// - 'require' → '_require'Handles modern JavaScript module string names syntax:
// Throws error for unsupported module string names:
// export { "module-name" as something } from './module';
// → Error: Module string names are not supported