La convención que quiero usar en el código base es:
const a = 1; const b = 2;
Sin embargo, hay muchas áreas en el código que están escritas así:
let a = 1, b = 2;
Quiero escribir un codemod, probablemente usando JSCodeshift que pueda cambiar el segundo estilo de declaración de variable al primero. He estado investigando sobre AST y he estado usando AST explorer. Sin embargo, tengo problemas para acceder al declarador de variables "tipo" en el árbol de sintaxis abstracta.
Un ejemplo de algo que he probado es este:
module.exports = function(file, api) { const j = api.jscodeshift; const root = j(file.source); // Step 1: Find all instances of the code to change const instances = root.find(VariableDeclarator.value.kind = 'let'); // Step 2: Apply a code transformation and replace the code instances.forEach(instance => { j(path).replaceWith(VariableDeclarator.value.kind = 'const'); }); return root.toSource(); } }
¡Cualquier ayuda o dirección sería apreciada! ¡Gracias!
Puedes usar Putout
código de salida, en el que estoy trabajando, con @putout/plugin-split-variable-declarations
esta manera:
import putout from 'putout'; const {code} = putout('let a = 1, b = 2;', { plugins: [ 'split-variable-declarations', ['let-to-const', { report: () => 'convert let to const', replace: () => ({ 'let __a = __b': 'const __a = __b', }), }] ] }); console.log(code); // output const a = 1; const b = 2;
Aquí hay un ejemplo de 🐊 Putout Editor
:
Parece que el problema principal que está experimentando es usar la sintaxis correcta cuando usa el método de búsqueda. Por ejemplo, cambiar su
const instances = root.find(VariableDeclarator.value.kind = 'let');
a
const instances = root.find(j.VariableDeclaration, {kind: 'let'});
Debe usar la definición de tipo de api.jscodeshift
.
Un ejemplo completo que hace lo que pides se ve así:
export default function transformer(file, api) { const j = api.jscodeshift; const root = j(file.source); const letDeclarations = root.find(j.VariableDeclaration, {kind: 'let'}); letDeclarations.replaceWith(({value: {declarations}}) => { return declarations.map(dec => j.variableDeclaration(dec.init ? 'const' : 'let', [dec]) ); }); return root.toSource(); }
Esto hará la siguiente transformación de:
let a = 1, b = 2, c; const d = 3; let e = 4; var f = 4; c = 3;
a:
const a = 1; const b = 2; let c; const d = 3; const e = 4; var f = 4; c = 3;
Este codemod solo transformará las declaraciones let que incluyen un inicializador, ya que se requiere para las declaraciones const
.
Vea el ejemplo completo en AST Explorer para jugar con él.