@vernikr/size-report 1.1.1 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -18,6 +18,53 @@
18
18
  где за основу взяты `fixtures/synthetic/config.json`, метрики — `raw`, `min`, `tok`, а
19
19
  способ минификации — `strip` или `esbuild`.
20
20
 
21
+ ## 1.2.0 — 2026-09-15
22
+
23
+ Выпуск причины, а не измерения: проверка («таблица совпадает с историей?») теперь
24
+ называет другой счёт, когда он есть, — и делает это всегда, а не только там, где
25
+ всё сошлось. Нашлось это прогулкой по собственной инструкции (`WORKLOG.md` §54),
26
+ починено по правилу «нарушение старше приближения» (`REFACTOR.md` R-4.23).
27
+
28
+ - **`size` и `size check` печатают заметку о датчике всегда.** Раньше заметка
29
+ печаталась только при благополучном вердикте: если отчёт собран с настоящим
30
+ минификатором, а прогон идёт без него (установка без необязательных
31
+ зависимостей, платформа без `esbuild`), числа честно расходились, а причины
32
+ «счёт другой» в выводе не было вовсе — читатель видел расхождение строки
33
+ подписи и ничего о том, откуда оно.
34
+ - **Вердикт остаётся первым по важности.** Нарушение старше приближения — тот же
35
+ порядок, что у `size check` и `size doctor`: код **4** утверждал бы, что
36
+ расхождение объясняется датчиком, а этого никто не проверял (расхождение может
37
+ быть и правкой мимо отчёта). Поэтому ответ в этом случае — по-прежнему **код 1**
38
+ плюс заметка с починкой: кода выхода выпуск не меняет ни в одном случае.
39
+ - Ни сборка отчёта, ни его форма, ни смысл настроек не тронуты. Остальное в этом
40
+ выпуске — не про поставку: выпуск по тегу из CI (R-4.24) и снятые цели по
41
+ времени у набора проверок (R-5.8) касаются репозитория пакета, а не того, что
42
+ устанавливают.
43
+ - Номер **1.2.0** назван владельцем пакета; по строгому SemVer содержимое —
44
+ исправление (PATCH): новых возможностей в поставке нет.
45
+
46
+ ### Что изменится в числах
47
+
48
+ **Ничего.** Таблица ниже та же, что у 1.1.0 и 1.1.1, до последней клетки: этот
49
+ выпуск меняет текст под расхождением, а не числа. Замер на фикстуре — тот же
50
+ (16 коммитов, 10 колонок), доказано не словом: артефакт (22 112 Б), страница
51
+ (59 376 Б) и оба замороженных эталона не переснимались, а `--json` и артефакт
52
+ побайтово равны эталону на фикстуре и на живой истории проекта-потребителя.
53
+
54
+ | Файл | raw | min со strip | min с esbuild | tok |
55
+ |---|---|---|---|---|
56
+ | code.js | 735 | 276 | 185 | 168 |
57
+ | modern.js | 246 | 51 | 45 | 44 |
58
+ | config.mjs | 172 | 45 | 40 | 40 |
59
+ | заметки.md | 306 | 303 | 303 | 53 |
60
+ | crlf.txt | 63 | 60 | 60 | 10 |
61
+ | package.json | 87 | 69 | 69 | 34 |
62
+ | style.css | 156 | 55 | 43 | 38 |
63
+ | table.toml | 300 | 299 | 299 | 52 |
64
+ | empty.js | 0 | 0 | 0 | 0 |
65
+ | WORKLOG.md | 446 | 439 | 439 | 101 |
66
+ | **ИТОГО** | **2511** | **1597** | **1483** | **540** |
67
+
21
68
  ## 1.1.1 — 2026-09-15
22
69
 
23
70
  Выпуск имени, а не измерения: пакет переехал в область владельца
package/README.md CHANGED
@@ -100,7 +100,7 @@
100
100
  есть в дереве, таблица файлов сходится с ним в обе стороны),
101
101
  `test/docs-commands.test.js` (команды и ключи есть в справке, причины отказа
102
102
  совпадают с реестром движка, ссылки на разделы ведут в существующие),
103
- `test/docs-numbers.test.js` (числа проверок и целей — факт) и
103
+ `test/docs-numbers.test.js` (числа проверок — факт) и
104
104
  `test/docs-pin.test.js` (пример установки ведёт на ревизию, чья справка знает
105
105
  названные команды), а с выпуском добавился пятый — `test/changelog.test.js`
106
106
  (версия выпуска — версия манифеста, а таблица «что изменится в числах» — не
@@ -176,8 +176,7 @@
176
176
  86 мс на каждую клетку, плюс разбор опирается на экспериментальный API (без него
177
177
  гард отступает к прежнему `node --check` — медленнее, но не мягче).
178
178
  Прогон подешевел втрое: `pnpm test` 15,7 → **5,6 с** (тогда в наборе было 39
179
- проверок), `pnpm run parity:live` 23,8 → **8,3 с**. Бюджет времени переснят с
180
- запасом на следующую проверку, а не под сегодняшнее число: набор стоит
179
+ проверок), `pnpm run parity:live` 23,8 → **8,3 с**. Набор стоит
181
180
  **23,4–29,9 с** при 124 проверках — в зависимости от загрузки машины: окна с
182
181
  загрузкой 18–70 несравнимы (в спокойном — 23,4–24,2 с, в занятых — 26,6–29,9 с;
183
182
  в среде без настроек git — 27,4 с, с `CI=1` — 29,9 с), и это свойство окна, а не
@@ -193,41 +192,38 @@
193
192
  прибавило** — 23,2 с и до него, и после: обе новые проверки измерены отдельным
194
193
  прогоном, а не выведены из разброса. Из общего времени **+8,5 с** — десять проверок хука
195
194
  (`test/hook.test.js`: сам он идёт 17,9–18,5 с и становится самым долгим файлом
196
- набора, а та же ревизия без него — 15,8–16,6 с при 107 проверках). Цель не
197
- двигалась, и это решение, а не пропуск: цель тогда была одна — полный набор
198
- **≤ 28 с** (запас 2,3 с) — измеренное в неё укладывается, а поднимают цель по делу и с измерением,
199
- а не под занятую машину: интеграционные
195
+ набора, а та же ревизия без него — 15,8–16,6 с при 107 проверках). Интеграционные
200
196
  прогоны (клон, коммиты, слияние, отказы) дешевле не сделать, не ослабив проверку.
201
- `pnpm run parity:live` **≤ 15 с** (9,3 с в обеих средах). Замеры, машина и разброс —
197
+ `pnpm run parity:live` 9,3 с в обеих средах. Замеры, машина и разброс —
202
198
  `REFACTOR.md` §5.
203
199
 
204
- **Прогонов два, и у каждого своя цель** (`REFACTOR.md` R-5.5). Цена проверки в этом
205
- наборе — не объём файла, а сколько раз файл запускает инструмент и git: запуск — это
206
- процесс Node, а клон фикстуры и сборка артефакта — сотни миллисекунд. Поэтому
207
- быстрый прогон собирает то, что доказывает по прочитанному (исходники, дерево,
208
- справка, эталонные числа на общей фикстуре), а полный добавляет то, что гоняет
209
- инструмент по многу раз на своих клонах, коммитит и ставит хуки; причина для каждого
210
- дорогого файла названа построчно в `tools/suites.js`, там же снимок стоимостей
211
- (перемерить — `pnpm run suites:measure`).
212
-
213
- | Прогон | Команда | Проверок | Цель |
214
- |---|---|---|---|
215
- | Быстрый — каждая правка | `pnpm test` | **57 из 131** | **≤ 10 с** |
216
- | Полный — выкладка и CI | `pnpm test:all` | **131** | **≤ 32 с** |
217
-
218
- Ни одна проверка не потеряна и не ослаблена: полный прогон запускает все 132 теми же
200
+ **Прогонов два, и выбор между ними по цене файла, а не по алфавиту**
201
+ (`REFACTOR.md` R-5.5). Цена проверки в этом наборе — не объём файла, а сколько раз
202
+ файл запускает инструмент и git: запуск — это процесс Node, а клон фикстуры и сборка
203
+ артефакта — сотни миллисекунд. Поэтому быстрый прогон собирает то, что доказывает по
204
+ прочитанному (исходники, дерево, справка, эталонные числа на общей фикстуре), а
205
+ полный добавляет то, что гоняет инструмент по многу раз на своих клонах, коммитит и
206
+ ставит хуки; причина для каждого дорогого файла названа построчно в
207
+ `tools/suites.js`.
208
+
209
+ | Прогон | Команда | Проверок |
210
+ |---|---|---|
211
+ | Быстрый — каждая правка | `pnpm test` | **57 из 135** |
212
+ | Полный — выкладка и CI | `pnpm test:all` | **135** |
213
+
214
+ Ни одна проверка не потеряна и не ослаблена: полный прогон запускает все 135 теми же
219
215
  файлами, а быстрый берёт их часть. Умолчание — полный: файл становится быстрым только
220
216
  явно и с причиной, поэтому новое дорогое не может тихо уехать в быстрый. Стерегут это
221
- двое, и по-разному: `test/suites.test.js` — объявление (полнота классификации,
222
- причины, потолок стоимости быстрого файла), а сам прогон (`tools/run-tests.js`)
223
- замер: он печатает стоимость каждого файла своим запуском, складывает числа проверок
224
- и валится, если вышел за цель вдвое. Снимок стоимости проверяется только замером,
225
- и это его законное место: подделанная стоимость у быстрого файла объявление проходит,
226
- а прогон её ловит. Цель при этом не порог: занятое окно растягивает прогон, и
227
- прогон, не уложившийся в цель, говорит это словами («ЦЕЛЬ НЕ ДОСТИГНУТА»), а не
228
- показывает зелёную галку при 29 с. CI зовёт полный прогон дваждыобычной средой и
229
- без настроек машины. Числа и цели в этой таблице сверяются сторожем документации
230
- (`test/docs-numbers.test.js`), а не живут второй копией без присмотра.
217
+ объявление `test/suites.test.js` (полнота классификации и причина у каждого файла) и
218
+ сторож документации `test/docs-numbers.test.js` (числа в таблице выше).
219
+
220
+ **Целей по времени у прогонов нет, и это решение, а не пропуск.** Секунды зависят от
221
+ окна машина бывает под очень разной нагрузкой, поэтому ни набор, ни CI за время
222
+ не валятся, и документ секунд не обещает: `pnpm run suites:measure` печатает
223
+ длительность каждого файла отдельным прогоном сам прогон печатает её рядом с
224
+ галочкой), но это измерение, а не порог. Разделение держится признаком файлачем он
225
+ занят, а не сколько идёт. CI зовёт полный прогон дважды: обычной средой и без настроек
226
+ машины (`GIT_CONFIG_GLOBAL=/dev/null`).
231
227
 
232
228
  **Обещанное пакетом сведено к факту.** Список поставки называл четыре пути,
233
229
  которых в репозитории нет (`dist/`, `templates/`, `CHANGELOG.md`, `LICENSE`):
@@ -249,7 +245,22 @@ fixture`) и больше не зависит ни от того, держит
249
245
  Секретов job не требует: история потребителя лежит в репозитории бандлом на той
250
246
  же ревизии, что записана в эталоне (`fixtures/live/`), а пересъём идёт во временный
251
247
  каталог и сверяется с закоммиченным — рабочее дерево остаётся чистым. Матрицы по
252
- версиям Node и публикаций нет намеренно: этот проход про контроль.
248
+ версиям Node нет намеренно: этот проход про контроль.
249
+
250
+ **Выпуск — это тег (`.github/workflows/release.yml`).** `git push origin v1.2.3`
251
+ прогоняет тот же полный набор, сверяет версию манифеста с тегом, проверяет работу
252
+ из собранного пакета и отправляет его в реестр — без секрета и без кода из
253
+ аутентификатора: публикация идёт по удостоверению GitHub Actions (trusted
254
+ publishing), которое npm принимает вместо токена. Одна настройка делается человеком
255
+ и один раз: на npmjs.com в настройках пакета (Trusted Publisher) нужно назвать
256
+ владельца, репозиторий и файл `release.yml`. Черновой прогон из Actions («Run
257
+ workflow»: по умолчанию он ничего не публикует) проходит весь список до самого пути
258
+ публикации — гоняет полный набор, проверяет работу из тарболла и собирает пакет на
259
+ черновой версии (`1.1.1` → `1.1.2-draft.0`, чтобы реестр не отказал в уже выпущенном
260
+ номере), — и это же стережёт `test/release.test.js` со стороны текста. Только настроен
261
+ ли издатель, он не проверяет: `--dry-run` не обменивается удостоверением и проходит
262
+ вообще без учётных данных (проверено в пустом каталоге: код 0 без токена). Это делает
263
+ первый настоящий тег.
253
264
 
254
265
  Первым же прогоном CI окупился: шаг живого паритета упал не на расхождении чисел,
255
266
  а на самой проверке — вывод процессов собирался как строка, и многобайтовый символ,
@@ -441,6 +452,7 @@ deльт задан один раз и по артефакту: рост зел
441
452
  | `tools/pack-check.js` | Собирает тарболл и проверяет, что из него всё работает: все исходники доехали, числа, артефакт и страница — как из репозитория (`pnpm run pack:check`) |
442
453
  | `tools/check-standards.js` | Проверяет, что оба эталона воспроизводятся: пересъём идёт в никуда и сверяется с закоммиченным (наши файлы — побайтово, бандл — по содержимому) и что бандл живой истории несёт `HEAD` (`pnpm run check:standards`) |
443
454
  | `.github/workflows/ci.yml` | CI: семь шагов на каждый пуш и запрос правки — те же команды, что локально, без секретов и матриц |
455
+ | `.github/workflows/release.yml` | Выпуск по тегу: тот же полный набор, сверка версии манифеста с тегом и публикация в реестр по удостоверению GitHub Actions — без секрета и без кода из аутентификатора |
444
456
  | `templates/` | То, что проект берёт как есть: `size-report.config.json` (черновик настроек), `ci.yml` (описание проверки) и `README.md` (куда что кладётся и что в них менять); едут в поставке и стерегутся `pack:check` и `test/templates.test.js` |
445
457
  | `fixtures/parity/` | Эталон с `safe-resets` на коммите `bd6ef9d`: 95 строк × 27 колонок. Копия реализации, которой он снят, в дереве не лежит — её байты живут в истории и берутся оттуда по требованию (`REFACTOR.md` R-1.5) |
446
458
  | `fixtures/synthetic/` | Бандл фикстуры на 16 коммитов, её конфиг, эталонные числа и хеш артефакта |
@@ -479,9 +491,10 @@ deльт задан один раз и по артефакту: рост зел
479
491
  | `test/api.test.js` | Публичный API пакета: список имён заморожен, разбиение не имеет права его менять |
480
492
  | `eslint.config.js` | Правила оформления: те же, что у проекта-потребителя, плюс запрет склейки операторов в строке (`pnpm run lint`, `pnpm run lint:strict`) |
481
493
  | `tools/harness.js` | Обвязка проверок: пути, клоны фикстуры (в том числе общий на набор и с CRLF), запуск инструмента, разбор отказов, хеши |
482
- | `tools/suites.js` | Разделение набора: какие файлы идут в быстрый прогон (с причиной и снимком стоимости), почему каждый дорогой — в полном, и цели обоих прогонов |
483
- | `tools/run-tests.js` | Прогон набора (`pnpm test`, `pnpm test:all`, `pnpm run suites:measure`): стоимость каждого файла своим замером, сверка числа проверок, граница бюджета |
494
+ | `tools/suites.js` | Разделение набора: какие файлы идут в быстрый прогон (с причиной для каждого), почему каждый дорогой — в полном |
495
+ | `tools/run-tests.js` | Прогон набора (`pnpm test`, `pnpm test:all`, `pnpm run suites:measure`): длительность каждого файла своим замером и сверка числа проверок |
484
496
  | `tools/docs-facts.js` | Чтение фактов из документации — один слой на четыре проверки сторожа: что документ называет (пути, зовы, адреса разделов) против того, что есть в репозитории |
497
+ | `tools/yaml.js` | Разбор подмножества YAML — один разборщик на два сторожа описаний (`templates/ci.yml` и `.github/workflows/release.yml`): вне подмножества — ошибка, а не молча пропущенная строка, включая двоеточие с пробелом в незакавыченном значении (именно оно делало описание выпуска неразбираемым, пока проверка искала подстроки) |
485
498
  | `tools/refusals.js` | Каталог отказов: по строке на каждый — причина, код выхода, обязательные фразы вывода, **что отказ советует** (`advice`: `run` — команда, `template` — форма с подстановкой, `manual` — действие человека с причиной, `coveredBy` — отдан другой проверке), а для непроверяемого — почему; карты мест отказа (`SITES`, `PRINTED`) держат числа, чтобы новый отказ не появился молча, а маркеры совета — чтобы не появился молча новый совет |
486
499
  | `test/parity.test.js` | Паритет движка с эталоном: числа, артефакт, локаль |
487
500
  | `test/frozen.test.js` | Замороженная копия: та ли это ревизия, с которой снят эталон, и воспроизводит ли она его |
@@ -496,9 +509,10 @@ deльт задан один раз и по артефакту: рост зел
496
509
  | `test/guard.test.js` | Разбор модуля: идёт потоком, оба пути дают один вердикт, отступление работает без файла потока, сотни разборов дешевле запуска |
497
510
  | `test/runner.test.js` | Чтение вывода процесса: куски склеиваются буферами, а не приклеиваются к строке — многобайтовый символ на границе кусков не превращается в два символа-заменителя |
498
511
  | `test/git-pins.test.js` | Сторож границы git: прямых вызовов git без общего списка закреплений нет, и незакреплённое чтение показывается свидетелем (путь кавычками) |
499
- | `test/docs-paths.test.js`, `test/docs-commands.test.js`, `test/docs-numbers.test.js`, `test/docs-pin.test.js` | Сторож документации, по файлу на обещание: пути и таблица файлов; зовы, причины отказа и адреса разделов; числа проверок и цели по времени; пин в примере установки |
512
+ | `test/docs-paths.test.js`, `test/docs-commands.test.js`, `test/docs-numbers.test.js`, `test/docs-pin.test.js` | Сторож документации, по файлу на обещание: пути и таблица файлов; зовы, причины отказа и адреса разделов; числа проверок; пин в примере установки |
500
513
  | `test/changelog.test.js` | Сторож выпуска: версия в `CHANGELOG.md` — версия манифеста, а таблица «что изменится в числах» — это замер на фикстуре, сверенный с живым прогоном |
501
- | `test/suites.test.js` | Сторож разделения набора: полнота классификации (быстрый явно, полный с причиной), потолок стоимости быстрого файла, что быстрый прогон остаётся частью набора |
514
+ | `test/release.test.js` | Сторож выпуска из CI: он начинается тегом, версия берётся из манифеста, секрета и одноразового кода не требует, prerelease не уезжает в `latest`, перед публикацией идёт полный набор — и подсказка на npmjs.com называет этот же файл |
515
+ | `test/suites.test.js` | Сторож разделения набора: полнота классификации (быстрый — явно, полный — с причиной), причина у каждого файла, что быстрый прогон остаётся частью набора |
502
516
  | `test/check.test.js` | Полнота и объяснение на настоящих коммитах фикстуры: непокрытый путь, «только отчёт», «число не сдвинулось», «мимо колонок», слияние — и что починка настроек не двигает числа |
503
517
  | `test/doctor.test.js` | Диагностика на пяти состояниях проекта: без настроек (2), полное покрытие (0), неполное (1), обрезанная история (3), нет датчика (4) — и блок покрытия равен ответу `size check`, а не считается вторым разом |
504
518
  | `test/hook.test.js` | Хуки на свежем клоне: ставятся только командой, дают отдельный коммит отчёта (в том числе после слияния), повторный запуск молчит, чужая работа и индекс не тронуты, в CI и при отказе инструмента ничего не делают, снятие возвращает проект к прежнему |
@@ -555,16 +569,23 @@ JSX и TSX выход зависит от настройки jsx сам
555
569
  ### 1. Установка
556
570
 
557
571
  ```bash
558
- pnpm add -D github:vernikr/size-report#v1.1.1
572
+ pnpm add -D @vernikr/size-report
559
573
  ```
560
574
 
561
- `npm i -D` и `yarn add -D` принимают ту же ссылку. **В npm пакет не опубликован**,
562
- поэтому `pnpm add -D @vernikr/size-report` не сработает. Репозиторий публичный, и
563
- учётных данных установка не требует: `github:` pnpm разрешает в архив
564
- `codeload.github.com` и тянет его по HTTPS.
575
+ Пакет **опубликован в реестре**, и публично: `npm view @vernikr/size-report
576
+ version` отвечает `1.1.1`, `npm access get status @vernikr/size-report` `public`,
577
+ а анонимный запрос тарболла код 200. `npm i -D` и `yarn add -D` принимают то же
578
+ имя; ни ключа, ни ссылки на репозиторий не нужно.
579
+
580
+ Тот же выпуск можно взять ссылкой на репозиторий — так установка не зависит от
581
+ реестра, но остаётся привязанной к ревизии:
582
+
583
+ ```bash
584
+ pnpm add -D github:vernikr/size-report#v1.2.0
585
+ ```
565
586
 
566
587
  Без сети (или если тянуть из codeload нечем) — тарболл: `pnpm pack` в клоне
567
- пакета, затем `pnpm add -D ./vernikr-size-report-1.1.1.tgz`.
588
+ пакета, затем `pnpm add -D ./vernikr-size-report-1.2.0.tgz`.
568
589
 
569
590
  **Почему тег, а не sha.** Короткий sha pnpm разрешает только через видимые рефы, а
570
591
  `git ls-remote` отдаёт одни верхушки веток: пока ревизия — верхушка, короткий sha
@@ -591,11 +612,11 @@ pnpm add -D github:vernikr/size-report#v1.1.1
591
612
  GIT_SSH_COMMAND=false`): установка 3,4 с, дальше `size --write` и `size` работают
592
613
  (`WORKLOG.md` §44). Прежнее требование было ценой приватности: локально — ключ, а
593
614
  в CI — read-only deploy key перед `pnpm install` (то самое первое подключение,
594
- `WORKLOG.md` §18); шаг с ключом из шаблона ушёл вместе с приватностью. Что
595
- остаётся на потом — публикация в npm (`PLAN.md` §8.4), и там есть цена: имя
596
- `size-report` в npm занято чужим пакетом (2017 год, три версии), поэтому
597
- публикация — это имя в области владельца (`@vernikr/size-report`), а не выкладка
598
- под прежним именем; что затронуло переименование — `PLAN.md` §10.
615
+ `WORKLOG.md` §18); шаг с ключом из шаблона ушёл вместе с приватностью. Публикация
616
+ в npm сделана 2026-09-15, и у неё была цена: имя `size-report` в реестре занято чужим
617
+ пакетом (2017 год, три версии), поэтому выкладка — это ещё и смена имени на имя в
618
+ области владельца (`@vernikr/size-report`), а не только отправка архива; что
619
+ затронуло переименование — `PLAN.md` §10, чем доказана выкладка — `WORKLOG.md` §53.
599
620
 
600
621
  ### 2. Черновик настроек
601
622
 
@@ -603,9 +624,18 @@ GIT_SSH_COMMAND=false`): установка 3,4 с, дальше `size --write`
603
624
  pnpm exec size --init # создаёт size-table.config.json
604
625
  ```
605
626
 
606
- Черновик собирается по самому проекту: колонки — крупнейшие файлы каждого
607
- расширения, журнал по знакомым именам (`WORKLOG.md`, `CHANGELOG.md`, ), вывод
608
- в `docs/`, если он есть, `fixCommand` под ваш менеджер пакетов. Он же печатает
627
+ Черновик собирается по самому проекту: колонки — крупнейшие файлы по списку
628
+ расширений исходников (список печатается тут же «расширения в проекте»), журнал
629
+ по знакомым именам (`WORKLOG.md`, `CHANGELOG.md`, …), вывод в `docs/`, если он
630
+ есть, `fixCommand` — под ваш менеджер пакетов.
631
+
632
+ > **Документации в черновике нет, и это заметно сразу.** Список расширений —
633
+ > исходники (`.js`, `.css`, `.json`, …), а `README.md` и журнал в него не входят:
634
+ > колонкой доки делает человек, потому что «важный документ» — не про расширение.
635
+ > Поэтому первый же `size check` на проекте с README и журналом честно скажет, что
636
+ > эти пути не отслеживаются и не исключены (код 1), — это и есть тот шаг, где доки
637
+ > становятся колонками или попадают в `skip` (`§5`). Проверено покомандно на
638
+ > живом проекте: `WORKLOG.md` §54. Он же печатает
609
639
  следующие три шага. Черновик ведёт метрику `min` на настоящее сжатие
610
640
  (`"minify": {"engine": "esbuild"}`) и сразу включает метрику `tok`
611
641
  (`"tokens": {"family": "openai", "encoding": "o200k_base"}`): и минификатор, и
@@ -723,7 +753,7 @@ pnpm exec size doctor # 0 — делать нечего; иначе перв
723
753
  | 1 | таблица разошлась с историей (или правка на диске не закоммичена); у `size check` — путь истории не отслеживается и не исключён | `pnpm run sizes` и закоммитить таблицу; для `check` — дописать путь колонкой или в `skip` |
724
754
  | 2 | что-то в вызове или в проекте — **командная строка** (незнакомый ключ, ключ без значения, повтор ключа, два режима сразу, лишнее слово, команда и режим, неизвестная команда, несовместимый ключ, нет ответа в JSON, два ответа сразу, нет коммита); **настройки и проект** (нет файла настроек, настройки не разобраны, настройки неверны, нет git, не git-репозиторий, конфиг уже есть); **история** (нет такого коммита, коммит назван неточно, коммит вне истории); **хук** (чужой хук, чужой core.hooksPath, нечем звать инструмент); **измерение** (файл не JavaScript, минификатор не разобрал) | текст отказа называет причину и готовую команду — и она выполнима: это сторожит `test/refusals.test.js` |
725
755
  | 3 | неполная история (clone с `--depth`) | полный клон: `git fetch --unshallow` |
726
- | 4 | нет датчика | `minify.engine: "esbuild"`, а минификатора нет: числа получены упрощением. Отчёт собран, причина и починка — в тексте |
756
+ | 4 | нет датчика | `minify.engine: "esbuild"`, а минификатора нет: числа получены упрощением. Отчёт собран, причина и починка — в тексте; если при этом таблица расходится с историей, код остаётся **1** (нарушение старше приближения), а заметка о другом счёте печатается рядом |
727
757
  | 5 | внутренняя ошибка | это дефект инструмента: текст нужен нам, см. «Ловушки» ниже |
728
758
 
729
759
  ### 6. Отчёт обновляется сам после коммита (по желанию)
@@ -768,7 +798,17 @@ pnpm exec size uninstall-hook # снять и вернуть проект к
768
798
  при упрощении — `minify.guard`. Стеком такой случай не выглядит ни там, ни там;
769
799
  - **Минификатора нет** (установка без необязательных зависимостей, платформа без
770
800
  `esbuild`) — метрика честно отступает к упрощению: числа те же, что у `strip`,
771
- способ говорит об этом словами, а прогон отдаёт **код 4** с готовой починкой.
801
+ способ говорит об этом словами, а **сборка** (`--write`) отдаёт **код 4** с
802
+ готовой починкой. У **проверки** в этом случае ответ из двух частей, и он назван
803
+ здесь потому, что именно её советует CI: если отчёт на диске собран с настоящим
804
+ минификатором, а прогон идёт без него, точность изменилась — значит числа в
805
+ таблице больше не совпадают с историей, и проверка скажет про расхождение
806
+ (**код 1**), показав разошедшуюся строку подписи, **и тут же назовёт другой счёт**
807
+ заметкой с готовой починкой. Вердикт при этом остаётся за расхождением: код 4
808
+ утверждал бы, что разница объясняется датчиком, а это никто не проверял —
809
+ расхождение может быть и правкой мимо отчёта (тот же порядок, что у `size check` и
810
+ у `doctor`: нарушение старше приближения). Починка в обоих случаях — `pnpm run
811
+ sizes`; на этом окружении она вернёт **код 4**.
772
812
  Проверить это без переустановки можно окружением `SIZE_REPORT_NO_OPTIONAL=1` —
773
813
  тем же приёмом это делает `test/minify.test.js`;
774
814
  - **Разбор модуля — рабочий поток, поднятый один раз на прогон** (`REFACTOR.md`
@@ -876,7 +916,7 @@ pnpm test # быстрый прогон (каждая пр
876
916
  # контракт данных и страница, сторож документации и выпуска
877
917
  pnpm test:all # полный прогон (выкладка и CI): то же плюс интеграционные —
878
918
  # сборка на дисках, сверка с деревом, хуки, метрики
879
- pnpm run suites:measure # перемерить стоимости файлов набора
919
+ pnpm run suites:measure # замерить длительность каждого файла набора
880
920
  pnpm run parity:live # паритет с живым проектом на клоне, две среды
881
921
  node bin/size.js --data # контракт данных: страница и агент
882
922
  node bin/size.js --page # минимальная страница отчёта
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vernikr/size-report",
3
- "version": "1.1.1",
3
+ "version": "1.2.0",
4
4
  "author": "vernikr",
5
5
  "repository": {
6
6
  "type": "git",
package/src/cli.js CHANGED
@@ -39,6 +39,17 @@ function sensorNote(cfg) {
39
39
  return note(sensorGaps(cfg));
40
40
  }
41
41
 
42
+ /* Вердикт режима вместе с заметками о датчиках: заметка печатается всегда — молчание
43
+ * о другом счёте читается как точное число, и расхождение остаётся без причины, — а
44
+ * код остаётся первым по важности. Нарушение старше приближения (тот же порядок, что
45
+ * у `size check` и у `doctor`): код 4 говорит «числа честные, но другим счётом», а
46
+ * когда таблица расходится, этого никто не проверял — расхождение может быть и
47
+ * настоящей правкой мимо отчёта. */
48
+ function verdict(code, gaps) {
49
+ const sensors = note(gaps);
50
+ return code === EXIT.OK ? sensors : code;
51
+ }
52
+
42
53
  export function check(cfg, want, root) {
43
54
  const out = path.join(root, cfg.output);
44
55
  if (!fs.existsSync(out)) {
@@ -89,9 +100,8 @@ function checkMode(cfg, root) {
89
100
  if (code === 0) {
90
101
  console.log('✓ таблица размеров: ' + rows.length + ' коммитов × ' + cfg.columns.length + ' файлов '
91
102
  + 'совпадает с историей (' + cfg.output + ', ' + kmb(byteLen(html)) + ')');
92
- return sensorNote(cfg);
93
103
  }
94
- return code;
104
+ return verdict(code, sensorGaps(cfg));
95
105
  }
96
106
 
97
107
  /* Полнота покрытия (`size check`): настройки, история, пути, датчики. Не путать с
@@ -104,8 +114,7 @@ function coverageMode(cfg, root, configFile, asJson) {
104
114
  const rep = coverage(cfg, root, configFile);
105
115
  if (asJson) process.stdout.write(JSON.stringify(rep, null, 2) + '\n');
106
116
  else console.log(coverageText(rep));
107
- if (!rep.ok) return EXIT.VIOLATION;
108
- return note(rep.sensors);
117
+ return verdict(rep.ok ? EXIT.OK : EXIT.VIOLATION, rep.sensors);
109
118
  }
110
119
 
111
120
  /* Диагностика одним ответом (`size doctor`): окружение, зависимости, настройки и
@@ -17,10 +17,12 @@
17
17
  `size-table.config.json`. **Колонки в нём — пример**, а не список ваших файлов:
18
18
  в шаблоне стоят `README.md` и `package.json`, потому что они есть почти в любом
19
19
  проекте, и с ними первый отчёт соберётся сразу. Свои колонки даёт
20
- `size --init` (он подбирает крупнейшие файлы по расширениям) можно взять его
21
- черновик целиком, а из шаблона перенести ключи, которых `--init` не пишет
22
- (`skip`, `rows`, `links.commitUrl`), или наоборот: скопировать шаблон и вписать
23
- колонки руками.
20
+ `size --init` (он подбирает крупнейшие файлы по списку расширений исходников; доки
21
+ в этот список не входят) можно взять его черновик целиком, а из шаблона
22
+ перенести ключи, которых `--init` не пишет (`skip`, `rows`, `links.commitUrl`),
23
+ или наоборот: скопировать шаблон и вписать колонки руками. Отсюда же растёт
24
+ ожидаемое: колонки примерные, поэтому `size check` на свежем проекте скажет, что
25
+ README и журнал колонкой не отслеживаются, — так и задумано.
24
26
 
25
27
  Что стоит знать про значения шаблона:
26
28