Очистка кода
Две команды для одного и того же ритуала перед коммитом — убрать то, что осталось от отладки и не должно попасть в диф: закомментированный код и заметки (strip-comments), забытые console.log/debugger (console-strip). Обе читают реальное синтаксическое дерево через TypeScript Compiler API, а не ищут текст по регэкспу — строка или шаблонный литерал, который просто похож на комментарий или вызов console.log, никогда не трогается. Обе используют одну модель безопасности: без флагов — только превью в терминале, -y/--yes — реально записать на диск, --diff — показать unified diff вместо простого списка файлов.
strip-comments
Убирает //, /* */, /** */ и <!-- --> из исходников на месте.
devtoolz strip-comments [paths...] [options]Понимает .vue-файлы отдельно: содержимое <script> разбирается тем же TypeScript-парсером, что и обычный .ts-файл, а <!-- --> внутри <template> — построчным сканом, который корректно отличает комментарий на всю строку от комментария, идущего следом за реальной разметкой на той же строке (второй убирается без удаления самой строки).
Реальный вывод — файл со свежим TODO, старым закомментированным блоком и JSDoc над экспортом:
🧰 devtoolz, reporting for duty
Scanned 1 file.
Would strip comments in 1 file(s):
src/formatPrice.ts 7 comments
(nothing written — pass -y to apply, or --dry-run to keep previewing)
── src/formatPrice.ts (7 comments) ─────────────────────────────────
@@ -1,13 +1,5 @@
-// TODO: revisit rounding once finance signs off
-const CURRENCY_SYMBOL = '$' // hardcoded for now, see #482
+const CURRENCY_SYMBOL = '$'
-/**
- * Formats a price in cents as a display string, e.g. 1999 -> "$19.99".
- */
export function formatPrice(cents: number): string {
- // old implementation, kept around just in case:
- // const dollars = Math.floor(cents / 100)
- // const rest = cents % 100
- // return `${CURRENCY_SYMBOL}${dollars}.${rest.toString().padStart(2, '0')}`
const value = (cents / 100).toFixed(2)
return `${CURRENCY_SYMBOL}${value}`Строка const NOTE = 'a URL can contain // without being a comment' в том же файле в диффе не появляется вообще — реальный разбор синтаксиса не путает // внутри строкового литерала с настоящим комментарием.
С --keep-jsdoc тот же файл теряет на один комментарий меньше — /** */ прямо над export function formatPrice остаётся на месте, а TODO-строка и закомментированный блок всё равно уходят:
── src/formatPrice.ts (6 comments) ─────────────────────────────────
@@ -1,4 +1,3 @@
-// TODO: revisit rounding once finance signs off
-const CURRENCY_SYMBOL = '$' // hardcoded for now, see #482
+const CURRENCY_SYMBOL = '$'
/**
@@ -6,8 +5,4 @@
*/
export function formatPrice(cents: number): string {
- // old implementation, kept around just in case:
- // const dollars = Math.floor(cents / 100)
- // const rest = cents % 100
- // return `${CURRENCY_SYMBOL}${dollars}.${rest.toString().padStart(2, '0')}`
const value = (cents / 100).toFixed(2)
return `${CURRENCY_SYMBOL}${value}`Опции
--keep-jsdoc
Не удалять /** */-комментарий, если он стоит прямо над экспортируемым объявлением — так экспортируемые типы/пропсы не теряют подсказки в IDE. Все остальные комментарии, включая /** */ не над экспортом, всё равно удаляются.
--dry-run
Показать превью без записи на диск (то же самое, что запуск вообще без --dry-run и без -y).
-y, --yes
Реально применить изменения. Без этого флага команда только показывает превью.
--diff
Добавить unified diff по каждому изменённому файлу вместо простого списка имён файлов со счётчиком.
--cwd <path>
Корень, от которого резолвятся относительные пути (по умолчанию — текущая директория).
--ext <list>
Через запятую, какие расширения обрабатывать. По умолчанию: .ts,.tsx,.js,.jsx,.cjs,.mjs,.vue.
--ignore <glob>
Дополнительный паттерн игнорирования (можно указать несколько раз) поверх встроенных дефолтов (node_modules, dist, .git и т.п.).
--no-respect-gitignore
Не учитывать .gitignore проекта при обходе файлов.
Пример:
devtoolz strip-comments src --dry-run --diff # что именно изменится
devtoolz strip-comments src --keep-jsdoc -y # применить, сохранив JSDoc над экспортамиconsole-strip
Убирает оставленные по ошибке console.log/console.debug/debugger.
devtoolz console-strip [paths...] [options]console.warn/console.error по умолчанию не трогаются — это часто легитимное продакшен-логирование, не отладочный мусор (список меняется через --methods). Удаляется только вызов, который является отдельным выражением целиком — то, что сидит внутри тела if/while/for без фигурных скобок, или является частью более сложного выражения (const r = console.log(x) || y), не трогается автоматически: такие места перечисляются отдельно, чтобы решение принял человек, а не угадывающая эвристика.
Реальный вывод — функция с четырьмя разными случаями сразу:
🧰 devtoolz, reporting for duty
Scanned 1 file.
Would strip console/debugger statements in 1 file(s):
src/checkout.ts 2 statements
(nothing written — pass -y to apply, or --dry-run to keep previewing)
── src/checkout.ts (2 statements) ───────────────────────────────────
@@ -1,4 +1,3 @@
export function submitOrder(cartTotal: number, userId: string) {
- console.log('submitOrder called', { cartTotal, userId })
if (cartTotal <= 0) console.log('empty cart, skipping')
@@ -10,6 +9,4 @@
}
- debugger
-
return receiptId
}
2 left in place, needs a manual look:
- src/checkout.ts:4:23 — inside a single-statement body without braces — console.log('empty cart, skipping')
- src/checkout.ts:6:37 — part of a larger expression, not its own statement — console.log('charging card')Отдельный вызов и голый debugger удаляются, console.warn остаётся (не в списке по умолчанию), а два неоднозначных случая — внутри if без скобок и часть присваивания — просто перечисляются, без попытки «угадать», что с ними делать.
Опции
--methods <list>
Через запятую, какие методы console удалять. По умолчанию: log,debug. warn/error можно добавить явно:
devtoolz console-strip src --methods log,debug,warn --dry-run --diff--no-debugger
Не удалять голые выражения debugger.
--dry-run
Показать превью без записи на диск.
-y, --yes
Реально применить изменения.
--diff
Unified diff по каждому изменённому файлу.
--cwd <path>
Корень, от которого резолвятся относительные пути.
--ext <list>
Через запятую, какие расширения обрабатывать. По умолчанию: .ts,.tsx,.js,.jsx,.cjs,.mjs,.vue.
--ignore <glob>
Дополнительный паттерн игнорирования (повторяемый) поверх встроенных дефолтов.
--no-respect-gitignore
Не учитывать .gitignore проекта.
Пример:
devtoolz console-strip src --dry-run --diff # что уйдёт, что останется
devtoolz console-strip src --no-debugger -y # применить, не трогая debugger
devtoolz console-strip src --methods log,debug,warn # убрать и console.warn тоже