code: function renameIdentifier(ast, oldName, newName, defNode) {
    // Summary:
    //  Rename identifiers with oldName in ast
    const changes = [];
    if (!defNode) {
      let scope;
      traverse(ast, {
        Identifier(path) {
          if (path.node.name === oldName) {
            scope = path.scope;
            path.stop();
          }
        },
      });
      if (!scope) return changes;
      defNode = getDefNode(oldName, scope);
    }
  
    function rename(path) {
      if (
        path.node.name === oldName &&
        path.key !== 'imported' && // it should NOT be imported specifier
        getDefNode(path.node.name, path.scope) === defNode
      ) {
        path.node.name = newName;
        changes.push({
          start: path.node.start,
          end: path.node.end,
          replacement: newName,
        });
      }
    }
    traverse(ast, {
      JSXIdentifier: rename,
      Identifier: rename,
    });
    return changes;
  }
docs: Rename an top scope identifier in a module. If first finds the definition node of the given name.
  Then rename all identifiers those refer to that definition node.
  @param {string} ast - Which module to rename an identifier.
  @param {string} oldName - The old identifier name.
  @index {string} newName - The new identifier name.
  @index {object} defNode - The definition node of the identifier. If not provided, then find the first definition in the module.
  @alias module:refactor.renameIdentifier
  @example
  // import { m1 } from './some-module';
  // m1.doSomething();
  // function () { const m1 = 'abc'; }
  const refactor = require('rekit-core').refactor;
  refactor.renameIdentifier(file, 'm1', 'm2');
  // => import { m2 } from './some-module';
  // => m2.doSomething();
  // => function () { const m1 = 'abc'; } // m1 is not renamed.