Hoist current file name for transform-react-jsx-source

For better tooling support it's important to include absolute file name for JSX
elements. However, having them inline will inflate resulting file size, so we
move the file name to a constant declared at the beginning of the file and
reference it from `__source` attribute.
This commit is contained in:
Alex Kotliarskyi 2016-01-19 20:10:53 -08:00
parent ec8f0a224e
commit 9f76cf7c42
2 changed files with 23 additions and 13 deletions

View File

@ -10,30 +10,39 @@
* *
* becomes: * becomes:
* *
* <sometag __source={{fileName: 'this/file.js', lineNumber: 10}}/> * var __jsxFileName = 'this/file.js';
* <sometag __source={{fileName: __jsxFileName, lineNumber: 10}}/>
*/ */
import path from "path";
const TRACE_ID = "__source"; const TRACE_ID = "__source";
const FILE_NAME_VAR = "__jsxFileName";
export default function ({ types: t }) { export default function ({ types: t }) {
function makeTrace(fileName, lineNumber) { function makeTrace(lineNumber) {
const fileNameLiteral = fileName != null ? t.stringLiteral(fileName) : t.nullLiteral();
const fileLineLiteral = lineNumber != null ? t.numericLiteral(lineNumber) : t.nullLiteral(); const fileLineLiteral = lineNumber != null ? t.numericLiteral(lineNumber) : t.nullLiteral();
const fileNameProperty = t.objectProperty(t.identifier("fileName"), fileNameLiteral); const fileNameProperty = t.objectProperty(t.identifier("fileName"), t.identifier(FILE_NAME_VAR));
const lineNumberProperty = t.objectProperty(t.identifier("lineNumber"), fileLineLiteral); const lineNumberProperty = t.objectProperty(t.identifier("lineNumber"), fileLineLiteral);
return t.objectExpression([fileNameProperty, lineNumberProperty]); return t.objectExpression([fileNameProperty, lineNumberProperty]);
} }
function makeFileNameConst(fileName) {
const declaration = t.variableDeclarator(t.identifier(FILE_NAME_VAR), t.stringLiteral(fileName));
return t.variableDeclaration("var", [declaration]);
}
let visitor = { let visitor = {
JSXOpeningElement(node, state) { Program(node, state) {
const id = t.jSXIdentifier(TRACE_ID);
const fileName = state.file.log.filename !== "unknown" const fileName = state.file.log.filename !== "unknown"
? path.relative(__dirname, state.file.log.filename) ? state.file.log.filename
: null; : null;
const trace = makeTrace(fileName, node.container.openingElement.loc.start.line);
node.container.program.body.unshift(makeFileNameConst(fileName));
},
JSXOpeningElement(node) {
const id = t.jSXIdentifier(TRACE_ID);
const trace = makeTrace(node.container.openingElement.loc.start.line);
node.container.openingElement.attributes.push(t.jSXAttribute(id, t.jSXExpressionContainer(trace))); node.container.openingElement.attributes.push(t.jSXAttribute(id, t.jSXExpressionContainer(trace)));
} }

View File

@ -1,4 +1,5 @@
var __jsxFileName = "/I/am/not/sure/how/to/get/path/to/test/fixtures/react-source/basic-sample/actual.js";
var x = <sometag __source={{ var x = <sometag __source={{
fileName: "../test/fixtures/react-source/basic-sample/actual.js", fileName: __jsxFileName,
lineNumber: 1 lineNumber: 1
}} />; }} />;