Изменение всех объявлений переменных let на const с помощью codemods в большой кодовой базе javascript
В кодовой базе я хочу использовать следующее соглашение:
const a = 1;
const b = 2;
Однако в коде есть много областей, которые написаны следующим образом:
let a = 1,
b = 2;
Я хочу написать codemod, возможно, используя JSCodeshift, который может изменить второй стиль объявления переменных на первый. Я проводил некоторые исследования AST и использую AST explorer. Однако у меня возникают проблемы с доступом к объявителю переменной "kind" в абстрактном синтаксическом дереве.
Вот пример того, что я пробовал:
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();
}
}
Любая помощь или направление будут оценены! Спасибо!
2 ответа
Вы можете использоватьPutout
преобразователь кода, над которым я работаю, с@putout/plugin-split-variable-declarations
Сюда:
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;
Вот пример изPutout Editor
:
Похоже, что основная проблема, с которой вы сталкиваетесь, заключается в использовании правильного синтаксиса при использовании метода find. Например, изменение вашего
const instances = root.find(VariableDeclarator.value.kind = 'let');
к
const instances = root.find(j.VariableDeclaration, {kind: 'let'});
Вы должны использовать определение типа из
api.jscodeshift
.
Полный пример, который делает то, что вы просите, выглядит так:
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();
}
Это сделает следующее преобразование из:
let a = 1,
b = 2,
c;
const d = 3;
let e = 4;
var f = 4;
c = 3;
к:
const a = 1;
const b = 2;
let c;
const d = 3;
const e = 4;
var f = 4;
c = 3;
Этот кодмод будет преобразовывать только объявления let, которые включают инициализатор, поскольку это требуется для
const
декларации.
См . полный пример в AST Explorer , чтобы поиграть с ним.