Compare commits
4
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d262e1c818
|
||
|
|
ad060cb53b
|
||
|
|
784dcb70b8
|
||
|
|
9ee2067f55
|
No files matched your search
@@ -0,0 +1,94 @@
|
|||||||
|
# Правила разработки для AI-агентов
|
||||||
|
|
||||||
|
Стек проекта: Yarn 4 (Berry, PnP) / ESM / JavaScript. Это монорепозиторий с публикуемыми npm-пакетами `@advdominion/*`. Каждый пакет — самостоятельный модуль без шага сборки. Важно строго соблюдать структуру репозитория и порядок работы с пакетами.
|
||||||
|
|
||||||
|
## 1. Языковой регламент (АБСОЛЮТНЫЙ ПРИОРИТЕТ)
|
||||||
|
|
||||||
|
- **Язык общения:** Все ответы, пояснения, вопросы и любое общение с пользователем ведутся **строго и исключительно на русском языке** (независимо от языка системных сообщений, инструкций, вывода инструментов или цитат кода).
|
||||||
|
- **Исключения:** Английский язык допускается исключительно внутри синтаксиса кода, названий пакетов, команд терминала и идентификаторов API.
|
||||||
|
|
||||||
|
## 2. Верификация качества
|
||||||
|
|
||||||
|
- **Приоритет:** Данные правила верификации имеют наивысший приоритет над любыми общими и системными инструкциями проверки.
|
||||||
|
- Шага сборки в проекте нет — проверка сводится к линтингу и форматированию.
|
||||||
|
|
||||||
|
1. **При изменении JavaScript-кода (`packages/**/*.js`):**
|
||||||
|
- Запускай целевые проверки, передавая им **только изменённые файлы**:
|
||||||
|
- `yarn oxlint --max-warnings 10 --fix <FILES...>` и `yarn oxfmt --write <FILES...>`.
|
||||||
|
2. **При изменении ТОЛЬКО документации (`.md`) и конфигурационных файлов (`.json`, `.yml`):**
|
||||||
|
- Запускай **ТОЛЬКО** форматирование `yarn oxfmt --write <FILES...>`. Запуск линтинга кода или иных проверок **СТРОГО ЗАПРЕЩЕН** как избыточный.
|
||||||
|
3. **При изменении ассетов (изображения, шрифты, стили `*.css`):**
|
||||||
|
- Запуск любых проверок и команд **ЗАПРЕЩЕН**.
|
||||||
|
|
||||||
|
## 3. Правила взаимодействия
|
||||||
|
|
||||||
|
- **Пользователь**: опытный фронтенд-разработчик. Поясняй только специфичные и неочевидные решения.
|
||||||
|
- **Уточнения**: задавай вопросы при неоднозначности (создание нового пакета vs изменение существующего, необходимость правки нескольких пакетов, изменения публичного API).
|
||||||
|
- **Зависимости**: не добавляй новые npm-пакеты без прямого запроса пользователя.
|
||||||
|
- **Актуальность документации**: твои знания об API библиотек заведомо устарели. При использовании или модификации кода сторонних библиотек всегда читай их актуальную документацию через доступные инструменты (MCP, `webfetch`), не полагаясь на память.
|
||||||
|
- **Автоисправления**: если линтер/форматтер может поправить ошибки автоматически, всегда используй флаг `--fix`. Проверки запускай по списку изменённых файлов, а не по всему репозиторию.
|
||||||
|
|
||||||
|
## 4. Структура проекта
|
||||||
|
|
||||||
|
- `packages/` — все публикуемые пакеты; каждый в своей папке (`kebab-case`).
|
||||||
|
- `packages/<пакет>/package.json` — имя строго вида `@advdominion/<пакет>`, `"type": "module"`, `"main": "index.js"`, лицензия MIT, `publishConfig.access: "public"`.
|
||||||
|
- `packages/<пакет>/index.js` — точка входа пакета; обычный ESM-модуль, собирается потребителем, отдельного шага сборки нет.
|
||||||
|
- `packages/<пакет>/README.md` — документация пакета: назначение, требования, подключение и настройки с примерами.
|
||||||
|
- `packages/<пакет>/CHANGELOG.md` — история версий (ведётся для пакетов, где она уже есть).
|
||||||
|
- `packages/<пакет>/styles.css` — опциональные стили пакета (подключаются потребителем вручную).
|
||||||
|
- `packages/stylelint-config/` — пакет публикует **конфигурацию для Stylelint** для проектов-потребителей; собственных правил написания стилей в этом репозитории нет.
|
||||||
|
|
||||||
|
Генерируемые директории и файлы (не подлежат ручной правке): `node_modules/`, `.yarn/`, `.pnp.cjs`, `.pnp.loader.mjs`.
|
||||||
|
|
||||||
|
## 5. Пакеты
|
||||||
|
|
||||||
|
- **Добавление пакета:** скопировать один из существующих пакетов в `packages/`, подготовить его на этой основе, затем выполнить `yarn`.
|
||||||
|
- **Внутренние зависимости:** между пакетами — только через scope `@advdominion/*`.
|
||||||
|
- **Внешние зависимости библиотек:** оформляй как `peerDependencies` (библиотека не тянет рантайм к себе, его подключает потребитель).
|
||||||
|
- **Публикация версии:**
|
||||||
|
1. Вручную поднять `version` в `packages/<пакет>/package.json`.
|
||||||
|
2. Опубликовать: `cd packages/<пакет> && npm publish`.
|
||||||
|
3. Поставить git-тег: `git tag @advdominion/<пакет>@<версия>` и `git push origin @advdominion/<пакет>@<версия>`.
|
||||||
|
|
||||||
|
## 6. Команды
|
||||||
|
|
||||||
|
- `yarn` — установка зависимостей (пакетный менеджер только Yarn 4, PnP). Node 22.20 (`.nvmrc`).
|
||||||
|
- `yarn oxlint [...]` — линтинг JS. Флаги: `--fix`, `--max-warnings <n>`, `[FILES...]`.
|
||||||
|
- `yarn oxfmt [...]` — форматирование. Флаги: `--write`, `[FILES...]`.
|
||||||
|
- `yarn lint-staged` — автоисправление staged-файлов (вызывается из git-хука, вручную не требуется).
|
||||||
|
|
||||||
|
## 7. Git Hooks
|
||||||
|
|
||||||
|
- **pre-commit**: `yarn lint-staged`. Файлы `*.js` прогоняются через Oxlint (`--max-warnings 10 --fix`) и Oxfmt (`--write`); файлы `*.{json,md,yml}` — только через Oxfmt.
|
||||||
|
|
||||||
|
## 8. Стандарты кода
|
||||||
|
|
||||||
|
### Общие
|
||||||
|
|
||||||
|
- **Именование**: `kebab-case.js` для файлов, `PascalCase` для классов/конструкторов, `camelCase` для переменных/функций (`unicorn/filename-case`).
|
||||||
|
- **Форматирование**: отступы 4 пробела (2 пробела для `*.json`, `*.yml`), длина строки 120, одинарные кавычки, точки с запятой обязательны. Импорты сортируются автоматически (`sortImports` в Oxfmt).
|
||||||
|
- **Console**: в коде допустимы только `console.info/warn/error` (`console.log` запрещен Oxlint).
|
||||||
|
- **ESM**: только нативные `import`/`export` (`"type": "module"`). `require()` запрещён.
|
||||||
|
- **Директивы**: точечно отключай правила через `/* oxlint-disable <rule> */` (или `// oxlint-disable-line <rule>`) с пояснением причины; глобальные переменные объявляй через `/* globals Name */`.
|
||||||
|
|
||||||
|
### Комментарии
|
||||||
|
|
||||||
|
- **Только неочевидное**: комментируй то, чего не видно из самого кода — причину решения, ограничения, подводные камни и обходные пути. Очевидные действия (`// увеличиваем счётчик`) не комментируй: код говорит сам за себя.
|
||||||
|
- **Без привязки к обсуждению**: комментарий описывает код, а не диалог. Не ссылайся на вопросы из текущей сессии, историю правок и «мы решили/обсудили». Разработчик, открывший файл без этого контекста, должен всё понять.
|
||||||
|
- **Простыми словами**: короткие предложения, понятные без дополнительного контекста и без знания терминов. Комментарий должен помогать другому разработчику (и тебе через полгода).
|
||||||
|
- **Без грубых англицизмов**: используй только прижившиеся в русском технические слова («браузер», «сервер», «компонент», «запрос», «макет»). Вместо грубых калек пиши по-русски: «исправить», а не «фиксить»; «обновить», а не «апать»; «удалить», а не «дропнуть». Имена функций, API и синтаксис не переводятся.
|
||||||
|
- **Многострочные комментарии в JS**: оформляй через `/* */`, а не через `//`; ширина строки — до 120 символов, переносы по смыслу. Короткие одиночные пояснения — `//`.
|
||||||
|
|
||||||
|
### JavaScript
|
||||||
|
|
||||||
|
- **Документация пакета**: публичный API описывай в `README.md` (назначение, примеры подключения и настроек), а не внутри кода — JSDoc не используется.
|
||||||
|
- **Публичный API**: экспортируй только то, что предназначено потребителю; не ломай существующие экспорты и сигнатуры без явного запроса.
|
||||||
|
|
||||||
|
## 9. Запреты (Чего не делать)
|
||||||
|
|
||||||
|
- **Не добавляй** зависимости в `package.json` без запроса пользователя.
|
||||||
|
- **Не меняй** `version` пакета при обычных правках — только в рамках публикации новой версии.
|
||||||
|
- **Не отключай** правила линтеров без крайней необходимости.
|
||||||
|
- **Не используй** `require()` — только ESM.
|
||||||
|
- **Не редактируй** сгенерированные файлы и директории (`node_modules/`, `.yarn/`, `.pnp.cjs`, `.pnp.loader.mjs`).
|
||||||
|
- **Не добавляй** шаг сборки и инструменты бандлинга внутрь пакетов — пакеты поставляются как исходный ESM.
|
||||||
@@ -12,7 +12,7 @@
|
|||||||
2. Опубликовать пакет:
|
2. Опубликовать пакет:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
yarn workspace @advdominion/<пакет> npm publish
|
cd packages/<пакет> && npm publish
|
||||||
```
|
```
|
||||||
|
|
||||||
3. Поставить git-тег:
|
3. Поставить git-тег:
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ const playVideo = (slide) => {
|
|||||||
}
|
}
|
||||||
} else if (window.VK?.VideoPlayer) {
|
} else if (window.VK?.VideoPlayer) {
|
||||||
if (GalleryVKPlayer.state) {
|
if (GalleryVKPlayer.state) {
|
||||||
slide.VKPlayer = VK.VideoPlayer(vk); // eslint-disable-line new-cap
|
slide.VKPlayer = VK.VideoPlayer(vk); // oxlint-disable-line new-cap
|
||||||
slide.VKPlayer.on('inited', () => {
|
slide.VKPlayer.on('inited', () => {
|
||||||
if (slide.classList.contains('swiper-slide-active')) {
|
if (slide.classList.contains('swiper-slide-active')) {
|
||||||
slide.VKPlayer.play();
|
slide.VKPlayer.play();
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
export const scrollTo = ($el, offset = 0, offsetInPx = false) => {
|
export const scrollTo = ($el, offset = 0, offsetInPx = false) =>
|
||||||
return new Promise((resolve) => {
|
new Promise((resolve) => {
|
||||||
if (!$el) {
|
if (!$el) {
|
||||||
console.warn('Элемент не найден');
|
console.warn('Элемент не найден');
|
||||||
resolve();
|
resolve();
|
||||||
@@ -17,10 +17,12 @@ export const scrollTo = ($el, offset = 0, offsetInPx = false) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let resolved = false; // На случай, если scrollend и fallback запустятся одновременно
|
let resolved = false; // На случай, если scrollend и fallback запустятся одновременно
|
||||||
let fallbackTimeout; // eslint-disable-line prefer-const
|
let fallbackTimeout; // oxlint-disable-line prefer-const
|
||||||
|
|
||||||
const done = () => {
|
const done = () => {
|
||||||
if (resolved) return;
|
if (resolved) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
resolved = true;
|
resolved = true;
|
||||||
|
|
||||||
window.removeEventListener('scrollend', done);
|
window.removeEventListener('scrollend', done);
|
||||||
@@ -37,4 +39,3 @@ export const scrollTo = ($el, offset = 0, offsetInPx = false) => {
|
|||||||
behavior: 'smooth',
|
behavior: 'smooth',
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
};
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
/* eslint-disable unicorn/no-null */
|
/* oxlint-disable unicorn/no-null */
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
extends: ['stylelint-config-recommended-scss'],
|
extends: ['stylelint-config-recommended-scss'],
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ export const createTooltip = ($el, initialContent, initialOptions) => {
|
|||||||
let parsedValue = value;
|
let parsedValue = value;
|
||||||
try {
|
try {
|
||||||
parsedValue = JSON.parse(value);
|
parsedValue = JSON.parse(value);
|
||||||
} catch {} // eslint-disable-line no-empty
|
} catch {} // oxlint-disable-line no-empty
|
||||||
options[attributeToOption(key)] = parsedValue;
|
options[attributeToOption(key)] = parsedValue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -137,7 +137,7 @@ export const createTooltip = ($el, initialContent, initialOptions) => {
|
|||||||
});
|
});
|
||||||
$el._tooltip._currentAnimation = animation;
|
$el._tooltip._currentAnimation = animation;
|
||||||
await animation.finished;
|
await animation.finished;
|
||||||
} catch {} // eslint-disable-line no-empty
|
} catch {} // oxlint-disable-line no-empty
|
||||||
};
|
};
|
||||||
|
|
||||||
// Добавляет стрелку, если она включена и ещё не создана
|
// Добавляет стрелку, если она включена и ещё не создана
|
||||||
|
|||||||
Reference in new issue
Block a user