babel-plugin-debug-file-path
Version:
A Babel plugin that adds file-path attribute to JSX elements
56 lines (45 loc) • 1.79 kB
JavaScript
const path = require('path');
module.exports = function ({ types: t }) {
return {
visitor: {
Program: {
enter(_, state) {
const filename = state.file.opts.filename;
if (!filename) return;
state.file.__relativePath = path.relative(process.cwd(), filename);
}
},
JSXOpeningElement(pathNode, state) {
if (process.env.NODE_ENV === 'production') return;
// Skip React.Fragment or <> fragments
const openingElement = pathNode.node;
// For React.Fragment written as <React.Fragment>
const isReactFragment =
openingElement.name.type === 'JSXMemberExpression' &&
openingElement.name.object.name === 'React' &&
openingElement.name.property.name === 'Fragment';
// For shorthand fragment <>...</>
const isFragmentShorthand = openingElement.name.type === 'JSXFragment';
// Note: JSXFragment is not a JSXOpeningElement, so you only check JSXMemberExpression here.
// The shorthand fragment doesn't have JSXOpeningElement node, so no need to check separately.
if (isReactFragment) return;
const relativePath = state.file.__relativePath;
if (!relativePath) return;
const lineNumber = openingElement.loc?.start?.line;
if (!lineNumber) return;
// Avoid duplicates
const hasAttr = openingElement.attributes.some(
attr => attr.name && attr.name.name === 'fileLoc'
);
if (hasAttr) return;
// fileLoc="relativePath:lineNumber"
openingElement.attributes.push(
t.jsxAttribute(
t.jsxIdentifier('fileLoc'),
t.stringLiteral(`${relativePath}:${lineNumber}`)
)
);
}
}
};
};