Files
dev-configs/docs/requirements.md
vigdorov cf64bf6d7d feat: initial dev-configs monorepo
Shared configs for TypeScript projects: ESLint, Prettier, TypeScript,
Vite, Jest, Playwright, Knip. Published as @vigdorov/* npm packages
to Gitea registry.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-16 23:40:22 +03:00

9.7 KiB
Raw Blame History

dev-configs — Требования

Общее описание

Monorepo библиотека с общими конфигами для TypeScript-проектов. Публикуется как набор npm-пакетов в Gitea npm registry.

Архитектура

  • Monorepo: npm workspaces
  • Scope: @vigdorov/
  • Registry: Gitea npm (https://git.vigdorov.ru/api/packages/vigdorov/npm/)
  • Сборка пакетов: tsc → dist/
  • Версионирование: Semver, независимое, ручное (npm version -w)
  • Публикация: Только пакеты с поднятой версией (CI сравнивает с registry)
  • CI: Drone CI, тип library в ci-templates, trigger только на main

Пакеты

@vigdorov/prettier-config

Тип: Статичный объект (без функции-генератора)

{
    "printWidth": 120,
    "tabWidth": 4,
    "useTabs": false,
    "semi": true,
    "singleQuote": true,
    "trailingComma": "all",
    "bracketSpacing": false,
    "jsxSingleQuote": false,
    "arrowParens": "always"
}

@vigdorov/eslint-config

Тип: Функции-генераторы Формат: ESLint 9+ flat config Пресеты: base, react, node

Зависимости:

  • eslint
  • typescript-eslint (v8+)
  • @stylistic/eslint-plugin
  • eslint-plugin-unused-imports
  • eslint-plugin-react (для react)
  • eslint-plugin-react-hooks (для react)

Правила — качество кода (base):

  • eqeqeq: "error"
  • no-console: ["warn", {allow: ["warn", "error"]}]
  • no-alert: "warn"
  • no-param-reassign: ["error", {props: true}]
  • no-useless-concat: "warn"
  • no-else-return: "warn"
  • no-lonely-if: "warn"
  • no-constructor-return: "warn"
  • no-sequences: "warn"
  • prefer-promise-reject-errors: "warn"
  • require-await: "warn"
  • no-new: "warn"
  • no-multi-str: "warn"
  • no-multi-assign: "warn"
  • no-nested-ternary: "warn"
  • no-useless-computed-key: "warn"
  • no-useless-constructor: "warn"
  • no-var: "warn"
  • no-duplicate-imports: "warn"
  • no-plusplus: "warn"
  • no-bitwise: "warn"
  • prefer-const: "warn"
  • prefer-rest-params: "warn"
  • prefer-template: "warn"
  • array-callback-return: ["warn", {allowImplicit: true, checkForEach: true}]
  • default-param-last: "warn"
  • yoda: "warn"

Правила — TypeScript (base):

  • @typescript-eslint/no-explicit-any: "error"
  • @typescript-eslint/no-empty-object-type: "error"
  • @typescript-eslint/no-unsafe-function-type: "error"
  • @typescript-eslint/no-wrapper-object-types: "error"
  • @typescript-eslint/no-use-before-define: "warn"
  • @typescript-eslint/no-shadow: "warn"

Правила — unused imports (base):

  • unused-imports/no-unused-imports: "warn"
  • unused-imports/no-unused-vars: ["warn", {vars: "all", varsIgnorePattern: "^_", args: "after-used", argsIgnorePattern: "^_"}]

Правила — @stylistic (base):

  • @stylistic/no-multiple-empty-lines: ["warn", {max: 1}]
  • @stylistic/lines-between-class-members: ["warn", "always"]
  • @stylistic/line-comment-position: ["warn", {position: "above"}]
  • @stylistic/multiline-comment-style: ["warn", "starred-block"]
  • @stylistic/capitalized-comments: "warn"
  • @stylistic/max-len: ["warn", {code: 120, ignoreComments: true, ignoreUrls: true, ignoreStrings: true, ignoreTemplateLiterals: true, ignoreRegExpLiterals: true}]

Правила — React (пресет react, поверх base):

  • react/prop-types: "off"
  • react/react-in-jsx-scope: "off"
  • react/jsx-filename-extension: ["warn", {extensions: [".tsx"]}]
  • react/jsx-props-no-spreading: "warn"
  • react/jsx-key: "warn"
  • react/no-array-index-key: "warn"
  • react/destructuring-assignment: "warn"
  • react/prefer-stateless-function: "warn"
  • react/jsx-fragments: ["off", "element"]
  • react-hooks/exhaustive-deps: "warn"

Правила — Node (пресет node):

  • Базовые правила из base
  • React-специфичные правила отключены

@vigdorov/typescript-config

Тип: JSON-файлы для extends (без сборки)

base.json:

{
    "compilerOptions": {
        "strict": true,
        "target": "ES2022",
        "module": "ESNext",
        "lib": ["ES2022"],
        "moduleResolution": "bundler",
        "resolveJsonModule": true,
        "forceConsistentCasingInFileNames": true,
        "noImplicitReturns": true,
        "noFallthroughCasesInSwitch": true,
        "noUnusedLocals": false,
        "allowUnreachableCode": false,
        "allowUnusedLabels": false,
        "allowSyntheticDefaultImports": true,
        "removeComments": true,
        "sourceMap": true,
        "incremental": true,
        "skipLibCheck": true,
        "isolatedModules": true
    }
}

react.json:

{
    "extends": "./base.json",
    "compilerOptions": {
        "lib": ["DOM", "DOM.Iterable", "ES2022"],
        "jsx": "react-jsx"
    }
}

@vigdorov/vite-config

Тип: Функции-генераторы Пресеты: spa, library

spa:

import {spa} from '@vigdorov/vite-config';

export default spa({
    port: 5176,
    aliases: {'@': 'src'},
    proxy: {'/api': 'http://localhost:3003'},
});

library:

import {library} from '@vigdorov/vite-config';

export default library({
    entry: 'src/index.ts',
    name: 'my-lib',
    aliases: {'@': 'src'},
    external: ['react', 'react-dom'],
    formats: ['es', 'cjs'],
});

Генератор spa:

  • Подключает @vitejs/plugin-react
  • Преобразует aliases в resolve.alias с абсолютными путями
  • Настраивает server.port и server.proxy
  • Дефолты: base: "/", outDir: "dist"

Генератор library:

  • Настраивает build.lib (entry, name, formats)
  • rollupOptions.external — исключает peer-зависимости
  • fileName: index.mjs / index.cjs
  • Алиасы работают так же как в SPA

@vigdorov/jest-config

Тип: Функция-генератор

import {jestConfig} from '@vigdorov/jest-config';

export default jestConfig({
    environment: 'jsdom',
    aliases: {'@': 'src'},
});

Базовый конфиг:

  • clearMocks: true
  • collectCoverage: true
  • coverageReporters: ['html', 'text', 'text-summary', 'lcov']
  • coverageDirectory: 'coverage'
  • testMatch: ['/tests//.(j|t)s?(x)', '**/?(.)+(spec|test).(j|t)s?(x)']
  • testPathIgnorePatterns: ['/node_modules/', '/dist/']
  • transform: @swc/jest

Параметры:

  • environment: 'node' | 'jsdom'
  • aliases: Record<string, string> — преобразуется в moduleNameMapper

@vigdorov/playwright-config

Тип: Функция-генератор

import {playwrightConfig} from '@vigdorov/playwright-config';

export default playwrightConfig({
    baseURL: 'http://localhost:5176',
    testDir: 'e2e',
    retries: 0,
});

Базовый конфиг:

  • timeout: 30000
  • retries: CI ? (params.retries ?? 2) : (params.retries ?? 0)
  • reporter: CI ? 'html' : 'list'
  • use.trace: 'on-first-retry'
  • use.screenshot: 'only-on-failure'
  • Три браузера: chromium, firefox, webkit

@vigdorov/knip-config

Тип: Функция-генератор

import {knipConfig} from '@vigdorov/knip-config';

export default knipConfig({
    entry: ['src/main.tsx'],
});

Базовый конфиг:

  • entry: params.entry ?? ['src/index.ts']
  • project: params.project ?? ['src/**/*.{ts,tsx,js,jsx}']
  • ignore: ['/.test.', '/.spec.', 'e2e/', '/*.d.ts', ...params.ignore]
  • ignoreDependencies: params.ignoreDependencies ?? []
  • Knip завершается с exit code 1 при ошибках (используется в check-скрипте для блокировки сборки)

CI/CD

Тип library в ci-templates

Отдельный library.drone.yml (не base.drone.yml)

Pipeline: prepare → install → test → build → publish

Скрипт publish-lib.sh:

  • Настраивает .npmrc с GITEA_TOKEN
  • Для каждого пакета в packages/ сравнивает версию с registry
  • Публикует только пакеты с новой версией

Trigger: только main, только push

service.yaml для dev-configs

service:
  name: dev-configs
  type: library

library:
  scope: "@vigdorov"
  registry: "https://git.vigdorov.ru/api/packages/vigdorov/npm/"

Процесс работы с версиями

  1. Разработка в feature-ветке
  2. Merge в main
  3. Поднятие версии: npm version patch -w packages/eslint
  4. Commit + push: git commit -am "release: eslint@1.0.1"
  5. CI публикует только пакеты с новой версией

Потребители

В каждом проекте-потребителе:

.npmrc:

@vigdorov:registry=https://git.vigdorov.ru/api/packages/vigdorov/npm/

.gitignore (добавить):

coverage/

Структура monorepo

dev-configs/
├── packages/
│   ├── eslint/          → @vigdorov/eslint-config
│   ├── prettier/        → @vigdorov/prettier-config
│   ├── typescript/      → @vigdorov/typescript-config
│   ├── vite/            → @vigdorov/vite-config
│   ├── jest/            → @vigdorov/jest-config
│   ├── playwright/      → @vigdorov/playwright-config
│   └── knip/            → @vigdorov/knip-config
├── package.json          (workspace root, private: true)
├── tsconfig.base.json    (общий tsconfig для сборки пакетов)
├── .npmrc
├── service.yaml
├── .drone.yml
├── .gitignore
└── CLAUDE.md