@vernikr/size-report 2.4.0 → 2.6.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.
Files changed (48) hide show
  1. package/README.md +989 -1081
  2. package/bin/postinstall.js +17 -18
  3. package/bin/size.js +2 -2
  4. package/package.json +3 -4
  5. package/src/args.js +72 -72
  6. package/src/artifact.js +14 -14
  7. package/src/check.js +41 -42
  8. package/src/cli.js +26 -29
  9. package/src/config.js +87 -91
  10. package/src/css.js +14 -14
  11. package/src/data.js +26 -50
  12. package/src/derived.js +31 -35
  13. package/src/doctor.js +95 -99
  14. package/src/explain.js +46 -47
  15. package/src/git.js +66 -71
  16. package/src/history.js +74 -83
  17. package/src/hook.js +130 -149
  18. package/src/init.js +37 -37
  19. package/src/journal.js +17 -15
  20. package/src/locales.js +31 -22
  21. package/src/metrics.js +72 -89
  22. package/src/minify.js +28 -27
  23. package/src/modes.js +57 -60
  24. package/src/optional.js +13 -11
  25. package/src/page/app.css +76 -94
  26. package/src/page/app.js +124 -80
  27. package/src/page/build.js +193 -50
  28. package/src/page/dom.js +8 -9
  29. package/src/page/panel.js +157 -69
  30. package/src/page/payload.js +168 -0
  31. package/src/page/state.js +144 -104
  32. package/src/page/table.js +270 -86
  33. package/src/parse-worker.js +10 -10
  34. package/src/parse.js +43 -45
  35. package/src/project.js +100 -104
  36. package/src/refusal.js +75 -76
  37. package/src/size-table.js +41 -76
  38. package/src/strip/forms.js +5 -5
  39. package/src/strip/guard.js +28 -28
  40. package/src/strip/js.js +27 -27
  41. package/src/strip.js +17 -21
  42. package/src/table.css +54 -19
  43. package/src/tokens.js +27 -27
  44. package/src/tool.js +10 -11
  45. package/templates/README.md +71 -77
  46. package/templates/ci.yml +33 -33
  47. package/templates/size-report.config.json +3 -3
  48. package/CHANGELOG.md +0 -690
package/CHANGELOG.md DELETED
@@ -1,690 +0,0 @@
1
- # CHANGELOG
2
-
3
- История выпусков `@vernikr/size-report`. Версии — SemVer (`PLAN.md` §8.2); версия данных —
4
- `schema: 1`, она заморожена выпуском 1.0.0 и меняется только вместе с MAJOR.
5
-
6
- ## Что значит «изменились числа»
7
-
8
- Числа этого инструмента — его продукт, а не отладочная печать: у каждой метрики есть
9
- источник (`raw` — размер объекта git, `min` — сжатая форма, `tok` — токены) и есть
10
- честность (точный счёт или приближение с пометкой). Поэтому у выпуска обязателен
11
- раздел «Что изменится в числах»: он отвечает, **у кого числа поедут и почему**.
12
- Выпуск, после которого число меняется молча, — дефект этого инструмента, а не выпуск.
13
-
14
- Замеры в этих разделах сняты на фикстуре пакета — `fixtures/synthetic/history.bundle`,
15
- 16 коммитов и 10 колонок, состояние на её верхушке. Таблица выпуска не пересказ: её
16
- сверяет с живым прогоном инструмента `test/changelog.test.js`, а повторить замер
17
- руками можно, склонировав бандл и прогнав `node bin/size.js --config <настройки> --data`,
18
- где за основу взяты `fixtures/synthetic/config.json`, метрики — `raw`, `min`, `tok`, а
19
- способ минификации — `strip` или `esbuild`.
20
-
21
- ## 2.4.0 — 2026-09-15
22
-
23
- Вид дерева и порядок колонок: чего в отчёте нет — после остальных и со снятой
24
- галочкой, колонки последнего коммита — впереди, складка папки не считает числа.
25
-
26
- - **Файл вне отчёта был подписью без галочки, а папка, где измерять нечего, —
27
- без неё вовсе.** Один и тот же вопрос — «почему у этого нет числа» — читался
28
- по-разному в двух строках подряд, а рядом с колонками такие строки выбивались из
29
- ряда. Теперь у всего, что вне отчёта, галочка **стоит на месте, снята и
30
- недоступна**: ряд строк ровный (глаз сравнивает одно с одним), а недоступность
31
- говорит, что это не выбор читателя, — причина во всплывающей строке, как и
32
- раньше. Заодно всё, чего в отчёте нет (и папки, и листья), идёт **после** того,
33
- что в нём есть: в списке, где половина строк не переключается, отчёт виден сразу,
34
- а не среди чужого.
35
- - **Складывание папки считало числа, которых не меняет.** Клик по знаку пересобирал
36
- панель и таблицу целиком — то есть платил за всю таблицу (в этом репозитории 97
37
- строк × 136 колонок, 39 576 клеток) ради того, чтобы спрятать строки. Замер в
38
- настоящем Chrome на этой же странице: **107 + 380 мс** перерисовки — столько же,
39
- сколько стоит переключение одного файла. Стало **0,6 мс** в обработчике (и 6 мс на
40
- перекладку страницы, которая прячет 42 строки): поддерево лежит в разметке и
41
- прячется классом на строке, а клик меняет только то, что читатель и видит, —
42
- класс, знак и запись в памяти.
43
- - **Колонки, которых коснулся последний коммит, идут впереди остальных.** Отчёт
44
- пересобирается после каждого коммита, и первый вопрос читателя — что принесла эта
45
- правка. Знак приходит из истории (`last` в контракте `--data`), а не из чисел:
46
- правка без изменения размера — тоже правка. Берётся последний коммит, задевший
47
- хотя бы одну колонку: коммиты мимо колонок (и прежде всего сам отчёт, который
48
- коммитит хук) пропускаются — иначе знак зависел бы от собственного коммита
49
- отчёта, тот же прогон давал бы другие байты, и хук коммитил бы отчёт второй раз
50
- на пустом месте. Внутри каждой части порядок прежний, из настроек.
51
-
52
- ### Что изменится в числах
53
-
54
- **Ничего.** Числа считает тот же движок теми же датчиками: выпуск про то, что и в
55
- каком порядке видно на странице, а не про измерение. Таблица та же, что у 2.3.0, до
56
- последней клетки.
57
-
58
- | Файл | raw | min со strip | min с esbuild | tok |
59
- |---|---|---|---|---|
60
- | code.js | 735 | 276 | 185 | 168 |
61
- | modern.js | 246 | 51 | 45 | 44 |
62
- | config.mjs | 172 | 45 | 40 | 40 |
63
- | заметки.md | 306 | 303 | 303 | 53 |
64
- | crlf.txt | 63 | 60 | 60 | 10 |
65
- | package.json | 87 | 69 | 69 | 34 |
66
- | style.css | 156 | 55 | 43 | 38 |
67
- | table.toml | 300 | 299 | 299 | 52 |
68
- | empty.js | 0 | 0 | 0 | 0 |
69
- | WORKLOG.md | 446 | 439 | 439 | 101 |
70
- | **ИТОГО** | **2511** | **1597** | **1483** | **540** |
71
-
72
- ## 2.3.0 — 2026-09-15
73
-
74
- Отчёт описывает проект целиком: колонкой идёт каждый отслеживаемый файл, а дерево
75
- складывается.
76
-
77
- - **Колонками была выборка из проекта.** Без файла настроек инструмент брал
78
- двенадцать крупнейших файлов — по одному от каждого расширения — и называл
79
- прочие исключениями. Отчёт при этом считал «общий объём» по горсти файлов, и
80
- читатель принимал это за объём проекта (в этом репозитории — 12 файлов из 148).
81
- Теперь колонка — **каждый отслеживаемый git файл, который можно измерить**, и
82
- `skip` называет только то, что колонкой быть не может: сам отчёт, замки
83
- зависимостей, карты, собранное, незнакомый формат, файл сверх 512 КБ — и путь,
84
- которого на HEAD нет (он живёт только в истории: измерять в нём нечего).
85
- - **Цена названа замером** (этот же репозиторий, 149 коммитов, 135 колонок против
86
- 12): сборка отчёта 2,4 с → **6,3 с**, файл отчёта 122 КБ → **417 КБ**, `check` —
87
- 6,1 с. Отчёт пересобирает хук после каждого коммита, поэтому столько теперь стоит
88
- и каждый коммит; кому это дорого — колонки задают файлом настроек (`size --init`
89
- даёт черновик, дальше его правят: прежний выбор воспроизводится списком из
90
- двенадцати файлов).
91
- - **Дерево складывается.** У каждой папки свой знак (▾/▸): он отвечает за то,
92
- сколько дерева видно, а галочка — за то, что считается, и потому это две разные
93
- цели нажатия, а не одна. Сложенное помнится между заходами и **не уезжает в
94
- ссылку**: ссылку отправляют ради чисел, а не ради того, как у кого разложено
95
- дерево. Запись у складывания своя (тот же паспорт отчёта), разворот всех папок её
96
- убирает — как и возврат галочек. На 148 путях проекта это единственный способ
97
- добраться до его середины.
98
- - **Вклейка программы страницы получила сторож.** Модульный синтаксис снимается
99
- построчно, поэтому многострочный `import` оставлял в странице хвост и ломал её
100
- целиком — теперь проверка ищет в вклеенной программе и имя модуля, а не только
101
- начало строки.
102
-
103
- ### Что изменится в числах
104
-
105
- **Колонка — каждый отслеживаемый файл, поэтому там, где настройки не заданы, колонок
106
- станет больше** (в этом репозитории 12 → 135), а вместе с ними вырастут «общий объём»
107
- (он и раньше считался по колонкам) и время прогона — оно названо выше. Числа ниже
108
- замерены на фикстуре, где колонки заданы файлом настроек: такой проект замер видит
109
- точно так же, как 2.2.0, — до последней клетки.
110
-
111
- | Файл | raw | min со strip | min с esbuild | tok |
112
- |---|---|---|---|---|
113
- | code.js | 735 | 276 | 185 | 168 |
114
- | modern.js | 246 | 51 | 45 | 44 |
115
- | config.mjs | 172 | 45 | 40 | 40 |
116
- | заметки.md | 306 | 303 | 303 | 53 |
117
- | crlf.txt | 63 | 60 | 60 | 10 |
118
- | package.json | 87 | 69 | 69 | 34 |
119
- | style.css | 156 | 55 | 43 | 38 |
120
- | table.toml | 300 | 299 | 299 | 52 |
121
- | empty.js | 0 | 0 | 0 | 0 |
122
- | WORKLOG.md | 446 | 439 | 439 | 101 |
123
- | **ИТОГО** | **2511** | **1597** | **1483** | **540** |
124
-
125
- ## 2.2.0 — 2026-09-15
126
-
127
- Дерево страницы — дерево проекта: видно всё, числа есть у измеряемых.
128
-
129
- - **В дереве было видно только то, что стало колонками.** В проекте со 147 файлами
130
- и выведёнными настройками колонок двенадцать — дерево и показывало двенадцать
131
- листьев, а про остальные молчало: читатель видел не дерево проекта, а список
132
- измеренного, и решить, что файлы потерялись, было проще всего. Теперь в контракте
133
- (`--data`) едет **каталог** — все пути, которые видит git (`ls-files`), — и дерево
134
- строится по нему.
135
- - **Числа — только у колонок, и это видно, а не подразумевается.** Лист вне отчёта
136
- стоит на своём месте, но подписью без галочки, а причина — во всплывающей строке,
137
- и причин две: `rule` — такой файл колонкой быть не может (сам отчёт, замок
138
- зависимостей, собранное, слишком крупный или формат без текста), `choice` — мог бы,
139
- но в набор колонок не выбран (его задают настройки). Знак причины движок ставит
140
- **теми же** правилами, по которым выбирает колонки, — иначе подсказка говорила бы
141
- одно, а выбор делал другое. Сам отчёт в дереве назван **всегда** — и пока не
142
- собран, и когда он вне git: его отслеживаемость это свойство момента, и зависеть
143
- от неё отчёт не должен (иначе первая же пересборка в свежем клоне даёт другие
144
- байты, и хук коммитит отчёт второй раз на пустом месте).
145
- - **Счётчик папки со смешанным составом — доля** («2/5»: два файла в отчёте из
146
- пяти в папке), а целиком измеряемая папка считает как раньше («5»). Папка, где
147
- измеряемых нет вовсе, галочки не получает: включать в ней нечего, но на месте она
148
- остаётся — дерево не должно врать о том, что в проекте есть.
149
- - **Цена названа:** набор колонок этим не меняется, поэтому прогон не подорожал.
150
- Замер на этом же проекте (162 колонки × 79 строк против 12): с токенами 16,1 с
151
- вместо 2,4 с, а на живой истории полный набор ещё и отказывает (перенос состояния
152
- теряет правку пути, которого нет на HEAD) — поэтому «мерить всё» решением не стало.
153
-
154
- ### Что изменится в числах
155
-
156
- **Ничего.** Числа считает тот же движок теми же датчиками: выпуск про то, что видно в
157
- дереве панели, а не про измерение. Таблица та же, что у 2.1.0, до последней клетки.
158
-
159
- | Файл | raw | min со strip | min с esbuild | tok |
160
- |---|---|---|---|---|
161
- | code.js | 735 | 276 | 185 | 168 |
162
- | modern.js | 246 | 51 | 45 | 44 |
163
- | config.mjs | 172 | 45 | 40 | 40 |
164
- | заметки.md | 306 | 303 | 303 | 53 |
165
- | crlf.txt | 63 | 60 | 60 | 10 |
166
- | package.json | 87 | 69 | 69 | 34 |
167
- | style.css | 156 | 55 | 43 | 38 |
168
- | table.toml | 300 | 299 | 299 | 52 |
169
- | empty.js | 0 | 0 | 0 | 0 |
170
- | WORKLOG.md | 446 | 439 | 439 | 101 |
171
- | **ИТОГО** | **2511** | **1597** | **1483** | **540** |
172
-
173
- ## 2.1.0 — 2026-09-15
174
-
175
- Вид страницы на десктопе: числам — вся оставшаяся высота, панели — своя прокрутка.
176
-
177
- - **Под таблицей была пустота, а список файлов задавал высоту страницы.** На широком
178
- экране оба столбца шли каждый со своей высотой (`align-items: start`), поэтому
179
- высота страницы равнялась тому, что вышло у панели: замер до правки при окне
180
- 1440×900 — панель 883 px, страница 1097 при окне 900, под таблицей 195 px пустоты,
181
- а нижние файлы дерева — за нижним краем окна (список при этом ещё и резался своим
182
- потолком в 62vh). Теперь страница целиком укладывается в окно: строки сетки
183
- названы по предмету, тянется одна рабочая — таблица берёт всю оставшуюся высоту
184
- (1440×900: 1060 × 735 вместо 602), панель — не больше неё и прокручивается сама
185
- (содержимое 804 при высоте 785). Список файлов на широком экране больше не режется:
186
- все 23 подписи дерева видны сразу.
187
- - **Клик по галочке возвращал список к началу.** Панель рисуется заново, и вместе с
188
- ней терялось место, до которого докурили: до нижних файлов дерева было не
189
- добраться. Прокрутка панели и списка теперь часть вида — запоминается перед
190
- пересборкой и ставится обратно (подтверждено в Chrome: при окне 1440×500
191
- `panel.scrollTop` = 421 до клика и 421 после).
192
- - **Строка категорий липнет** к верху панели, пока листается дерево. Чтобы под
193
- липкой строкой не читались проезжающие файлы, верхний отступ панели переехал в
194
- первое поле: прокручиваемое видно и в отступе прокрутки (в полосе 13 px читались
195
- `parity/` и `data.json` — теперь там сама строка).
196
- - **Расшифровка под деревом убрана**, а шрифт подписей файлов стал как у чисел
197
- таблицы (12,5 px): расшифровка отодвигала числа, а её смысл стоит у того, что
198
- объясняет — цвет дельты называет знак числа, способ и точность стоят под
199
- переключателями метрик, знак пропуска — в подсказке клетки.
200
- - **Граница широкой раскладки — 899 px.** При ровно 900 px обе половины оформления
201
- применялись к одной странице, и от «узкой» в «широкой» оставался потолок высоты
202
- таблицы: те же пустые 179 px под ней на одном размере окна.
203
-
204
- ### Что изменится в числах
205
-
206
- **Ничего.** Правка — про вид страницы и прокрутку; движок тот же, что у 2.0.2, а
207
- страница получает от него готовые числа.
208
-
209
- | Файл | raw | min со strip | min с esbuild | tok |
210
- |---|---|---|---|---|
211
- | code.js | 735 | 276 | 185 | 168 |
212
- | modern.js | 246 | 51 | 45 | 44 |
213
- | config.mjs | 172 | 45 | 40 | 40 |
214
- | заметки.md | 306 | 303 | 303 | 53 |
215
- | crlf.txt | 63 | 60 | 60 | 10 |
216
- | package.json | 87 | 69 | 69 | 34 |
217
- | style.css | 156 | 55 | 43 | 38 |
218
- | table.toml | 300 | 299 | 299 | 52 |
219
- | empty.js | 0 | 0 | 0 | 0 |
220
- | WORKLOG.md | 446 | 439 | 439 | 101 |
221
- | **ИТОГО** | **2511** | **1597** | **1483** | **540** |
222
-
223
- ## 2.0.2 — 2026-09-15
224
-
225
- Инструкция перестала обещать лишний ручной шаг и назвала платформенную разницу.
226
-
227
- - **README учил ставить хук руками.** В §6 осталась строка прежнего выпуска — «хуки
228
- ставятся только командой `install-hook`, ни один обычный запуск их не создаёт», — а с
229
- 2.0.0 постановка своя (`bin/postinstall.js` и первый запуск). Текст теперь говорит то,
230
- что делает код, и называет единственное исключение: pnpm 10 не исполняет скрипты
231
- зависимостей («Ignored build scripts») — там хук ставит первый запуск, либо сборка
232
- разрешается `pnpm.onlyBuiltDependencies` в манифесте потребителя.
233
- - **Названа одна ручная ступень, которая была невидимой.** Первый отчёт создаётся, но не
234
- коммитится (новый файл в чужой истории — решение человека): это сказано в §6 и в
235
- шаблоне `templates/README.md`, дальше отчёт обновляется отдельными коммитами сам.
236
-
237
- ### Что изменится в числах
238
-
239
- **Ничего.** Правка — только текст инструкции; движок тот же, что у 2.0.1.
240
-
241
- | Файл | raw | min со strip | min с esbuild | tok |
242
- |---|---|---|---|---|
243
- | code.js | 735 | 276 | 185 | 168 |
244
- | modern.js | 246 | 51 | 45 | 44 |
245
- | config.mjs | 172 | 45 | 40 | 40 |
246
- | заметки.md | 306 | 303 | 303 | 53 |
247
- | crlf.txt | 63 | 60 | 60 | 10 |
248
- | package.json | 87 | 69 | 69 | 34 |
249
- | style.css | 156 | 55 | 43 | 38 |
250
- | table.toml | 300 | 299 | 299 | 52 |
251
- | empty.js | 0 | 0 | 0 | 0 |
252
- | WORKLOG.md | 446 | 439 | 439 | 101 |
253
- | **ИТОГО** | **2511** | **1597** | **1483** | **540** |
254
-
255
- ## 2.0.1 — 2026-09-15
256
-
257
- Место отчёта в свежем проекте: `docs/size-report.html`, и каталог создаётся сам.
258
-
259
- - **Отчёт больше не ложится в корень.** Первая редакция вывода выбирала «рядом с
260
- доками, если каталог `docs` есть, иначе в корне»: в проекте, который только что
261
- поставил пакет, каталога ещё нет — и отчёт оказывался там, где его не ищут (замер:
262
- свежий клон, установка из реестра, `docs/` не появился, файл лёг в корень). Теперь
263
- адрес один: `docs/size-report.html`; каталог — часть адреса, а создаёт его тот, кто
264
- пишет файл. Имя из настроек по-прежнему перебивает вывод.
265
- - Стережёт это проверка: проект без настроек и без каталога `docs` — отчёт в `docs/`,
266
- в корне его нет, контрольный режим зелёный.
267
-
268
- ### Что изменится в числах
269
-
270
- **Ничего.** Правка — про путь файла, а не про измерение. Таблица та же, что у 2.0.0.
271
-
272
- | Файл | raw | min со strip | min с esbuild | tok |
273
- |---|---|---|---|---|
274
- | code.js | 735 | 276 | 185 | 168 |
275
- | modern.js | 246 | 51 | 45 | 44 |
276
- | config.mjs | 172 | 45 | 40 | 40 |
277
- | заметки.md | 306 | 303 | 303 | 53 |
278
- | crlf.txt | 63 | 60 | 60 | 10 |
279
- | package.json | 87 | 69 | 69 | 34 |
280
- | style.css | 156 | 55 | 43 | 38 |
281
- | table.toml | 300 | 299 | 299 | 52 |
282
- | empty.js | 0 | 0 | 0 | 0 |
283
- | WORKLOG.md | 446 | 439 | 439 | 101 |
284
- | **ИТОГО** | **2511** | **1597** | **1483** | **540** |
285
-
286
- ## 2.0.0 — 2026-09-15
287
-
288
- Один отчёт вместо двух, и он же появляется сам: форма отчёта сведена к одному
289
- файлу, а обновление — к одному решению (хук ставится сам).
290
-
291
- - **Отчёт — один файл: самодостаточная страница `size-report.html`.** Данные,
292
- оформление и программа лежат в нём же; внешних ссылок нет. Прежние две формы
293
- (статическая таблица и рядом страница) убраны вместе с их кодом (`src/render.js`,
294
- `src/artifact.css`): два вывода одной истории расходились бы молча, а выбрать,
295
- какой верный, было бы нечем. Колонка движка — это файл, значит и отчёт — файл.
296
- - **Запись одна: `--write [файл]`** (прежняя `--page` убрана — это ломающее
297
- изменение). Значение ключа пишет отчёт по названному пути (каталог создаётся сам)
298
- и становится его же `output`: отчёт называет себя тем путём, по которому лежит.
299
- - **По умолчанию — `docs/size-report.html`**, если каталог `docs/` в проекте есть,
300
- иначе в корне. Имя больше не выводится из настроек: файл это и есть отчёт.
301
- - **Хук ставится сам** — после постановки пакета (`bin/postinstall.js`) и при первом
302
- запуске в проекте. Поэтому `docs/` с отчётом появляется первым же коммитом, без
303
- ручного шага; ставится там, где это безопасно (обычный `.git/hooks`, нет чужого
304
- хука, есть чем звать инструмент, не CI), и там же молчит, где нельзя.
305
- - Коммит отчёта виден в хуке как раньше: отдельным коммитом, только этим путём.
306
- Отчёт остаётся **неподвижной точкой** — список пропущенных коммитов в файл не
307
- идёт (он меняется от коммита самого отчёта), и хук не коммитит его бесконечно;
308
- читателю этот список по-прежнему доступен: `--data`, `--json`, `size explain`.
309
-
310
- ### Что изменится в числах
311
-
312
- **Ничего.** Измерение не тронуто: те же датчики, те же способы, те же колонки. Что
313
- меняется у потребителя — **форма файла и его путь**: `size` (проверка) на прежнем
314
- файле будет красным, пока отчёт не пересобран, а скрипты, звавшие `--page`,
315
- получат отказ с названным ключом. Таблица ниже та же, что у 1.3.1, до последней
316
- клетки.
317
-
318
- | Файл | raw | min со strip | min с esbuild | tok |
319
- |---|---|---|---|---|
320
- | code.js | 735 | 276 | 185 | 168 |
321
- | modern.js | 246 | 51 | 45 | 44 |
322
- | config.mjs | 172 | 45 | 40 | 40 |
323
- | заметки.md | 306 | 303 | 303 | 53 |
324
- | crlf.txt | 63 | 60 | 60 | 10 |
325
- | package.json | 87 | 69 | 69 | 34 |
326
- | style.css | 156 | 55 | 43 | 38 |
327
- | table.toml | 300 | 299 | 299 | 52 |
328
- | empty.js | 0 | 0 | 0 | 0 |
329
- | WORKLOG.md | 446 | 439 | 439 | 101 |
330
- | **ИТОГО** | **2511** | **1597** | **1483** | **540** |
331
-
332
- ## 1.3.1 — 2026-09-15
333
-
334
- Правка раскладки страницы: на широком экране панель выбора встаёт слева от таблицы.
335
-
336
- - **От 900 px панель — колонка слева от таблицы.** Метрики, дерево файлов и легенда
337
- видны одновременно с числами: прокрутка нижних строк больше не уводит управление за
338
- верх экрана, а таблица получает всё оставшееся по горизонтали (1060 px при окне
339
- 1440 против 1372 у прежней раскладки в одну колонку). Узкое окно раскладку снимает:
340
- там столбцы снова идут друг под другом, как было.
341
- - Раскладка — сетка на `body` (`src/page/app.css`), а не обёртка в разметке: страница
342
- собирается вклейкой глав, и форма страницы осталась в одном месте. Порог тот же,
343
- что у адаптаций: между «широко» и «узко» нет промежутка без правил.
344
- - Ни поведение, ни артефакт, ни данные не тронуты — правка только в оформлении
345
- страницы (`--page`); статический артефакт (`--write`) этот выпуск не касается.
346
-
347
- ### Что изменится в числах
348
-
349
- **Ничего.** Этот выпуск не трогает ни измерение, ни форму отчёта: изменилась
350
- раскладка страницы, а числа считает тот же движок теми же датчиками. Таблица ниже та
351
- же, что у 1.3.0, до последней клетки.
352
-
353
- | Файл | raw | min со strip | min с esbuild | tok |
354
- |---|---|---|---|---|
355
- | code.js | 735 | 276 | 185 | 168 |
356
- | modern.js | 246 | 51 | 45 | 44 |
357
- | config.mjs | 172 | 45 | 40 | 40 |
358
- | заметки.md | 306 | 303 | 303 | 53 |
359
- | crlf.txt | 63 | 60 | 60 | 10 |
360
- | package.json | 87 | 69 | 69 | 34 |
361
- | style.css | 156 | 55 | 43 | 38 |
362
- | table.toml | 300 | 299 | 299 | 52 |
363
- | empty.js | 0 | 0 | 0 | 0 |
364
- | WORKLOG.md | 446 | 439 | 439 | 101 |
365
- | **ИТОГО** | **2511** | **1597** | **1483** | **540** |
366
-
367
- ## 1.3.0 — 2026-09-15
368
-
369
- Выпуск выведенных настроек: чтобы получить отчёт, проект больше не обязан себя
370
- описывать.
371
-
372
- - **Файла настроек может не быть.** Их выводит сам инструмент — по проекту: колонками
373
- крупнейшие файлы, по одному от каждого расширения (иначе отчёт состоял бы из одних
374
- крупных `.md`, и ни один `.js` не попал бы под настоящее сжатие), журналом — первый
375
- знакомый (`WORKLOG.md`, `CHANGELOG.md`, …), файлом отчёта — `docs/`, если каталог есть,
376
- командой починки — объявленный скрипт `sizes`, а без него путь к установленному
377
- пакету внутри проекта, ссылкой на коммит — адрес `origin` (GitHub или GitLab: у
378
- остальных хозяев пусто, догадка вела бы не туда), метриками — `raw`, `min`, `tok`.
379
- Команда починки и ссылка берутся готовыми, а не выдуманными: её цитируют подпись
380
- отчёта и отказы, и зов скрипта, которого в проекте ещё нет, ответил бы «нет такого
381
- скрипта» ровно там, где человеку нужна работающая команда.
382
- - **Всё, что колонкой быть не может или в неё не поместилось, названо в `skip`** (сам
383
- отчёт, замки зависимостей, карты, собранное): поэтому первый же `size check` полон, а не
384
- красный, — «пути мимо колонок» появляются от новых правок, а не от того, что проект ещё
385
- не настраивали. Колонка — это файл: список путей колонки движок читает как её
386
- переименования, поэтому «папка целиком» колонкой не бывает.
387
- - **О выведенных настройках сказано строкой** в stderr, с готовой командой `--init` —
388
- она их закрепляет, и дальше их правят как обычные настройки. Закрепляется то же,
389
- чем проект работает без файла (вывод поверх умолчаний), поэтому смена умолчаний в
390
- новой версии пакета не поедет по уже настроенному проекту молча. Без закрепления
391
- профиль выводится на каждом запуске: числа не «поехали», но повторить прежний замер
392
- можно только закрепив его.
393
- - **Отказ остался у названного файла:** `--config <файл>`, которого нет, — код 2 с той же
394
- починкой `--init <файл>` (опечатку в пути покрывать догадкой нельзя). У умолчательного
395
- имени отказа нет вовсе; коды выхода ни в одном другом случае не изменились.
396
- - Номер **1.3.0** — по SemVer: появилась возможность, которой не было; схема данных
397
- (`schema: 1`) та же.
398
-
399
- ### Что изменится в числах
400
-
401
- **У кого настройки есть — ничего.** Этот выпуск не трогает ни форму отчёта, ни счёт:
402
- таблица ниже та же, что у 1.2.0.
403
-
404
- **У кого настроек нет** — числа появятся там, где был отказ (код 2): их даст выведенный
405
- профиль. Выведенное и закреплённое (`--init`) друг от друга не отличаются: файл — это тот
406
- же профиль, только записанный. Повторить замер можно только по закреплённому: без файла
407
- профиль выводится заново каждый запуск.
408
-
409
- | Файл | raw | min со strip | min с esbuild | tok |
410
- |---|---|---|---|---|
411
- | code.js | 735 | 276 | 185 | 168 |
412
- | modern.js | 246 | 51 | 45 | 44 |
413
- | config.mjs | 172 | 45 | 40 | 40 |
414
- | заметки.md | 306 | 303 | 303 | 53 |
415
- | crlf.txt | 63 | 60 | 60 | 10 |
416
- | package.json | 87 | 69 | 69 | 34 |
417
- | style.css | 156 | 55 | 43 | 38 |
418
- | table.toml | 300 | 299 | 299 | 52 |
419
- | empty.js | 0 | 0 | 0 | 0 |
420
- | WORKLOG.md | 446 | 439 | 439 | 101 |
421
- | **ИТОГО** | **2511** | **1597** | **1483** | **540** |
422
-
423
- ## 1.2.0 — 2026-09-15
424
-
425
- Выпуск причины, а не измерения: проверка («таблица совпадает с историей?») теперь
426
- называет другой счёт, когда он есть, — и делает это всегда, а не только там, где
427
- всё сошлось. Нашлось это прогулкой по собственной инструкции (`WORKLOG.md` §54),
428
- починено по правилу «нарушение старше приближения» (`REFACTOR.md` R-4.23).
429
-
430
- - **`size` и `size check` печатают заметку о датчике всегда.** Раньше заметка
431
- печаталась только при благополучном вердикте: если отчёт собран с настоящим
432
- минификатором, а прогон идёт без него (установка без необязательных
433
- зависимостей, платформа без `esbuild`), числа честно расходились, а причины
434
- «счёт другой» в выводе не было вовсе — читатель видел расхождение строки
435
- подписи и ничего о том, откуда оно.
436
- - **Вердикт остаётся первым по важности.** Нарушение старше приближения — тот же
437
- порядок, что у `size check` и `size doctor`: код **4** утверждал бы, что
438
- расхождение объясняется датчиком, а этого никто не проверял (расхождение может
439
- быть и правкой мимо отчёта). Поэтому ответ в этом случае — по-прежнему **код 1**
440
- плюс заметка с починкой: кода выхода выпуск не меняет ни в одном случае.
441
- - Ни сборка отчёта, ни его форма, ни смысл настроек не тронуты. Остальное в этом
442
- выпуске — не про поставку: выпуск по тегу из CI (R-4.24) и снятые цели по
443
- времени у набора проверок (R-5.8) касаются репозитория пакета, а не того, что
444
- устанавливают.
445
- - Номер **1.2.0** назван владельцем пакета; по строгому SemVer содержимое —
446
- исправление (PATCH): новых возможностей в поставке нет.
447
-
448
- ### Что изменится в числах
449
-
450
- **Ничего.** Таблица ниже та же, что у 1.1.0 и 1.1.1, до последней клетки: этот
451
- выпуск меняет текст под расхождением, а не числа. Замер на фикстуре — тот же
452
- (16 коммитов, 10 колонок), доказано не словом: артефакт (22 112 Б), страница
453
- (59 376 Б) и оба замороженных эталона не переснимались, а `--json` и артефакт
454
- побайтово равны эталону на фикстуре и на живой истории проекта-потребителя.
455
-
456
- | Файл | raw | min со strip | min с esbuild | tok |
457
- |---|---|---|---|---|
458
- | code.js | 735 | 276 | 185 | 168 |
459
- | modern.js | 246 | 51 | 45 | 44 |
460
- | config.mjs | 172 | 45 | 40 | 40 |
461
- | заметки.md | 306 | 303 | 303 | 53 |
462
- | crlf.txt | 63 | 60 | 60 | 10 |
463
- | package.json | 87 | 69 | 69 | 34 |
464
- | style.css | 156 | 55 | 43 | 38 |
465
- | table.toml | 300 | 299 | 299 | 52 |
466
- | empty.js | 0 | 0 | 0 | 0 |
467
- | WORKLOG.md | 446 | 439 | 439 | 101 |
468
- | **ИТОГО** | **2511** | **1597** | **1483** | **540** |
469
-
470
- ## 1.1.1 — 2026-09-15
471
-
472
- Выпуск имени, а не измерения: пакет переехал в область владельца
473
- (`@vernikr/size-report`) — имя `size-report` в реестре занято чужим пакетом, и
474
- опубликоваться под ним было нельзя (`PLAN.md` §10). Заодно в поставку вошёл файл
475
- лицензии, которого манифест обещал, а в дереве не было.
476
-
477
- - **Имя пакета — `@vernikr/size-report`.** `bin` остался `size`, установка —
478
- `pnpm add -D @vernikr/size-report`, зов — `pnpm exec size`.
479
- - Тот же выпуск закрывает три правки после 1.1.0: совет отказа проверяется
480
- исполнением, а не на слово (`REFACTOR.md` R-4.22), якорь фикстуры выведен из
481
- дерева в историю (R-1.5, R-3.4) и числа переименования в `PLAN.md` §10 сверены
482
- с фактом.
483
- - **Имя инструмента в данных (`--data`) совпадает с именем пакета** — оно же
484
- входит в паспорт отчёта, от которого зависят ключ памяти страницы и якорь
485
- ссылки. Поэтому у отчёта, пересобранного этим выпуском, **сохранённый выбор
486
- читателя в браузере не подхватится один раз**: запись прошлого выпуска лежит
487
- под другим ключом. Числа и разметка от этого не меняются, а первый читатель и
488
- так видит умолчание.
489
- - В поставку добавлен `LICENSE` (MIT) — манифест называл лицензию, а файла в
490
- тарболле не было.
491
-
492
- ### Что изменится в числах
493
-
494
- **Ничего.** Это не обещание, а замер: таблица ниже снята выпуском 1.1.1 и
495
- совпадает с таблицей 1.1.0 до последней клетки — измерение этот выпуск не трогает
496
- вовсе, а правки лежат в имени пакета, текстах отказов и выводе якоря фикстуры.
497
- Доказано не словом: вывод `--json` и артефакт побайтово равны замороженному
498
- эталону на фикстуре и на живой истории проекта-потребителя, а его закоммиченная
499
- таблица пересобирается в те же байты (`sha256 863ce3e9…`).
500
-
501
- | Файл | raw | min со strip | min с esbuild | tok |
502
- |---|---|---|---|---|
503
- | code.js | 735 | 276 | 185 | 168 |
504
- | modern.js | 246 | 51 | 45 | 44 |
505
- | config.mjs | 172 | 45 | 40 | 40 |
506
- | заметки.md | 306 | 303 | 303 | 53 |
507
- | crlf.txt | 63 | 60 | 60 | 10 |
508
- | package.json | 87 | 69 | 69 | 34 |
509
- | style.css | 156 | 55 | 43 | 38 |
510
- | table.toml | 300 | 299 | 299 | 52 |
511
- | empty.js | 0 | 0 | 0 | 0 |
512
- | WORKLOG.md | 446 | 439 | 439 | 101 |
513
- | **ИТОГО** | **2511** | **1597** | **1483** | **540** |
514
-
515
- Разрезы те же, что у 1.0.0 и 1.1.0, и читаются так же: `raw` — размер объекта
516
- git; `min` со `strip` — упрощение, под которым снят эталон паритета; `min` со
517
- `esbuild` — то, что даёт настоящий минификатор (`minify.engine`); `tok` — словарь
518
- `o200k_base` с `gpt-tokenizer 4.0.0`. У проекта прежние настройки означают
519
- `strip`, поэтому обновление «само» чисел не меняет. gzip в выпуск по-прежнему не
520
- входит (`PLAN.md` §10, D4).
521
-
522
- ## 1.1.0 — 2026-09-15
523
-
524
- Первый выпуск после 1.0.0, и в нём **ни одной правки измерения** — только то, что
525
- нашлось живыми прогонами после выпуска, все в ответах инструмента человеку.
526
-
527
- - `explain` понимает то, чем коммиты зовут на самом деле: `HEAD`, ветку, тег,
528
- `HEAD~1`, полный и короткий sha. Раньше имя ревизии выглядело как несуществующий
529
- коммит («в истории нет коммита «HEAD»») — то есть отказ называл не ту причину.
530
- Коммит вне истории отчёта теперь отдельная причина с названным sha.
531
- - У отказов появился **каталог и сторож** (`tools/refusals.js`): по строке на
532
- каждый отказ с кодом выхода и обязательными фразами, карты мест отказа держат
533
- числа, а две проверки делят обе половины обещания — одна вызывает отказ, другая
534
- требует у каждого места пункт каталога. Новый отказ не может появиться без
535
- проверки. Заодно исправлены шесть мест, где текст врал или молчал о починке, и
536
- появилась одна новая причина: **`нет git`** — раньше «git не запустился» и
537
- «здесь нет репозитория» назывались одним текстом с оговоркой «или», то есть не
538
- назывались вовсе.
539
- - Проверка настроек отвергает колонку, у которой путь — не непустая строка
540
- (`"paths": [123]`): раньше такая колонка ни с чем не совпадала, а отчёт отдавал
541
- нули **за успех**.
542
- - `--init` в каталоге без знакомых расширений больше не печатает «✗» при коде
543
- выхода 0: знак и код говорили разное.
544
- - **Репозиторий пакета стал публичным**, поэтому установка не требует ни ключа,
545
- ни токена, ни шага в CI: `github:` pnpm разрешает в архив `codeload.github.com`
546
- по HTTPS (`WORKLOG.md` §44).
547
-
548
- ### Что изменится в числах
549
-
550
- **Ничего.** Это не обещание, а замер: таблица ниже снята выпуском 1.1.0 и совпадает
551
- с таблицей 1.0.0 до последней клетки — метрики, настройки по умолчанию и датчики те
552
- же, а правки этого выпуска лежат в текстах отказов, разборе аргументов командной
553
- строки и проверке настроек, куда измерение не заходит. Доказано не словом: вывод
554
- `--json` и артефакт побайтово равны замороженному эталону на фикстуре и на живой
555
- истории проекта-потребителя, а его закоммиченная таблица (211 КБ) тем же выпуском
556
- пересобирается в те же байты (`sha256 863ce3e9…`).
557
-
558
- | Файл | raw | min со strip | min с esbuild | tok |
559
- |---|---|---|---|---|
560
- | code.js | 735 | 276 | 185 | 168 |
561
- | modern.js | 246 | 51 | 45 | 44 |
562
- | config.mjs | 172 | 45 | 40 | 40 |
563
- | заметки.md | 306 | 303 | 303 | 53 |
564
- | crlf.txt | 63 | 60 | 60 | 10 |
565
- | package.json | 87 | 69 | 69 | 34 |
566
- | style.css | 156 | 55 | 43 | 38 |
567
- | table.toml | 300 | 299 | 299 | 52 |
568
- | empty.js | 0 | 0 | 0 | 0 |
569
- | WORKLOG.md | 446 | 439 | 439 | 101 |
570
- | **ИТОГО** | **2511** | **1597** | **1483** | **540** |
571
-
572
- Разрезы те же, что у 1.0.0, и читаются так же: `raw` — размер объекта git (ни от
573
- чего, кроме него, не зависит); `min` со `strip` — умолчание, под которым снят
574
- эталон паритета; `min` со `esbuild` — то, что даёт настоящий минификатор, если его
575
- включить (`minify.engine`); `tok` — словарь `o200k_base` с `gpt-tokenizer 4.0.0`.
576
- У проекта прежние настройки означают `strip`, поэтому обновление «само» чисел не
577
- меняет; способ `esbuild` остаётся осознанным решением того, кто его включает.
578
- gzip в выпуск по-прежнему не входит (`PLAN.md` §10, D4).
579
-
580
- ## 1.0.0 — 2026-09-14
581
-
582
- Первый выпуск: инструмент вынесен из проекта-потребителя в отдельный пакет
583
- (`PLAN.md` §5, шаги 0–5) — раньше он жил копией внутри чужого репозитория. Выпусков
584
- до него не было: версия в манифесте стояла `0.0.0`, а работа шла внутри этого
585
- репозитория (`WORKLOG.md`, `REFACTOR.md`, `PLAN.md`); номера `0.1.0`–`0.5.0` в
586
- `PLAN.md` §12 — план выпусков, а не их история.
587
-
588
- Версия `1.0.0` — не про объём изменений, а про заморозку: `schema: 1` данных этой
589
- версией объявлена стабильной, и сломать её теперь можно только MAJOR-выпуском с
590
- миграцией. Версия инструмента попадает в данные (`tool.version`), версии
591
- минификатора и словаря — в способ получения числа, поэтому «числа этого выпуска» —
592
- это числа с `esbuild 0.28.2` и `gpt-tokenizer 4.0.0` в тех разрезах, где они
593
- задействованы.
594
-
595
- ### Что изменится в числах
596
-
597
- Замер на фикстуре, состояние на HEAD (`now`), метрики `raw`, `min`, `tok`, словарь
598
- `o200k_base`:
599
-
600
- | Файл | raw | min со strip | min с esbuild | tok |
601
- |---|---|---|---|---|
602
- | code.js | 735 | 276 | 185 | 168 |
603
- | modern.js | 246 | 51 | 45 | 44 |
604
- | config.mjs | 172 | 45 | 40 | 40 |
605
- | заметки.md | 306 | 303 | 303 | 53 |
606
- | crlf.txt | 63 | 60 | 60 | 10 |
607
- | package.json | 87 | 69 | 69 | 34 |
608
- | style.css | 156 | 55 | 43 | 38 |
609
- | table.toml | 300 | 299 | 299 | 52 |
610
- | empty.js | 0 | 0 | 0 | 0 |
611
- | WORKLOG.md | 446 | 439 | 439 | 101 |
612
- | **ИТОГО** | **2511** | **1597** | **1483** | **540** |
613
-
614
- - **У проекта с прежними настройками не поедет ничего.** Существующие конфиги
615
- `minify.engine` не задают, а умолчание — `strip`: те же комментарии и отступы, те
616
- же имена, те же байты, что у инструмента до этого выпуска. Это доказано не словом:
617
- вывод `--json` и собранный артефакт совпадают побайтово с замороженным эталоном —
618
- на фикстуре и на живой истории проекта-потребителя (`fixtures/synthetic/`,
619
- `fixtures/parity/`, проверки `test/parity.test.js`, `test/frozen.test.js`).
620
- - **`raw` не зависит ни от чего, кроме объекта git**: это его размер, содержимое
621
- файла для этой метрики не читается вовсе. Ни настройки, ни способ минификации, ни
622
- версия инструмента на него не влияют.
623
- - **`min` со `esbuild` меньше**, чем со `strip`, и это единственное, что меняет
624
- числа, если включить настоящее сжатие: имена сокращены, пробелы убраны. На фикстуре
625
- итог 1597 → **1483** (−7 %), по файлам — **−33 %** на `code.js` (276 → 185) и
626
- **−22 %** на `style.css` (55 → 43). Для форматов, которых минификатор не берёт
627
- (`.md`, `.txt`, `.toml`, `.json`), число то же, что со `strip`: 303, 60, 299, 69.
628
- Именно поэтому метрика помечена приближением **целиком**: точность колонки
629
- считается по худшей клетке, а не по большинству (пометка стоит и у отдельной
630
- клетки — `test/minify.test.js`). Способ `esbuild` ставит `--init` новым проектам;
631
- перевод существующего проекта на него — осознанное решение, а не побочный эффект
632
- обновления.
633
- - **`tok` — число новое, сравнивать его не с чем**: метрики не было у прежнего
634
- инструмента, это не «изменилось», а «появилось». Точный счёт словарём даёт на
635
- фикстуре **540**; та же фикстура без словаря считается оценкой по длине
636
- (1 токен ≈ 3 знака) и даёт **583** — число другое, поэтому оно помечено
637
- приближением, а прогон отдаёт **код 4**, а не зелёный успех
638
- (`SIZE_REPORT_NO_OPTIONAL` воспроизводит установку без необязательных
639
- зависимостей).
640
- - **Без `esbuild`** `min` отступает к `strip`: те же 1597, с пометкой приближения и
641
- кодом 4. Числа от этого не ломаются, но и не выдаются за сжатие.
642
- - **`gzip` в 1.0.0 не поставляется**: метрики нет ни в черновике настроек, ни в
643
- документации; в реестре она пока принимается, а её удаление — `PLAN.md` §10 (D4),
644
- изменение поведения, а не перенос.
645
- - **Окружение машины на числа не влияет — и это тоже изменение**, относительно
646
- инструмента до этого выпуска: он читал пути и переводы строк так, как настроена
647
- машина, и на установке Git «по умолчанию» либо давал неверные числа, либо падал
648
- вовсе (`BLOCKERS.md` §B1, §B2, §N10). Теперь вывод одинаков в любой среде, и это
649
- доказывается прогоном с погашенными настройками машины (`GIT_CONFIG_GLOBAL=/dev/null`).
650
-
651
- ### Что вошло
652
-
653
- - Три метрики: `raw` (размер объекта git), `min` (в двух способах — снятие балласта
654
- и настоящее сжатие через `esbuild`), `tok` (токены выбранного словаря). Числа
655
- абсолютные, производные (дельты, суммы, фильтры) считает страница.
656
- - Интерактивный отчёт: дерево файлов, категории, переключение метрик, память выбора
657
- между открытиями и передача выбора ссылкой; страница — один самодостаточный файл,
658
- открывается с диска без сети.
659
- - Команды: сборка отчёта, сверка с историей (`size check`), объяснение пропущенной
660
- строки (`size explain <sha>`), диагностика (`size doctor`), установка и снятие
661
- хука автообновления отчёта, `--init` с черновиком настроек.
662
- - Шаблоны для подключаемого проекта: черновик настроек и описание проверки для CI.
663
- - Сторожа, которыми проверяется не код, а обещания: паритет с замороженным эталоном,
664
- живая история, работа из собранного пака, утверждения документации, закрепления
665
- настроек git на границе вызова.
666
-
667
- ### Исправлено
668
-
669
- - Молчание при опечатках и в несовместимых сочетаниях ключей: неизвестное слово,
670
- лишнее слово, два режима сразу, ключ без значения и `--json` там, где ответа в
671
- JSON нет, — теперь отказ с названным виновником и готовой командой, а не код 0 с
672
- чужой работой.
673
- - Колонка, чей файл жил в истории и был удалён до HEAD, роняла прогон с бессмысленным
674
- текстом отказа; выбор пути перестал зависеть от настроек переименований
675
- (`BLOCKERS.md` §B3, §N8).
676
- - Зависимость чисел от окружения машины (`BLOCKERS.md` §B1, §B2, §N10).
677
-
678
- ### Не входит в 1.0.0
679
-
680
- - `docs/METHODS.md`, `docs/DATA-FORMAT.md`, `docs/ARCHITECTURE.md` — документация
681
- пакета из `PLAN.md` §8.3; сегодня роль каждого числа описана в `README.md`.
682
- - Кэш замеров, разделение быстрого и медленного наборов проверок, профиль на истории
683
- в пару тысяч коммитов — `PLAN.md` §5, шаг 6.
684
- - Удаление метрики `gzip` из реестра (`PLAN.md` §10, D4) и лицензионный файл
685
- (открытый вопрос §10).
686
- - Поставка `dist/app.js` (пре-собранная программа отчёта) и публикация в npm:
687
- установка идёт git-зависимостью из публичного репозитория (публичным он стал
688
- 2026-09-14, `WORKLOG.md` §44), а в npm пакет не опубликован — `PLAN.md` §8.4.
689
- - Минификация разметки (HTML), JSX/TSX и другие семейства токенизаторов, кроме
690
- `openai`: у них нет своего словаря, а считать чужим — выдавать догадку за число.