Tree Transformations
Recipes
Retain First Comment

Retain comment on first line

Problem

When removing or replacing the first statement in a file, it is possible for leading comments at the top of the file to be removed (opens in a new tab).

Solution

To retain the leading comments during a transformation, the comments array on the statement's node must be copied to the next statement's node that will be at the top of the file.

Bad Example

Transform

export default function transformer(file, api) {
  const j = api.jscodeshift;
 
  return j(file.source)
    .find(j.VariableDeclaration)
    .replaceWith(
        j.expressionStatement(j.callExpression(
                j.identifier('foo'), []
            )
        )
    )
    .toSource();
};

In

// Comment on first line
const firstStatement = require('some-module');

Out

foo();

Good Example

Transform

export default function transformer(file, api) {
  const j = api.jscodeshift;
  const root = j(file.source);
 
  const getFirstNode = () => root.find(j.Program).get('body', 0).node;
 
  // Save the comments attached to the first node
  const firstNode = getFirstNode();
  const { comments } = firstNode;
 
  root.find(j.VariableDeclaration).replaceWith(
    j.expressionStatement(j.callExpression(
        j.identifier('foo'),
        []
    ))
  );
 
  // If the first node has been modified or deleted, reattach the comments
  const firstNode2 = getFirstNode();
  if (firstNode2 !== firstNode) {
    firstNode2.comments = comments;
  }
 
  return root.toSource();
};

In

// Comment on first line
const firstStatement = require('some-module');

Out

// Comment on first line
foo();