Codemod vs. eslint --fix
Я хочу написать пару сценариев для автоматического обнаружения пропущенных импортов и импорта их на основе корневого каталога. Лучше написать этот скрипт как скрипт codemod или как правило eslint с опцией fix?
2 ответа
Codemods предназначены для миграции, в то время как linting всегда существует для того, чтобы насторожить / предупредить ваших разработчиков о какой-то ошибке, которую они потенциально допустили во время разработки. Оба могут быть использованы вместе.
Для вашего случая я думаю, что вы можете использовать два подхода:
Напишите правило lint, которое обнаруживает проблему, и codemod, чтобы исправить существующие случаи возникновения проблемы. Правило lint гарантирует, что разработчики не пропустят это в будущем.
Напишите правило lint, которое обнаруживает проблему вместе с
--fix
возможность автоматически решить проблему.
Я бы склонялся ко второму подходу, потому что он более перспективен. Вы можете просто использовать это no-unresolved
Править ESLint напрямую, а не писать свои собственные. В любом случае исправление /codemod не является тривиальным и может привести к снижению производительности, если в вашем проекте много каталогов и файлов.
Вы можете комбинировать оба мира и использовать код трансформатор , который может быть использован в качестве плагина для eslint и очень полезно для написания
codemods
, потому что в нем есть вся необходимая инфраструктура:
- тестовый раннер ;
- максимально простой API на основе шаблонов;
- справочник, из которого можно учиться;
- putoutредактор ;
С помощью областей видимости вы можете легко определить, объявлена ли используемая вами переменная или нет.
Вот пример
plugin
который делает то, что вам нужно: @ putout / plugin-declare-undefined-variables он работает следующим образом:
import {template} from 'putout';
export const match = () => ({
'await readFile(__a, __b)': (vars, path) => {
return !path.scope.bindings.readFile;
}
});
export const replace = () => ({
'await readFile(__a, __b)': (vars, path) => {
const programScope = path.scope.getProgramParent();
const importNode = template.ast('import {readFile} from "fs/promises"');
programScope.path.node.body.unshift(importNode);
return path;
}
});
Вот как это выглядит в
putout editor
: