A Babel plugin that automatically adds a __self prop to all JSX elements. This development-only plugin helps React generate useful runtime warnings by providing self-reference context to JSX elements, enabling better debugging information in React's development mode.
npm install --save-dev babel-plugin-transform-react-jsx-selfThe plugin is configured through Babel configuration files, not imported directly in code:
.babelrc
{
"plugins": ["transform-react-jsx-self"]
}babel.config.js
module.exports = {
plugins: ["transform-react-jsx-self"]
};This plugin is typically used only in development builds as it serves no purpose in production code.
Development configuration example:
{
"env": {
"development": {
"plugins": ["transform-react-jsx-self"]
}
}
}CLI usage:
babel --plugins transform-react-jsx-self script.jsNode API usage:
require("babel-core").transform("code", {
plugins: ["transform-react-jsx-self"]
});Automatically transforms JSX elements by adding a __self={this} prop to provide React with debugging context.
/**
* Internal constant defining the prop name added to JSX elements
*/
const TRACE_ID = "__self";
/**
* Main Babel plugin factory function that returns a plugin configuration.
* This function is called by Babel when the plugin is loaded.
* @param {Object} api - Babel plugin API object containing types and other utilities
* @param {Object} api.types - Babel types utility for creating AST nodes (destructured as 't')
* @returns {Object} Babel plugin configuration with visitor pattern
*/
export default function ({ types: t }) {
const visitor = {
/**
* Transforms JSX opening elements by adding __self prop
* @param {Object} path - Babel path object containing the JSX node
* @param {Object} path.node - The JSXOpeningElement AST node to modify
*/
JSXOpeningElement({ node }) {
const id = t.jSXIdentifier(TRACE_ID);
const trace = t.thisExpression();
node.attributes.push(t.jSXAttribute(id, t.jSXExpressionContainer(trace)));
}
};
return {
visitor
};
}
/**
* Babel AST Types used by this plugin
*/
interface BabelTypes {
/**
* Creates a JSX identifier AST node
* @param {string} name - The identifier name
* @returns {JSXIdentifier} JSX identifier node
*/
jSXIdentifier(name: string): JSXIdentifier;
/**
* Creates a 'this' expression AST node
* @returns {ThisExpression} This expression node
*/
thisExpression(): ThisExpression;
/**
* Creates a JSX attribute AST node
* @param {JSXIdentifier} name - The attribute name
* @param {JSXExpressionContainer} value - The attribute value
* @returns {JSXAttribute} JSX attribute node
*/
jSXAttribute(name: JSXIdentifier, value: JSXExpressionContainer): JSXAttribute;
/**
* Creates a JSX expression container AST node
* @param {Expression} expression - The contained expression
* @returns {JSXExpressionContainer} JSX expression container node
*/
jSXExpressionContainer(expression: Expression): JSXExpressionContainer;
}Transformation behavior:
Input JSX:
<div>Hello World</div>
<Button onClick={handleClick}>Click me</Button>
<MyComponent prop="value" />Output JSX:
<div __self={this}>Hello World</div>
<Button __self={this} onClick={handleClick}>Click me</Button>
<MyComponent __self={this} prop="value" />Development-only usage (recommended):
{
"env": {
"development": {
"plugins": ["transform-react-jsx-self"]
}
}
}With other React plugins:
{
"plugins": [
"transform-react-jsx-self",
"transform-react-jsx-source",
"transform-react-jsx"
]
}When using with webpack, the plugin integrates through babel-loader configuration:
module.exports = {
module: {
rules: [
{
test: /\.jsx?$/,
loader: "babel-loader",
options: {
plugins: process.env.NODE_ENV === "development"
? ["transform-react-jsx-self"]
: []
}
}
]
}
};