@vernikr/size-report 2.0.1 → 2.1.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 +82 -0
- package/README.md +74 -34
- package/package.json +2 -2
- package/src/css.js +1 -1
- package/src/locales.js +0 -10
- package/src/page/app.css +67 -38
- package/src/page/app.js +30 -5
- package/src/page/build.js +0 -7
- package/src/page/panel.js +3 -16
- package/templates/README.md +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -18,6 +18,88 @@
|
|
|
18
18
|
где за основу взяты `fixtures/synthetic/config.json`, метрики — `raw`, `min`, `tok`, а
|
|
19
19
|
способ минификации — `strip` или `esbuild`.
|
|
20
20
|
|
|
21
|
+
## 2.1.0 — 2026-09-15
|
|
22
|
+
|
|
23
|
+
Вид страницы на десктопе: числам — вся оставшаяся высота, панели — своя прокрутка.
|
|
24
|
+
|
|
25
|
+
- **Под таблицей была пустота, а список файлов задавал высоту страницы.** На широком
|
|
26
|
+
экране оба столбца шли каждый со своей высотой (`align-items: start`), поэтому
|
|
27
|
+
высота страницы равнялась тому, что вышло у панели: замер до правки при окне
|
|
28
|
+
1440×900 — панель 883 px, страница 1097 при окне 900, под таблицей 195 px пустоты,
|
|
29
|
+
а нижние файлы дерева — за нижним краем окна (список при этом ещё и резался своим
|
|
30
|
+
потолком в 62vh). Теперь страница целиком укладывается в окно: строки сетки
|
|
31
|
+
названы по предмету, тянется одна рабочая — таблица берёт всю оставшуюся высоту
|
|
32
|
+
(1440×900: 1060 × 735 вместо 602), панель — не больше неё и прокручивается сама
|
|
33
|
+
(содержимое 804 при высоте 785). Список файлов на широком экране больше не режется:
|
|
34
|
+
все 23 подписи дерева видны сразу.
|
|
35
|
+
- **Клик по галочке возвращал список к началу.** Панель рисуется заново, и вместе с
|
|
36
|
+
ней терялось место, до которого докурили: до нижних файлов дерева было не
|
|
37
|
+
добраться. Прокрутка панели и списка теперь часть вида — запоминается перед
|
|
38
|
+
пересборкой и ставится обратно (подтверждено в Chrome: при окне 1440×500
|
|
39
|
+
`panel.scrollTop` = 421 до клика и 421 после).
|
|
40
|
+
- **Строка категорий липнет** к верху панели, пока листается дерево. Чтобы под
|
|
41
|
+
липкой строкой не читались проезжающие файлы, верхний отступ панели переехал в
|
|
42
|
+
первое поле: прокручиваемое видно и в отступе прокрутки (в полосе 13 px читались
|
|
43
|
+
`parity/` и `data.json` — теперь там сама строка).
|
|
44
|
+
- **Расшифровка под деревом убрана**, а шрифт подписей файлов стал как у чисел
|
|
45
|
+
таблицы (12,5 px): расшифровка отодвигала числа, а её смысл стоит у того, что
|
|
46
|
+
объясняет — цвет дельты называет знак числа, способ и точность стоят под
|
|
47
|
+
переключателями метрик, знак пропуска — в подсказке клетки.
|
|
48
|
+
- **Граница широкой раскладки — 899 px.** При ровно 900 px обе половины оформления
|
|
49
|
+
применялись к одной странице, и от «узкой» в «широкой» оставался потолок высоты
|
|
50
|
+
таблицы: те же пустые 179 px под ней на одном размере окна.
|
|
51
|
+
|
|
52
|
+
### Что изменится в числах
|
|
53
|
+
|
|
54
|
+
**Ничего.** Правка — про вид страницы и прокрутку; движок тот же, что у 2.0.2, а
|
|
55
|
+
страница получает от него готовые числа.
|
|
56
|
+
|
|
57
|
+
| Файл | raw | min со strip | min с esbuild | tok |
|
|
58
|
+
|---|---|---|---|---|
|
|
59
|
+
| code.js | 735 | 276 | 185 | 168 |
|
|
60
|
+
| modern.js | 246 | 51 | 45 | 44 |
|
|
61
|
+
| config.mjs | 172 | 45 | 40 | 40 |
|
|
62
|
+
| заметки.md | 306 | 303 | 303 | 53 |
|
|
63
|
+
| crlf.txt | 63 | 60 | 60 | 10 |
|
|
64
|
+
| package.json | 87 | 69 | 69 | 34 |
|
|
65
|
+
| style.css | 156 | 55 | 43 | 38 |
|
|
66
|
+
| table.toml | 300 | 299 | 299 | 52 |
|
|
67
|
+
| empty.js | 0 | 0 | 0 | 0 |
|
|
68
|
+
| WORKLOG.md | 446 | 439 | 439 | 101 |
|
|
69
|
+
| **ИТОГО** | **2511** | **1597** | **1483** | **540** |
|
|
70
|
+
|
|
71
|
+
## 2.0.2 — 2026-09-15
|
|
72
|
+
|
|
73
|
+
Инструкция перестала обещать лишний ручной шаг и назвала платформенную разницу.
|
|
74
|
+
|
|
75
|
+
- **README учил ставить хук руками.** В §6 осталась строка прежнего выпуска — «хуки
|
|
76
|
+
ставятся только командой `install-hook`, ни один обычный запуск их не создаёт», — а с
|
|
77
|
+
2.0.0 постановка своя (`bin/postinstall.js` и первый запуск). Текст теперь говорит то,
|
|
78
|
+
что делает код, и называет единственное исключение: pnpm 10 не исполняет скрипты
|
|
79
|
+
зависимостей («Ignored build scripts») — там хук ставит первый запуск, либо сборка
|
|
80
|
+
разрешается `pnpm.onlyBuiltDependencies` в манифесте потребителя.
|
|
81
|
+
- **Названа одна ручная ступень, которая была невидимой.** Первый отчёт создаётся, но не
|
|
82
|
+
коммитится (новый файл в чужой истории — решение человека): это сказано в §6 и в
|
|
83
|
+
шаблоне `templates/README.md`, дальше отчёт обновляется отдельными коммитами сам.
|
|
84
|
+
|
|
85
|
+
### Что изменится в числах
|
|
86
|
+
|
|
87
|
+
**Ничего.** Правка — только текст инструкции; движок тот же, что у 2.0.1.
|
|
88
|
+
|
|
89
|
+
| Файл | raw | min со strip | min с esbuild | tok |
|
|
90
|
+
|---|---|---|---|---|
|
|
91
|
+
| code.js | 735 | 276 | 185 | 168 |
|
|
92
|
+
| modern.js | 246 | 51 | 45 | 44 |
|
|
93
|
+
| config.mjs | 172 | 45 | 40 | 40 |
|
|
94
|
+
| заметки.md | 306 | 303 | 303 | 53 |
|
|
95
|
+
| crlf.txt | 63 | 60 | 60 | 10 |
|
|
96
|
+
| package.json | 87 | 69 | 69 | 34 |
|
|
97
|
+
| style.css | 156 | 55 | 43 | 38 |
|
|
98
|
+
| table.toml | 300 | 299 | 299 | 52 |
|
|
99
|
+
| empty.js | 0 | 0 | 0 | 0 |
|
|
100
|
+
| WORKLOG.md | 446 | 439 | 439 | 101 |
|
|
101
|
+
| **ИТОГО** | **2511** | **1597** | **1483** | **540** |
|
|
102
|
+
|
|
21
103
|
## 2.0.1 — 2026-09-15
|
|
22
104
|
|
|
23
105
|
Место отчёта в свежем проекте: `docs/size-report.html`, и каталог создаётся сам.
|
package/README.md
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
|
|
11
11
|
## Статус
|
|
12
12
|
|
|
13
|
-
**Выпуск 2.0
|
|
13
|
+
**Выпуск 2.1.0 (2026-09-15).** Инструмент живёт отдельным пакетом: имя в
|
|
14
14
|
реестре — `@vernikr/size-report` (публикуется тегом из CI, без секрета). Настроек
|
|
15
15
|
проект может не заводить вовсе: без файла инструмент выводит их из самого проекта и
|
|
16
16
|
говорит об этом строкой, а `--init` закрепляет выведенное файлом (чем этот шаг
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
в числах»:
|
|
23
23
|
таблица чисел в нём не пересказ, а замер на фикстуре, который сверяется с живым
|
|
24
24
|
прогоном (`test/changelog.test.js`). Числа этим выпуском не меняются — правки
|
|
25
|
-
лежат в
|
|
25
|
+
лежат в виде страницы отчёта на десктопе; `schema: 1` данных, замороженная 1.0.0,
|
|
26
26
|
остаётся той же.
|
|
27
27
|
|
|
28
28
|
**Шаг 1 плана пройден — перенос без изменения поведения.** Команда —
|
|
@@ -219,10 +219,10 @@
|
|
|
219
219
|
|
|
220
220
|
| Прогон | Команда | Проверок |
|
|
221
221
|
|---|---|---|
|
|
222
|
-
| Быстрый — каждая правка | `pnpm test` | **
|
|
223
|
-
| Полный — выкладка и CI | `pnpm test:all` | **
|
|
222
|
+
| Быстрый — каждая правка | `pnpm test` | **66 из 170** |
|
|
223
|
+
| Полный — выкладка и CI | `pnpm test:all` | **170** |
|
|
224
224
|
|
|
225
|
-
Ни одна проверка не потеряна и не ослаблена: полный прогон запускает все
|
|
225
|
+
Ни одна проверка не потеряна и не ослаблена: полный прогон запускает все 170 теми же
|
|
226
226
|
файлами, а быстрый берёт их часть. Умолчание — полный: файл становится быстрым только
|
|
227
227
|
явно и с причиной, поэтому новое дорогое не может тихо уехать в быстрый. Стерегут это
|
|
228
228
|
объявление `test/suites.test.js` (полнота классификации и причина у каждого файла) и
|
|
@@ -309,8 +309,8 @@ Trusted Publisher в настройках пакета), права **publish**
|
|
|
309
309
|
один набор стилей таблицы на оба вывода (`src/table.css`) — странице достались
|
|
310
310
|
липкие шапка и колонка коммита, которые раньше были только у статического
|
|
311
311
|
артефакта, и она больше не уезжает вбок в узком окне (до правки — 1518px при
|
|
312
|
-
окне 620). Добавились
|
|
313
|
-
|
|
312
|
+
окне 620). Добавились состояния «нечего показать» (сняты все метрики или все
|
|
313
|
+
файлы) и переключатели, доступные с клавиатуры. Цвет
|
|
314
314
|
deльт задан один раз и по артефакту: рост зелёный, спад красный — смена это две
|
|
315
315
|
строки в `src/table.css` плюс пересборка эталона артефакта, больше цвета нигде нет.
|
|
316
316
|
|
|
@@ -319,20 +319,29 @@ deльт задан один раз и по артефакту: рост зел
|
|
|
319
319
|
папки три состояния — все её файлы включены, часть, ни одного, — и переключатель
|
|
320
320
|
папки ведёт за собой всё поддерево; рядом стоит число файлов. Своего состояния у
|
|
321
321
|
папки и у быстрой кнопки категории нет: обе переставляют галочки файлов, поэтому
|
|
322
|
-
дерево, кнопки и таблица не могут разойтись. Список файлов
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
322
|
+
дерево, кнопки и таблица не могут разойтись. Список файлов длиннее панели
|
|
323
|
+
прокручивается, а не выталкивает таблицу, — и прокрутка эта одна: на широком
|
|
324
|
+
экране листается панель целиком (дерево в ней видно целиком: 23 подписи из 23 при
|
|
325
|
+
окне 1440×900), а на узком — сам список, потому что там панель растёт вместе со
|
|
326
|
+
страницей.
|
|
327
|
+
|
|
328
|
+
**На широком экране панель стоит слева от таблицы и не вытесняет числа**
|
|
329
|
+
(от 900 px, `src/page/app.css`). Это не украшение: на десктопе бокового места
|
|
330
|
+
много, а вертикального мало — переключатели, дерево и числа видны одновременно, и
|
|
331
|
+
ни прокрутка чисел, ни прокрутка дерева не уводит управление за верх экрана.
|
|
332
|
+
Раскладка сделана сеткой на `body`: обёртки в разметке нет, потому что страница
|
|
333
|
+
собирается вклейкой глав и форма страницы должна жить в одном месте. Строк у сетки
|
|
334
|
+
пять и они названы по предмету (заголовок, сообщение о ссылке, работа, сообщение
|
|
335
|
+
пустоты, подпись), тянется только рабочая: таблица берёт всю оставшуюся высоту, а
|
|
336
|
+
панель — не больше неё. Цена прежнего поведения была видна глазом: высоту страницы
|
|
337
|
+
задавал список файлов, и под таблицей оставалась пустота (замер до правки при окне
|
|
338
|
+
1440×900: панель 883 px, страница 1097 при окне 900, под таблицей 195 px).
|
|
339
|
+
Измерено в настоящем Chrome после правки: при 1440×900 страница ровно в окно
|
|
340
|
+
(900), панель — колонка 300 px слева (103…888, содержимое 804 — дальше она
|
|
341
|
+
прокручивается), таблица 1060 × 735 на том же верху 103 (до правки 1060 × 602), а
|
|
342
|
+
под ней остаётся только подпись под таблицей (62 px); при 1024×800 — те же 300 и
|
|
343
|
+
таблица 651 × 620; при 899 раскладка снимается и столбцы снова идут друг под
|
|
344
|
+
другом (панель 871, таблица 871 × 442, страница прокручивается — 972).
|
|
336
345
|
Стрежет это проверка на числах таблицы, а не на разметке: выключение папки убирает
|
|
337
346
|
ровно её колонки и ровно её объём из итога (`test/contract.test.js`). Проверено в
|
|
338
347
|
настоящем Chrome: 9 папок до трёх уровней вложенности (`.github/workflows`,
|
|
@@ -340,6 +349,29 @@ deльт задан один раз и по артефакту: рост зел
|
|
|
340
349
|
ни одной ошибки в консоли, `docs/6` после выключения одного своего файла показала
|
|
341
350
|
третье состояние, а после выключения целиком — 52 колонки → 40.
|
|
342
351
|
|
|
352
|
+
**Галочка не отбирает ни прокрутку, ни место у чисел** (правка вида страницы
|
|
353
|
+
2026-09-15, `src/page/app.js`, `src/page/app.css`). Панель рисуется заново после
|
|
354
|
+
каждого переключения, и вместе с ней терялось место, до которого читатель
|
|
355
|
+
долистал: клик по галочке возвращал список к началу, а до нижних файлов дерева так
|
|
356
|
+
и не добирались. Теперь прокрутка панели и списка — часть вида, как галочки: она
|
|
357
|
+
запоминается перед пересборкой и ставится обратно после (фокус возвращается без
|
|
358
|
+
прокрутки — `preventScroll`), а поле «Файлы» больше не режет дерево своим
|
|
359
|
+
потолком в 62vh. Строка категорий («Код», «Документация», «Служебные») в широкой
|
|
360
|
+
раскладке липнет к верху панели — фон у неё тот же, что у панели, поэтому под ней
|
|
361
|
+
не читаются проезжающие файлы; верхний отступ панели для этого переехал в первое
|
|
362
|
+
поле (прокручиваемое видно и в отступе прокрутки — замер: до него в полосе 13 px
|
|
363
|
+
читались «parity/» и «data.json», после — сама строка). Шрифт подписей файлов
|
|
364
|
+
стал как у чисел таблицы (12,5 px), а расшифровка под деревом убрана: она
|
|
365
|
+
отодвигала числа, а её смысл и так стоит у того, что объясняет (знак числа называет
|
|
366
|
+
цвет дельты, способ и точность — под переключателями метрик, знак пропуска —
|
|
367
|
+
в подсказке клетки). Заодно граница широкой раскладки стала 899 px: при ровно
|
|
368
|
+
900 px обе половины оформления применялись к одной странице, и от «узкой» в
|
|
369
|
+
«широкой» оставался потолок высоты таблицы — те же пустые 179 px под ней на одном
|
|
370
|
+
единственном размере окна. Проверено в настоящем Chrome на этой странице: при
|
|
371
|
+
окне 1440×500 (панель прокручивается) и прокрутке до последнего файла
|
|
372
|
+
`panel.scrollTop` = 421 до клика и 421 после, строка категорий стоит на 1 px от
|
|
373
|
+
верхнего края панели, а под ней на всех полосах прокрутки — только её же подписи.
|
|
374
|
+
|
|
343
375
|
**Панель помнит выбор читателя** (`REFACTOR.md` R-2.5). Запись хранится в памяти
|
|
344
376
|
браузера, и она привязана к «паспорту отчёта» — имя инструмента, схема данных,
|
|
345
377
|
путь артефакта, заголовок и метки колонок; в ключ входит отпечаток паспорта,
|
|
@@ -518,12 +550,12 @@ deльт задан один раз и по артефакту: рост зел
|
|
|
518
550
|
| `src/derived.js` | Общий расчёт отчёта: итоги, дельты, клетка, подпись коммита — один на движок и программу страницы |
|
|
519
551
|
| `src/css.js` | Чтение оформления с диска: какие наборы стилей есть и какая у них роль |
|
|
520
552
|
| `src/table.css` | Таблица отчёта: геометрия клеток, липкие шапка и колонка, цвет дельт |
|
|
521
|
-
| `src/page/app.css` | Оформление страницы сверх общей части: панель с деревом файлов (на широком экране — колонка
|
|
553
|
+
| `src/page/app.css` | Оформление страницы сверх общей части: панель с деревом файлов и липкой строкой категорий (на широком экране — колонка слева, страница в окно), состояния пустоты, узкое окно |
|
|
522
554
|
| `src/page/state.js` | Состояние страницы: данные отчёта, вид галочек, паспорт записи, память браузера и обмен ссылкой — глава программы страницы |
|
|
523
555
|
| `src/page/dom.js` | Узлы страницы: мелкие помощники разметки (`appEl`, `appBox`) — одни на панель и таблицу |
|
|
524
|
-
| `src/page/panel.js` | Панель выбора: галочки метрик и файлов, категории, дерево
|
|
556
|
+
| `src/page/panel.js` | Панель выбора: галочки метрик и файлов, категории, дерево путей; перерисовку просит у главы сборки |
|
|
525
557
|
| `src/page/table.js` | Таблица страницы: клетка, подпись коммита, шапка и состояния пустоты — разметка поверх общего расчёта |
|
|
526
|
-
| `src/page/app.js` | Сборка и запуск страницы: таблица целиком, перерисовка по выбору
|
|
558
|
+
| `src/page/app.js` | Сборка и запуск страницы: таблица целиком, перерисовка по выбору читателя (с возвратом фокуса и прокрутки), первая отрисовка и смена якоря; вклеивается в собранную страницу
|
|
527
559
|
| `src/page/build.js` | Сборка страницы: данные, оформление и программа в одном файле без внешних ссылок |
|
|
528
560
|
| `src/git.js` | Единственная граница вызова git: закрепления настроек, блобы пачкой, история, сверка с диском |
|
|
529
561
|
| `src/strip.js` | Снятие балласта: какая форма к какому файлу (расширение, стратегия) и что считать точным числом — вход разбора форм |
|
|
@@ -643,7 +675,7 @@ pnpm add -D @vernikr/size-report
|
|
|
643
675
|
```
|
|
644
676
|
|
|
645
677
|
Пакет **опубликован в реестре**, и публично: `npm view @vernikr/size-report
|
|
646
|
-
version` отвечает `2.0
|
|
678
|
+
version` отвечает `2.1.0`, `npm access get status @vernikr/size-report` — `public`,
|
|
647
679
|
а анонимный запрос тарболла — код 200. `npm i -D` и `yarn add -D` принимают то же
|
|
648
680
|
имя; ни ключа, ни ссылки на репозиторий не нужно.
|
|
649
681
|
|
|
@@ -651,11 +683,11 @@ version` отвечает `2.0.1`, `npm access get status @vernikr/size-report`
|
|
|
651
683
|
реестра, но остаётся привязанной к ревизии:
|
|
652
684
|
|
|
653
685
|
```bash
|
|
654
|
-
pnpm add -D github:vernikr/size-report#v2.0
|
|
686
|
+
pnpm add -D github:vernikr/size-report#v2.1.0
|
|
655
687
|
```
|
|
656
688
|
|
|
657
689
|
Без сети (или если тянуть из codeload нечем) — тарболл: `pnpm pack` в клоне
|
|
658
|
-
пакета, затем `pnpm add -D ./vernikr-size-report-2.0.
|
|
690
|
+
пакета, затем `pnpm add -D ./vernikr-size-report-2.1.0.tgz`.
|
|
659
691
|
|
|
660
692
|
**Почему тег, а не sha.** Короткий sha pnpm разрешает только через видимые рефы, а
|
|
661
693
|
`git ls-remote` отдаёт одни верхушки веток: пока ревизия — верхушка, короткий sha
|
|
@@ -663,7 +695,7 @@ pnpm add -D github:vernikr/size-report#v2.0.1
|
|
|
663
695
|
<sha> to a commit`. Это не рассуждение, а проба: короткий пин `6530237` ставился,
|
|
664
696
|
пока `main` стоял на нём, и перестал — на следующем же коммите, а тот же sha
|
|
665
697
|
целиком поставился. Имя ветки (`#main`) или тег принимаются оба, но ветка —
|
|
666
|
-
движущаяся цель, а тег постоянен: этот выпуск стоит на теге `v2.0
|
|
698
|
+
движущаяся цель, а тег постоянен: этот выпуск стоит на теге `v2.1.0`, он же и в
|
|
667
699
|
примере (сорок знаков тоже годятся, но их придётся брать глазами из истории).
|
|
668
700
|
|
|
669
701
|
Ревизия в примере — не украшение, а часть утверждения: она закреплена за тем, что
|
|
@@ -836,18 +868,26 @@ pnpm exec size doctor # 0 — делать нечего; иначе перв
|
|
|
836
868
|
| 4 | нет датчика | `minify.engine: "esbuild"`, а минификатора нет: числа получены упрощением. Отчёт собран, причина и починка — в тексте; если при этом таблица расходится с историей, код остаётся **1** (нарушение старше приближения), а заметка о другом счёте печатается рядом |
|
|
837
869
|
| 5 | внутренняя ошибка | это дефект инструмента: текст нужен нам, см. «Ловушки» ниже |
|
|
838
870
|
|
|
839
|
-
### 6. Отчёт обновляется сам после коммита
|
|
871
|
+
### 6. Отчёт обновляется сам после коммита
|
|
840
872
|
|
|
841
873
|
```bash
|
|
842
874
|
pnpm exec size install-hook # поставить post-commit и post-merge
|
|
843
875
|
pnpm exec size uninstall-hook # снять и вернуть проект к прежнему поведению
|
|
844
876
|
```
|
|
845
877
|
|
|
846
|
-
Хуки ставятся
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
878
|
+
Хуки ставятся **сами**, и это единственное, что проект замечает от установки пакета:
|
|
879
|
+
после `npm i` — скриптом установки, у pnpm 10 — первым запуском инструмента (pnpm не
|
|
880
|
+
исполняет скрипты зависимостей: «Ignored build scripts»; разрешить можно
|
|
881
|
+
`pnpm.onlyBuiltDependencies: ["@vernikr/size-report"]` в своём манифесте). Ставшие
|
|
882
|
+
файлы живут в `.git`, `git status` их не видит, снимаются командой выше. После
|
|
883
|
+
каждого коммита и слияния отчёт пересобирается: каталог `docs` и файл `size-report.html`
|
|
884
|
+
создаются, если их ещё нет, а **отслеживаемый** в git отчёт ложится отдельным коммитом
|
|
885
|
+
с подписью `chore(report): отчёт пересобран после <sha>`. Коммитится только путь отчёта:
|
|
886
|
+
чужой индекс и незакоммиченная работа не тронуты.
|
|
887
|
+
|
|
888
|
+
Первый отчёт — исключение из «сам»: файл создан, но не закоммичен, потому что новый
|
|
889
|
+
файл в чужой истории — решение человека, а не услуга. Один `git add docs/size-report.html`
|
|
890
|
+
(или обычный `git add -A`, если отчёт нужен в проекте) — и дальше он едет коммитами сам.
|
|
851
891
|
Слияние обрабатывается тем же входом, что обычный коммит, но другим файлом —
|
|
852
892
|
`post-merge`: git создаёт коммит слияния сам и `post-commit` при этом не зовёт.
|
|
853
893
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vernikr/size-report",
|
|
3
|
-
"version": "2.0
|
|
3
|
+
"version": "2.1.0",
|
|
4
4
|
"author": "vernikr",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -66,7 +66,7 @@
|
|
|
66
66
|
"report"
|
|
67
67
|
],
|
|
68
68
|
"devDependencies": {
|
|
69
|
-
"@vernikr/size-report": "2.0.
|
|
69
|
+
"@vernikr/size-report": "2.0.2",
|
|
70
70
|
"c8": "10",
|
|
71
71
|
"dependency-cruiser": "17",
|
|
72
72
|
"eslint": "^9.18.0",
|
package/src/css.js
CHANGED
|
@@ -10,7 +10,7 @@ import fs from 'node:fs';
|
|
|
10
10
|
* 1. `table.css` — **таблица**: геометрия клеток, липкие шапка и колонка коммита,
|
|
11
11
|
* подпись коммита, цвета дельт.
|
|
12
12
|
* 2. `page/app.css` — оформление страницы **сверх таблицы**: холст, панель
|
|
13
|
-
* выбора,
|
|
13
|
+
* выбора, состояния пустоты и адаптации под узкое окно.
|
|
14
14
|
*
|
|
15
15
|
* Соглашение о цвете дельт задано один раз — в `table.css`: `.up` зелёный, `.down`
|
|
16
16
|
* красный (рост — «больше логики», а не тревога). Второго места у него нет
|
package/src/locales.js
CHANGED
|
@@ -21,11 +21,6 @@ export const LOCALES = {
|
|
|
21
21
|
dir: 'все файлы папки {name} ({n})',
|
|
22
22
|
all: 'все',
|
|
23
23
|
sub: '{tool} {version} · {artifact}',
|
|
24
|
-
legendUp: 'рост',
|
|
25
|
-
legendDown: 'спад',
|
|
26
|
-
legendSame: 'пустая клетка — не менялось',
|
|
27
|
-
legendMiss: '«—» — файла в этой ревизии ещё нет',
|
|
28
|
-
legendApprox: 'подчёркнутое число — приближённое: способ назван под метриками',
|
|
29
24
|
/* Слова точности: подпись метрики говорит про худшее в колонке, а клетки —
|
|
30
25
|
* про своё число. Одно слово на подпись и на подсказку клетки, чтобы не
|
|
31
26
|
* разошлось и не звучало по-разному. */
|
|
@@ -77,11 +72,6 @@ export const LOCALES = {
|
|
|
77
72
|
dir: 'all files in “{name}” ({n})',
|
|
78
73
|
all: 'all',
|
|
79
74
|
sub: '{tool} {version} · {artifact}',
|
|
80
|
-
legendUp: 'growth',
|
|
81
|
-
legendDown: 'fall',
|
|
82
|
-
legendSame: 'an empty cell — no change',
|
|
83
|
-
legendMiss: '“—” — the file does not exist in that revision yet',
|
|
84
|
-
legendApprox: 'an underlined number is approximate: its way of measuring is named under the metrics',
|
|
85
75
|
exact: 'an exact number',
|
|
86
76
|
approximate: 'an approximation',
|
|
87
77
|
approximateCell: 'an approximate number: ',
|
package/src/page/app.css
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/* Оформление страницы отчёта — то, что стоит сверх общей таблицы (`src/table.css`):
|
|
2
|
-
* холст и типографика, панель
|
|
2
|
+
* холст и типографика, панель выбора, состояния пустоты и адаптации под
|
|
3
3
|
* узкое окно. Чисел и цвета дельт здесь нет намеренно: их задаёт общая часть, и она
|
|
4
4
|
* же попадает в статический артефакт, поэтому двух наборов одной таблицы не
|
|
5
5
|
* бывает. Страница открывается с диска, без сервера и без сети, поэтому ни одной
|
|
@@ -64,8 +64,13 @@ h1 { margin: 0 0 3px; font-size: 21px; font-weight: 650; letter-spacing: -.012em
|
|
|
64
64
|
/* Дерево файлов: вложенность показана отступом и линией уровня, папка — такой же
|
|
65
65
|
* переключатель, как файл, только его галочка отвечает за всё поддерево, а число
|
|
66
66
|
* рядом говорит, за сколько файлов. Список файлов длиннее окна, поэтому панель
|
|
67
|
-
* прокручивается сама: иначе управление вытолкнуло бы таблицу за экран.
|
|
68
|
-
|
|
67
|
+
* прокручивается сама: иначе управление вытолкнуло бы таблицу за экран.
|
|
68
|
+
*
|
|
69
|
+
* На узком экране прокручивается сам список (панель там растёт вместе со
|
|
70
|
+
* страницей), на широком — панель целиком (ниже): прокрутка одна, и она у того,
|
|
71
|
+
* кто и вправду ограничен окном. Шрифт файлов — тот же, что у чисел таблицы:
|
|
72
|
+
* подписей в списке много и они короткие, а рядом с ними стоит таблица. */
|
|
73
|
+
.panel .files { max-height: min(30vh, 320px); overflow: auto; font-size: 12.5px; }
|
|
69
74
|
.panel .tree { margin: 0; padding: 0; list-style: none; }
|
|
70
75
|
.panel .tree .tree { margin-left: 14px; padding-left: 9px; border-left: 1px solid var(--line); }
|
|
71
76
|
.panel .tree .box { padding: 1px 7px 1px 5px; }
|
|
@@ -87,25 +92,12 @@ h1 { margin: 0 0 3px; font-size: 21px; font-weight: 650; letter-spacing: -.012em
|
|
|
87
92
|
.box input { margin: 0; accent-color: AccentColor; }
|
|
88
93
|
.box.all { font-weight: 600; }
|
|
89
94
|
|
|
90
|
-
/*
|
|
91
|
-
*
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
margin: 10px 0 0;
|
|
97
|
-
padding: 0;
|
|
98
|
-
list-style: none;
|
|
99
|
-
color: var(--muted);
|
|
100
|
-
font-size: 12px;
|
|
101
|
-
}
|
|
102
|
-
.legend li { display: inline-flex; gap: 6px; align-items: center; }
|
|
103
|
-
.swatch { width: 10px; height: 10px; border-radius: 3px; background: currentColor; }
|
|
104
|
-
.swatch.same { background: none; border: 1px dashed currentColor; }
|
|
105
|
-
.swatch.miss { background: none; border: 1px solid currentColor; border-radius: 0; }
|
|
106
|
-
.swatch.approx { background: none; border-bottom: 2px dotted currentColor; }
|
|
107
|
-
|
|
108
|
-
/* Приближённое число помечено пунктиром, а не цветом: цвет в таблице занят дельтой
|
|
95
|
+
/* Расшифровки под деревом файлов нет намеренно: под списком она отодвигала
|
|
96
|
+
* числа, а её содержимое и так стоит рядом с тем, что объясняет, — цвет дельт
|
|
97
|
+
* называет сам знак числа, точность стоит под переключателями метрик, а знак
|
|
98
|
+
* «файла ещё нет» — в подсказке клетки.
|
|
99
|
+
*
|
|
100
|
+
* Приближённое число помечено пунктиром, а не цветом: цвет в таблице занят дельтой
|
|
109
101
|
* (рост и спад), и второй смысл на том же признаке читался бы как первый. */
|
|
110
102
|
#grid td.approx { text-decoration: underline dotted; text-underline-offset: 2.5px; }
|
|
111
103
|
|
|
@@ -154,39 +146,76 @@ h1 { margin: 0 0 3px; font-size: 21px; font-weight: 650; letter-spacing: -.012em
|
|
|
154
146
|
* сдвигает разметку. Ссылки журнала и все переключатели доступны с Tab. */
|
|
155
147
|
:focus-visible { outline: 2px solid AccentColor; outline-offset: 2px; border-radius: 3px; }
|
|
156
148
|
|
|
157
|
-
/* Широкая страница: панель выбора (метрики, дерево
|
|
158
|
-
*
|
|
159
|
-
* мало — переключатели и числа видны
|
|
149
|
+
/* Широкая страница: панель выбора (метрики, дерево файлов) стоит **слева** от
|
|
150
|
+
* таблицы, а страница целиком укладывается в окно. Это не украшение: на десктопе
|
|
151
|
+
* бокового места много, а вертикального мало — переключатели и числа видны
|
|
152
|
+
* одновременно, и ни прокрутка чисел, ни прокрутка списка файлов не уводит
|
|
160
153
|
* управление за экран. Узкое окно эту же раскладку снимает (ниже): там столбцы
|
|
161
154
|
* снова идут друг под другом, потому что рядом им не хватает ширины.
|
|
162
155
|
*
|
|
163
156
|
* Раскладка — сетка на `body`, а не обёртка в разметке: страница собирается
|
|
164
157
|
* вклейкой глав (`src/page/build.js`), и добавлять ей узлы ради оформления значило
|
|
165
|
-
* бы менять форму страницы в двух местах вместо одного.
|
|
158
|
+
* бы менять форму страницы в двух местах вместо одного. Строк пять, и они названы
|
|
159
|
+
* по предмету: заголовок, сообщение о ссылке, **рабочая строка**, сообщение
|
|
160
|
+
* пустоты и подпись. Тянется только рабочая — таблица получает всю оставшуюся
|
|
161
|
+
* высоту, а панель не больше неё; при этом своя высота у панели не «сколько
|
|
162
|
+
* получилось» (тогда она вытолкнула бы таблицу за экран), а та же рабочая строка,
|
|
163
|
+
* внутри которой она прокручивается: список файлов длиннее окна — обычное дело.
|
|
166
164
|
*
|
|
167
165
|
* Порог 900px — тот же, что у адаптаций ниже: одна граница на «широко» и «узко»,
|
|
168
166
|
* иначе между двумя порогами страница осталась бы без ни одного правила. */
|
|
169
167
|
@media (min-width: 900px) {
|
|
170
168
|
body {
|
|
169
|
+
box-sizing: border-box;
|
|
170
|
+
height: 100vh;
|
|
171
|
+
height: 100dvh;
|
|
172
|
+
padding-bottom: var(--gap);
|
|
173
|
+
overflow: auto;
|
|
171
174
|
display: grid;
|
|
172
175
|
grid-template-columns: minmax(230px, 300px) minmax(0, 1fr);
|
|
176
|
+
grid-template-rows: auto auto minmax(0, 1fr) auto auto;
|
|
173
177
|
column-gap: var(--gap);
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
+
align-items: stretch;
|
|
179
|
+
}
|
|
180
|
+
header { grid-area: 1 / 1 / 2 / -1; }
|
|
181
|
+
#notice { grid-area: 2 / 2 / 3 / 3; }
|
|
182
|
+
#shell { grid-area: 3 / 2 / 4 / 3; }
|
|
183
|
+
#state { grid-area: 4 / 2 / 5 / 3; align-self: start; }
|
|
184
|
+
#note { grid-area: 5 / 2 / 6 / 3; }
|
|
185
|
+
/* Работа — на всю высоту, как и таблица: панель кончается там же, где она.
|
|
186
|
+
* Прокручивается панель, а не страница. Верхнего отступа у неё здесь нет:
|
|
187
|
+
* список проезжает под ним, и липкая строка категорий стояла бы не вплотную к
|
|
188
|
+
* краю, а под полосой проезжающих файлов. Отступ никуда не делся — он у первого
|
|
189
|
+
* поля, и уезжает вместе с ним. */
|
|
190
|
+
#panel { grid-area: 2 / 1 / -1 / 2; min-height: 0; margin-bottom: 0; padding-top: 0; overflow: auto; }
|
|
191
|
+
.panel > fieldset:first-child { padding-top: 12px; }
|
|
192
|
+
/* Высоту таблицы здесь задаёт строка, а не окно: своё правило высоты ей нужно
|
|
193
|
+
* только в узком окне, где страница прокручивается целиком. */
|
|
194
|
+
.shell { max-height: none; }
|
|
195
|
+
/* Прокрутка у панели одна: список файлов больше её не заводит, и поле «Файлы»
|
|
196
|
+
* не режет дерево своим потолком. */
|
|
197
|
+
.panel .files { max-height: none; overflow: visible; }
|
|
198
|
+
/* Переключатели категорий остаются на виду, пока листаешь дерево. Фон — тот же,
|
|
199
|
+
* что у панели (поверхность плюс её подсветка), иначе под ними читались бы
|
|
200
|
+
* проезжающие строки списка. */
|
|
201
|
+
.panel .cats {
|
|
202
|
+
position: sticky;
|
|
203
|
+
top: 0;
|
|
204
|
+
z-index: 2;
|
|
205
|
+
background-color: Canvas;
|
|
206
|
+
background-image: linear-gradient(var(--tint), var(--tint));
|
|
178
207
|
}
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
#
|
|
182
|
-
/* В столбце дерево прокручивается выше, чем над таблицей: место занимает
|
|
183
|
-
* боковая колонка, а числа не отодвигает. */
|
|
184
|
-
.panel .files { max-height: min(62vh, 620px); }
|
|
208
|
+
/* Без метрик таблицы нет, и растянутая пустая строка ей не место: свободное
|
|
209
|
+
* место этой строки забирает сообщение о пустоте, а не полоса над ним. */
|
|
210
|
+
body:has(#shell[hidden]) #state { grid-area: 3 / 2 / 4 / 3; }
|
|
185
211
|
}
|
|
186
212
|
|
|
187
213
|
/* Адаптации: единственное место, где страница правит общую геометрию, — потому что
|
|
188
|
-
* общая часть заморожена байтами артефакта, а не потому что так удобнее.
|
|
189
|
-
|
|
214
|
+
* общая часть заморожена байтами артефакта, а не потому что так удобнее. Порог —
|
|
215
|
+
* 899px, а не 900: при ровно 900px обе половины применились бы к одной странице, и
|
|
216
|
+
* от «узкой» в «широкой» остался бы потолок высоты таблицы — то есть пустое место
|
|
217
|
+
* под ней на одном единственном размере окна. */
|
|
218
|
+
@media (max-width: 899px) {
|
|
190
219
|
body { padding: 14px 14px 32px; }
|
|
191
220
|
h1 { font-size: 18px; }
|
|
192
221
|
#grid { font-size: 12px; }
|
package/src/page/app.js
CHANGED
|
@@ -25,14 +25,39 @@ function appTable() {
|
|
|
25
25
|
appWrite();
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
/*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
28
|
+
/* Прокрутка панели — свойство панели, а не разметки, поэтому она переживает
|
|
29
|
+
* пересборку: иначе каждый клик по галочке возвращал бы список к началу, и до
|
|
30
|
+
* нижних файлов дерева было бы не добраться. Запоминается прокрутка панели и
|
|
31
|
+
* списка файлов — у каждого она своя, а в узком окне прокручивается список.
|
|
32
|
+
* Элементы берутся те, что есть в разметке страницы (`src/page/build.js`):
|
|
33
|
+
* второго перечисления мест прокрутки в пакете нет. */
|
|
34
|
+
const appScrolled = ['#panel', '#panel .files'];
|
|
35
|
+
function appScrollTop() {
|
|
36
|
+
return appScrolled.map((sel) => {
|
|
37
|
+
const el = document.querySelector(sel);
|
|
38
|
+
return el === null ? 0 : el.scrollTop;
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function appScrollBack(saved) {
|
|
43
|
+
appScrolled.forEach((sel, i) => {
|
|
44
|
+
const el = document.querySelector(sel);
|
|
45
|
+
if (el !== null) el.scrollTop = saved[i];
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/* Панель перерисовывается целиком, поэтому поле, стоящее под клавиатурой, и
|
|
50
|
+
* прокрутка после каждой пересборки возвращаются на своё место: иначе
|
|
51
|
+
* переключение с Tab и Space требовало бы начинать обход панели заново, а
|
|
52
|
+
* прокрутка — искать своё место заново. Место поля опознаётся порядковым номером —
|
|
53
|
+
* порядок полей панели от данных не зависит. Фокус ставится без прокрутки (`preventScroll`):
|
|
54
|
+
* он возвращает клавиатуру, а не двигает список. */
|
|
32
55
|
function appRender(keepNotice) {
|
|
33
56
|
const at = Array.from(document.querySelectorAll('#panel input')).indexOf(document.activeElement);
|
|
57
|
+
const saved = appScrollTop();
|
|
34
58
|
appPanel();
|
|
35
|
-
|
|
59
|
+
appScrollBack(saved);
|
|
60
|
+
if (at >= 0) document.querySelectorAll('#panel input')[at].focus({ preventScroll: true });
|
|
36
61
|
appTable();
|
|
37
62
|
/* Сообщение о ссылке переживает отрисовку, которая сама же им и вызвана, и
|
|
38
63
|
* гаснет от действия читателя: он его уже прочитал. */
|
package/src/page/build.js
CHANGED
|
@@ -72,13 +72,6 @@ function uiText(page, loc) {
|
|
|
72
72
|
approximate: page.approximate,
|
|
73
73
|
approxCell: page.approximateCell,
|
|
74
74
|
methodLabel: page.panelMethod,
|
|
75
|
-
legend: [
|
|
76
|
-
{ cls: 'up', text: page.legendUp },
|
|
77
|
-
{ cls: 'down', text: page.legendDown },
|
|
78
|
-
{ cls: 'approx', text: page.legendApprox },
|
|
79
|
-
{ cls: 'same', text: page.legendSame },
|
|
80
|
-
{ cls: 'miss', text: page.legendMiss }
|
|
81
|
-
],
|
|
82
75
|
empty: page.emptyMetrics,
|
|
83
76
|
noFiles: page.noFiles,
|
|
84
77
|
/* {command} подставляет страница: у неё есть данные, а {now} — уже здесь. */
|
package/src/page/panel.js
CHANGED
|
@@ -1,19 +1,6 @@
|
|
|
1
1
|
import { appEl, appBox } from './dom.js';
|
|
2
2
|
import { appData, appUi, appView, appFileAt } from './state.js';
|
|
3
3
|
|
|
4
|
-
/* Легенда: образцы — теми же классами, что и числа в клетках (`up`/`down` из
|
|
5
|
-
* общей части оформления), поэтому образец не может разойтись с цветом числа. */
|
|
6
|
-
function appLegend() {
|
|
7
|
-
const list = appEl('ul', 'legend');
|
|
8
|
-
appUi.legend.forEach((item) => {
|
|
9
|
-
const li = appEl('li');
|
|
10
|
-
li.appendChild(appEl('span', 'swatch ' + item.cls));
|
|
11
|
-
li.appendChild(appEl('span', null, item.text));
|
|
12
|
-
list.appendChild(li);
|
|
13
|
-
});
|
|
14
|
-
return list;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
4
|
/* Галочку файла ставит только файл: и категория, и папка в дереве — способы
|
|
18
5
|
* переставить те же галочки сразу группой, а своего состояния у них нет. Иначе
|
|
19
6
|
* одно и то же решение жило бы в двух местах и расходилось. */
|
|
@@ -106,7 +93,9 @@ export function appPanel() {
|
|
|
106
93
|
|
|
107
94
|
const files = appEl('fieldset', 'files');
|
|
108
95
|
files.appendChild(appEl('legend', null, appUi.files));
|
|
109
|
-
|
|
96
|
+
/* Строка категорий помечена классом: список файлов листается, и она остаётся на
|
|
97
|
+
* виду (липкость — в широкой раскладке, там панель и прокручивается). */
|
|
98
|
+
const cats = appEl('div', 'row cats');
|
|
110
99
|
appData.categories.forEach((cat) => {
|
|
111
100
|
const idx = [];
|
|
112
101
|
appData.files.forEach((f, i) => { if (f.category === cat.key) idx.push(i); });
|
|
@@ -119,6 +108,4 @@ export function appPanel() {
|
|
|
119
108
|
files.appendChild(cats);
|
|
120
109
|
files.appendChild(appTree());
|
|
121
110
|
panel.appendChild(files);
|
|
122
|
-
|
|
123
|
-
panel.appendChild(appLegend());
|
|
124
111
|
}
|
package/templates/README.md
CHANGED
|
@@ -56,7 +56,7 @@ README и журнал колонкой не отслеживаются, — т
|
|
|
56
56
|
именно этот объект выводит `size --init`, когда журнал в проекте есть.
|
|
57
57
|
- `paths` внутри колонки — псевдонимы одного файла: если файл переименовывали,
|
|
58
58
|
перечислите и старое имя, и новое, и колонка не разорвётся.
|
|
59
|
-
- `output: "docs/size-report.html"` — файл отчёта (он один: самодостаточная страница со всеми числами, фильтрами и ссылкой); каталог инструмент создаст
|
|
59
|
+
- `output: "docs/size-report.html"` — файл отчёта (он один: самодостаточная страница со всеми числами, фильтрами и ссылкой); каталог инструмент создаст сам. Хук обновления ставится сам — скриптом установки (npm, yarn) или первым запуском (pnpm 10 не исполняет скрипты зависимостей, если не разрешить `pnpm.onlyBuiltDependencies`), и после каждого коммита отчёт пересобирается. Первый отчёт остаётся неотслеживаемым, пока вы не добавите его в git; дальше он обновляется коммитами сам.
|
|
60
60
|
|
|
61
61
|
## Проверка в CI
|
|
62
62
|
|