codemods/lib/renameImports.js (38 lines of code) (raw):

module.exports = function renameImports(ast, j, importSource, importMap) { const imports = ast.find(j.ImportDeclaration, {source: {value: importSource}}) const importsByName = {} imports.forEach(decl => { j(decl) .find(j.ImportSpecifier) .forEach(spec => { importsByName[spec.node.imported.name] = spec }) }) for (const [from, to] of Object.entries(importMap)) { const idents = to.split('.') rewriteImport(from, idents[0], idents.slice(1)) } function rewriteImport(from, to, members) { imports.forEach(decl => { j(decl) .find(j.ImportSpecifier, {imported: {name: from}}) .forEach(spec => { if (importsByName[to] && members.length) { // if the destination import already exists and there are members // in this identifier, then this one is a dupe j(spec).remove() } else { // otherwise, we can safely rename this one to the new identifier spec.node.imported.name = to importsByName[to] = spec } }) }) // replace all of the rewritten identifiers with member expressions ast .find(j.Identifier, {name: from}) .filter(id => id.parent.node.type !== 'ImportSpecifier') .replaceWith(memberExpression(to, ...members)) } function memberExpression(ident, ...members) { return members.reduce((expr, member) => { return j.memberExpression(expr, j.identifier(member)) }, j.identifier(ident)) } }