CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-metro-transform-plugins

Transform plugins for Metro bundler that provide code optimization and platform-specific transformations for React Native applications

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

module-system.mddocs/

Module System Transformation

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.

Capabilities

Import Export Plugin

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;

Import Transformations

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;

Export Transformations

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]; }

Template-Based Code Generation

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});
`);

Module Resolution

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'))

Shared Module Optimization

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;

ES Module Detection

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
}

Location Preservation

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>;

Variable Renaming

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'

Module String Names

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

docs

code-generation.md

code-optimization.md

index.md

module-system.md

platform-inlining.md

require-optimization.md

tile.json