Общая библиотека компонентов и composables

↑ 6.2 Сборка и инфраструктура: Vite, monorepo, CI∕CD · ← Предыдущая · → Следующая

Желательно~3 мин чтенияУровень: middle

Зачем это на собесе

Как вынести общий UI и логику для нескольких приложений и не создать зависимость-монстра.

Объяснение

Состав библиотеки:

СлойЧтоПример
Токеныцвета, отступы, типографика@acme/tokens (CSS-переменные, SCSS)
UI-kitбазовые компонентыBaseButton, BaseInput, DataTable (на Quasar/Headless UI)
Composablesобщая логикаuseDebounce, usePagination, useAuth
Утилиты и типыформатирование, валидаторы@acme/utils, @acme/types
API-клиентсгенерированный из OpenAPI@acme/api-client
КонфигиESLint, TS, Vite@acme/config

Сборка библиотеки (Vite library mode):

// vite.config.ts
export default defineConfig({
  plugins: [vue(), dts({ tsconfigPath: "./tsconfig.build.json" })],
  build: {
    lib: { entry: "src/index.ts", formats: ["es"], fileName: "index", cssFileName: "style" },
    rollupOptions: { external: ["vue", "quasar", "vue-router", "pinia"], output: { preserveModules: true, globals: { vue: "Vue" } } },   // зависимости — внешние
  },
});
// package.json
{ "name": "@acme/ui", "version": "1.4.0", "type": "module",
  "exports": { ".": { "types": "./dist/index.d.ts", "import": "./dist/index.js" }, "./style.css": "./dist/style.css" },
  "peerDependencies": { "vue": "^3.4.0", "quasar": "^2.16.0" }, "sideEffects": ["**/*.css"], "files": ["dist"] }

Публикация: приватный реестр (GitLab/GitHub Packages, Verdaccio, Artifactory), Changesets/semantic-release (версии и changelog по Conventional Commits).

Практики:

  • Vue/Quasar — peerDependencies, а не dependencies (иначе две копии).
  • API компонентов стабильный и документированный (Storybook, см. Storybook и документация дизайн-системы), версионирование по semver, deprecation-цикл.
  • Tree-shakeable экспорты (preserveModules, sideEffects).
  • Тесты компонентов и визуальные регрессии.
  • Типы: .d.ts через vite-plugin-dts, vue-tsc.
  • Разработка в monorepo (workspace:*) или через локальную связь (pnpm link).
  • Не переносите в библиотеку то, что используется одним приложением.

Нюансы и подводные камни

  • Дубликаты Vue/Pinia из-за неверных зависимостей → «inject() can only be used inside setup».
  • Ломающие изменения без major-версии сломают все приложения.
  • Глобальные стили библиотеки конфликтуют с приложением — изолируйте (префиксы, @layer).
  • Слишком большая универсальность усложняет компоненты («API из 40 props»).
  • Обновление всех потребителей: coordinated-релизы, codemods.

Практика

  1. Вынесите BaseInput, BaseButton и токены в пакет, соберите в library mode.
  2. Настройте peerDependencies и проверьте отсутствие дубликатов Vue.
  3. Автоматизируйте релизы через Changesets.

Вопросы с ответами

Связанные темы