Skip to content

Быстрый старт

Пошаговое руководство на базе reference-расширения project-notes (packages/extensions/project-notes/).

1. Структура пакета

my-extension/
  extension.manifest.mjs   # id, targets, contributes
  package.json
  vite.config.ts           # ahExtensionFrontendViteConfig
  tsconfig.json
  src/
    backend/index.ts       # опционально
    frontend/index.ts      # опционально
    frontend/components/
    ai/index.ts            # опционально
  dist/                    # build output (gitignored)
  *.zip                    # архив (gitignored)

2. package.json

json
{
  "name": "@artiroute/ext-my-feature",
  "version": "1.0.0",
  "private": true,
  "type": "module",
  "scripts": {
    "build": "extension-build --root .",
    "dev": "extension-build --root . --no-pack"
  },
  "peerDependencies": {
    "@artiroute/extension-sdk": "workspace:*",
    "primevue": "^4.4.1",
    "vue": "^3.5.22",
    "vue-router": "^4.6.0"
  },
  "devDependencies": {
    "@artiroute/extension-build": "workspace:*",
    "@artiroute/extension-sdk": "workspace:*",
    "@vitejs/plugin-vue": "^5.2.4",
    "typescript": "^5.8.3",
    "vite": "^7.1.7",
    "vue": "^3.5.22"
  }
}

Добавьте пакет в packages/extensions/my-extension/ — workspace подхватит его автоматически.

3. Манифест

js
// extension.manifest.mjs
export const extensionManifest = {
  id: '@artiroute/my-feature',
  name: 'My Feature',
  version: '1.0.0',
  extensionApi: '1',
  targets: {
    backend: {},
    frontend: {},
    ai: {},
  },
  contributes: {
    ext: {
      extendsRegistries: [
        { registryId: 'app.sidebar', keys: ['my-feature'] },
        { registryId: 'app.routes', keys: ['my-feature'] },
      ],
    },
  },
};

Каждый key в extendsRegistries должен совпадать с ключом в register() внутри setup(). Подробнее: Манифест.

4. vite.config.ts (frontend)

ts
import { fileURLToPath } from 'node:url';
import { ahExtensionFrontendViteConfig } from '@artiroute/extension-build';
import { extensionManifest } from './extension.manifest.mjs';

const root = fileURLToPath(new URL('.', import.meta.url));

export default ahExtensionFrontendViteConfig({ root, manifest: extensionManifest });

5. Frontend entry

ts
import { defineExtension, getExtensionRegistry } from '@artiroute/extension-sdk/extension';

export default defineExtension(() => {
  getExtensionRegistry('app.sidebar').register('my-feature', {
    label: 'My Feature',
    icon: 'pi pi-star',
    to: '/ext/my-feature',
  });

  getExtensionRegistry('app.routes').register('my-feature', {
    path: '/ext/my-feature',
    name: 'ext:my-feature',
    component: MyPage,
    layout: 'default',
    meta: { title: 'My Feature' },
  });
});

6. Сборка и установка

bash
# из корня monorepo
pnpm build:extensions
pnpm install:extensions

install:extensions распаковывает .zip (или копирует dist/) в apps/backend/data/extensions/<slug>/.

7. Проверка

  1. Перезапустите backend (pnpm backend:dev) — миграции и Feathers поднимутся при bootstrap
  2. Запустите frontend (pnpm frontend:dev) — sidebar и routes подхватятся из реестра
  3. Для AI target — pnpm ai:dev

Расширение должно появиться в UI (sidebar, маршрут и т.д. в зависимости от зарегистрированных реестров).

8. Scaffold из примера

Самый быстрый путь — скопировать packages/extensions/project-notes/ и заменить id, keys и компоненты.

См. также:

AI workspace для командных материалов и знаний