A Babel plugin adding the ability to rewire module dependencies for testing purposes
npx @tessl/cli install tessl/npm-babel-plugin-rewire@1.2.0babel-plugin-rewire is a Babel plugin that adds the ability to rewire module dependencies for testing purposes. It transforms ES6 modules to expose internal variables and imports through special methods, enabling comprehensive testing by mocking dependencies that would otherwise be inaccessible.
npm install babel-plugin-rewireThe plugin is used as a Babel transformation plugin:
// babel.config.js
module.exports = {
plugins: ["babel-plugin-rewire"]
};Or via CLI:
babel --plugins babel-plugin-rewire src --out-dir libAdd to your Babel configuration:
{
"plugins": ["babel-plugin-rewire"]
}// src/calculator.js
import mathUtils from './mathUtils';
const MULTIPLIER = 2;
export function calculate(a, b) {
return mathUtils.add(a, b) * MULTIPLIER;
}
// test/calculator.test.js
import { calculate, __RewireAPI__ } from '../src/calculator';
describe('calculator', () => {
afterEach(() => {
__RewireAPI__.__ResetDependency__('mathUtils');
__RewireAPI__.__ResetDependency__('MULTIPLIER');
});
it('should use mocked dependencies', () => {
// Mock the imported module
__RewireAPI__.__Rewire__('mathUtils', {
add: (a, b) => a + b + 10
});
// Mock internal variable
__RewireAPI__.__Rewire__('MULTIPLIER', 3);
const result = calculate(5, 3);
expect(result).toBe(54); // (5 + 3 + 10) * 3
});
});babel-plugin-rewire operates through AST transformation and runtime injection:
Configuration options for the Babel plugin itself, including how to exclude certain identifiers from rewiring transformation.
// Plugin factory function signature
function babelPluginRewire({ types: t, template }): {
visitor: VisitorObject;
};
// Plugin options
interface PluginOptions {
ignoredIdentifiers?: string[];
}The runtime API injected into each transformed module, providing methods to mock dependencies, access private variables, and control rewiring state.
// Main rewiring functions (available on module exports)
function __Rewire__(variableName: string, value: any): () => void;
function __GetDependency__(variableName: string): any;
function __ResetDependency__(variableName: string): void;
function __with__(objectMap: Record<string, any>): (callback: () => any) => any;
// API object containing all rewiring methods
interface RewireAPI {
__get__(variableName: string): any;
__GetDependency__(variableName: string): any;
__set__(variableName: string, value: any): () => void;
__set__(objectMap: Record<string, any>): () => void;
__Rewire__(variableName: string, value: any): () => void;
__reset__(variableName: string): void;
__ResetDependency__(variableName: string): void;
__with__(objectMap: Record<string, any>): (callback: () => any) => any;
}
// Global reset function (available in global scope)
function __rewire_reset_all__(): void;// Plugin options for configuration
interface PluginOptions {
/** Array of identifier names to ignore during transformation */
ignoredIdentifiers?: string[];
}
// Visitor object returned by plugin
interface VisitorObject {
Program: {
enter(path: any, state: any): void;
exit(path: any, state: any): void;
};
}
// Revert function returned by __set__ and __Rewire__
type RevertFunction = () => void;
// Callback function for __with__ method
type WithCallback = () => any;
// Object map for bulk rewiring
type RewireObjectMap = Record<string, any>;