feat: add support for #super imports in vite-layers

This commit is contained in:
2026-08-13 02:29:44 +07:00
parent 7d98bb00fd
commit 660989085c
14 changed files with 778 additions and 144 deletions
+27 -2
View File
@@ -77,10 +77,34 @@ c12, вне графа Vite — сам он не следит), подхваты
| Префикс | Куда резолвится | Примечания |
|---|---|---|
| `@/…`, `~/…` | первый совпавший файл по `srcDir` слоёв, high→low | слоёвый резолвер; **self-skip** даёт `super()` |
| `#super`, `#super/…` | первый совпавший файл **строго ниже** слоя импортёра | явный `super()` — предпочтительная форма, см. ниже |
| `~~/…`, `@@/…` | `rootDir` проекта | обычный alias |
| `#layers/<name>/…` | `rootDir` соответствующего слоя | обычный alias, first-wins по имени |
| `#feature` | entry макроса `feature('key')` | алиас регистрируется автоматически; вызовы сворачиваются в литералы |
## `super()`: доступ к затенённому файлу
Оверрайд часто хочет не заменить базовый файл целиком, а обернуть его. Для этого есть `#super`:
```ts
// apps/brand/src/main.ts — бренд без собственного bootstrap: реиспользует entry базы
import '#super' // мой же путь (main.ts), слоем ниже → apps/main/src/main.ts
// apps/brand/src/components/Header.vue — оборачиваем базовый компонент
import BaseHeader from '#super/components/Header.vue'
```
- `#super/<path>` — резолвит `<path>` начиная со слоя **строго ниже** слоя импортёра
(работает из любого файла слоя, не только из одноимённого оверрайда);
- голый `#super` — сахар для «мой собственный путь, слоем ниже».
`#super/*` типизируется в сгенерированном tsconfig (`paths` → слои ниже проектного), так что
go-to-definition ведёт в правильный файл; голая форма покрыта ambient-декларацией
(`.vite-layers/super.d.ts`) — типов не даёт, но и ошибок не создаёт (подходит для side-effect
импортов). Legacy-форма — self-import собственного пути (`import '@/main.ts'` изнутри `main.ts`,
Nuxt-парити) — продолжает работать, но не грепается, меняет смысл при копировании в другой файл и
резолвится TypeScript'ом в самого себя; в новом коде используйте `#super`.
## Модель приоритета (из Nuxt)
`layers[0]` — это сам проект (высший приоритет); далее `extends` слева-направо, в глубину;
@@ -187,8 +211,9 @@ UI рисуется целиком на сервере (json-render спеки `
## Улучшения над Nuxt/c12
1. **`super()` через self-skip** — оверрайд может импортировать собственный путь (`@/components/X`),
чтобы дотянуться до базового файла. В Nuxt такого механизма нет.
1. **`super()`** — явный `#super`/`#super/<path>` (типизированный, greppable) плюс self-skip
(оверрайд может импортировать собственный путь `@/components/X`, чтобы дотянуться до базового
файла). В Nuxt такого механизма нет.
2. **Cycle-guard** — голый c12 уходит в stack overflow на обратном ребре (`A→B→A`); дедуп Nuxt
срабатывает только ПОСЛЕ рекурсивного обхода c12 и не спасает. Терминальный пустой слой в
`resolve`-хуке c12 обрывает рекурсию.