Open skovy opened 3 years ago
I've run into similar issue, when moving children to a different place or mutating children array. Spaces around jsxExpression are not preserved:
Input:
<div> Testing {variable} stuff :) </div>
Output:
<div>Testing{variable}stuff :)
</div>
Example code for jscodeshift with @babel/parser:
export default function transformer(file, api) {
const j = api.jscodeshift;
return j(file.source)
.findJSXElements("div")
.forEach(nodePath => {
nodePath.node.children.push(j.jsxText("\n"));
})
.toSource();
}
Hello @skovy
I am running into same issue. Can you please share some example or code snippet on how can you mutate the original node? Thank you.
For future folks, I encountered this, as well and came up with a solution. Looking at the code all leading and trailing whitespace is removed if there is any non-whitespace text in the JSX text node: https://github.com/benjamn/recast/blob/7f441d2c74d2cd61287fc6b498a9060f5597a27c/lib/printer.ts#L1317
We can work around this by splitting out the whitespace into dedicated JSX text nodes. Here's the little TypeScript function that I wrote to help with this problem:
const getJsxTextNodes = (j: JSCodeshift, text: string) => {
const nodes: JSXText[] = [];
if (/^(\s+)/.test(text)) {
nodes.push(j.jsxText(RegExp.$1));
text = text.trimStart();
}
if (/(\s+)$/.test(text)) {
nodes.push(j.jsxText(text.trimEnd()), j.jsxText(RegExp.$1));
} else if (text) {
nodes.push(j.jsxText(text));
}
return nodes;
};
Hope this helps!
I'm working with jscodeshift, and noticed an issue when re-printing an existing node. I'm creating a codemod to convert a
JSXElement
into another type ofJSXElement
, however, I'd like to re-use the entirechildren
array. Doing so results in a functional change to the code (leading space fromJSXText
node is removed).Here's a basic script to convey what I'm attempting with the latest version (
recast@0.20.4
):Output
The only approach I've found to work is directly mutating the original node. Is it possible to construct an entirely new
JSXElement
, or reusechildren
from another node while retaining the spacing between the closingspan
andText
(</span>[SPACE]Text
)? Reusingchildren
directly would be ideal in this case since the exact child nodes can vary.