Switch out imports and component props of a React Component without wasting time. Let a Codemod script handle it.
Codemod is the practice of parsing through code using ASTs and transforming code automagically. This gives developers some sweet superpowers to solve problems efficiently in each file. These scripts benefit developers, PMs, and their organizations:
Below are a few examples of changing an import name, a component name, and adding a component property:
ComponentTransform.js
export default function transformer(file, { jscodeshift: j }, options) {
const source = j(file.source);
/** Transform #1: Change an Input Location **/
// Tranform React Imports for a Button
const reactImports = source
.find(j.ImportDeclaration) // Find all nodes that match a type of `ImportDeclaration`
.filter(path => path.node.source.value === '@old-library') // Filter imports by source equal to the target
reactImports.forEach((
reactImport, // Iterate over react imports
) =>
// Replace the existing node with a new one
j(reactImport).replaceWith(
// Build a new import declaration node based on the existing one
j.importDeclaration(
reactImport.node.specifiers, // copy over the existing import specificers
j.stringLiteral('@new-library'), // Replace the source with our new source
),
),
);
/** Transform #2: Update a specific import name*/
// Build an import specifier
const newImport = j.importSpecifier(j.identifier('Button'));
source
.find(j.ImportDeclaration)
// Find if the import source is the newly transformed import
.filter(path => path.node.source.value === '@new-library')
// Grab the import with the name we want to change
.find(j.ImportSpecifier, {
imported: {
name: 'DeprecatedButton'
}
})
.replaceWith(newImport); // Insert our new import specifier
/** Transform #3: Add Component Props */
source
.find(j.JSXElement,{
openingElement: {
name: {
name: 'DeprecatedButton'
}
}
})
.forEach(element => {
const newComponentTag = j.jsxIdentifier('Button');
const newComponent = j.jsxElement(
// New opening element now relabeled + props transformed
j.jsxOpeningElement(newComponentTag, [
...element.node.openingElement.attributes,
// build and insert our new prop
j.jsxAttribute(j.jsxIdentifier('disabled'), j.stringLiteral('true')),
]),
// New closing element now relabeled
j.jsxClosingElement(newComponentTag, [
...element.node.closingElement,
]),
element.node.children,
);
// Replace our original component with our modified one
j(element).replaceWith(newComponent);
});
return source.toSource();
}