Перейти к содержимому

Сборка пакета .portalpart

Сборка пакета .portalpart

WebPart пишутся на C# и упаковываются в ZIP-архив .portalpart (manifest + DLL + CSS + опционально JS).

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

Окно терминала
cd packages/webpart-examples/hello-widget
./build.sh
# → dist/hello-widget.portalpart

Скрипт использует Docker-образ mcr.microsoft.com/dotnet/sdk:10.0 для dotnet publish.

Шаблон нового WebPart

Окно терминала
cd backend
dotnet new install ./templates/portal-webpart
dotnet new portal-webpart -n my-widget -o ../packages/my-widget

Создайте manifest.json (см. manifest.md), стили в dist/main.css, при необходимости клиентский код в dist/main.js, затем соберите ZIP по аналогии с build.sh в примере.

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

my-widget.portalpart (ZIP)
├── manifest.json
└── dist/
├── MyWidget.dll
├── main.css
└── main.js ← опционально, см. PortalWebPartClients в manifest.md

Установка: Админка → WebPart → загрузить файл.

Обновление WebPart после изменений в коде

Изменения в исходниках (*.cs, dist/main.css, dist/main.js) не попадают в портал автоматически. Работающий экземпляр берёт DLL, CSS и JS из установленного пакета в хранилище (S3), а не из каталога packages/.

Цикл обновления

  1. Внесите изменения в C#-код и/или dist/main.css, dist/main.js.
  2. Увеличьте версию в manifest.json (semver, например 1.0.11.0.2). Это важно для сброса кэша CSS/JS (см. ниже).
  3. Соберите пакет:
    Окно терминала
    cd packages/webpart-examples/my-widget
    ./build.sh
    # или локально: dotnet publish … && zip (см. build.sh в примере)
  4. Переустановите .portalpart:
    • Админка → WebPart — загрузите ZIP с тем же id (старый пакет будет заменён);
    • или POST /api/v1/webparts/packages (multipart, поле package, права администратора).
  5. Обновите страницу в браузере с очисткой кэша (Cmd+Shift+R / Ctrl+Shift+R) или откройте страницу в новой вкладке.

Повторная загрузка с тем же id в manifest.json удаляет предыдущий пакет, выгружает старую DLL из памяти API и регистрирует новую версию. Настройки WebPart на страницах (Property Pane) сохраняются — меняется только код и ассеты.

Что обновляется при переустановке

КомпонентГде хранитсяПоведение при переустановке
C# / HTML (SSR)dist/*.dll в S3Новая DLL подхватывается при следующем render/action
CSSdist/main.v{version}.css в S3Новый путь + ?v=… в URL definition
JSdist/main.v{version}.js в S3То же; bind вызывается заново после render

Кэш CSS/JS (автоматически)

При сборке build.sh вызывает scripts/stage-versioned-assets.py:

  1. Переименовывает dist/main.cssdist/main.v{version}.css (и JS аналогично).
  2. Обновляет styles / scripts в manifest.json внутри ZIP.

При установке пакета backend дополнительно добавляет ?v={version} к URL в definition:

/api/v1/webparts/assets/demo.my-widget/dist/main.v1.0.2.css?v=1.0.2

Фронтенд (webPartLoader.js) кэширует ассеты по (manifestKey, pathname, version) и снимает старые <style> / <script> при смене версии. Ответ API для URL с ?v=Cache-Control: public, max-age=31536000, immutable.

В исходниках указывайте обычные имена (dist/main.css); версионирование имён — только на этапе сборки ZIP.

Кэш и типичные проблемы

«Изменил код, на странице старый вид»

  • Пакет не переустановлен — выполните шаги 3–4 выше.
  • Браузер закэшировал CSS — жёсткое обновление страницы.
  • Версия в manifest.json не изменилась — URL ассетов остаётся прежним; увеличьте version.

«Работает HTML, но не стили / не JS»

  • Проверьте, что styles / scripts указаны в manifest.json и файлы попали в ZIP (unzip -l *.portalpart).
  • CSS/JS должны быть в пакете, не в frontend/public/.

«После обновления JS не срабатывает»

  • Ключ в PortalWebPartClients[…] должен совпадать с id в манифесте.
  • bind вызывается после замены innerHTML — не вешайте обработчики только при первой загрузке страницы.

Локальная разработка без Docker

Если build.sh недоступен (нет Docker):

Окно терминала
cd packages/webpart-examples/my-widget
dotnet publish MyWidget.csproj -c Release -o dist/stage/dist/publish
mkdir -p dist/stage/dist
cp dist/stage/dist/publish/MyWidget.dll dist/stage/dist/MyWidget.dll
cp manifest.json dist/stage/manifest.json
cp dist/main.css dist/stage/dist/main.css
# main.js — при наличии
python3 ../scripts/stage-versioned-assets.py dist/stage
cd dist/stage && zip -r ../my-widget.portalpart manifest.json dist/

См. также backend/templates/README.md.