bien, entonces tengo un código que se ve así:
import { wait } from "@testing-library/react"; describe("MyTest", () => { it("should wait", async () => { await wait(() => { console.log("Done"); }); }); }); Quiero cambiar la wait del miembro de importación para que sea waitFor . Puedo cambiarlo en el AST así:
source .find(j.ImportDeclaration) .filter((path) => path.node.source.value === "@testing-library/react") .find(j.ImportSpecifier) .filter((path) => path.node.imported.name === "wait") .replaceWith(j.importSpecifier(j.identifier("waitFor"))) .toSource()Sin embargo, el código de salida tendrá el siguiente aspecto:
import { waitFor } from "@testing-library/react"; describe("MyTest", () => { it("should wait", async () => { await wait(() => { console.log("Done"); }); }); });Estoy buscando una manera de cambiar todos los usos posteriores de esa importación para que coincida con el nuevo nombre
¿Es esto posible con jscodeshift?
Puede hacerlo visitando todos los nodos de CallExpression , filtrando aquellos con el nombre al que se dirige ("esperar") y reemplazándolos con nuevos nodos.
Para encontrar los nodos relevantes, puede recorrer la colección devuelta por el método find() de jscodeshift y agregar su lógica allí, o puede darle a find() un segundo argumento. Este debería ser un predicado usado para filtrar:
const isWaitExpression = (node) => node.callee && node.callee.name === "wait"; // I've used "root" where you used "source" root .find(j.CallExpression, isWaitExpression) Luego puede reemplazar esos nodos con replaceWith() :
const replaceExpression = (path, j) => j.callExpression(j.identifier("waitFor"), path.node.arguments); root .find(j.CallExpression, isWaitExpression) .replaceWith((path) => replaceExpression(path, j)); Puede parecer un poco confuso, pero para crear un nodo CallExpression , llame al método callExpression() desde la API. Tenga en cuenta la carcasa de camello allí.
En conjunto, un transformador que cambia el nombre de "esperar" de RTL a "esperar", tanto la declaración de importación nombrada como cada instancia en la que se llama en el archivo, se puede hacer así:
const isWaitExpression = (node) => node.callee && node.callee.name === "wait"; const replaceExpression = (path, j) => j.callExpression(j.identifier("waitFor"), path.node.arguments); export default function transformer(file, api) { const j = api.jscodeshift; const root = j(file.source); root .find(j.ImportDeclaration) .filter((path) => path.node.source.value === "@testing-library/react") .find(j.ImportSpecifier) .filter((path) => path.node.imported.name === "wait") .replaceWith(j.importSpecifier(j.identifier("waitFor"))); root .find(j.CallExpression, isWaitExpression) .replaceWith((path) => replaceExpression(path, j)); return root.toSource(); }Y aquí hay un enlace a él en AST explorer