Skip to content
This repository was archived by the owner on May 29, 2026. It is now read-only.

feat: add example dashboard widget + splitChunks bundling pattern#26

Merged
rubenvdlinde merged 1 commit into
developmentfrom
perf/widget-bundle-pattern
May 5, 2026
Merged

feat: add example dashboard widget + splitChunks bundling pattern#26
rubenvdlinde merged 1 commit into
developmentfrom
perf/widget-bundle-pattern

Conversation

@rubenvdlinde

Copy link
Copy Markdown
Contributor

Wires the ConductionNL bundling pattern from ADR-004 into the template so every new app cloned from this repo:

  1. Gets a working Nextcloud Dashboard widget out of the box (the ExampleWidget)
  2. Inherits the optimization.splitChunks config that prevents Vue + @nextcloud/vue + pinia from being inlined into every entry-point
  3. Has the appName / appVersion DefinePlugin lines already in place

Triggered by the recent mydash page-load investigation: every Conduction app with dashboard widgets had grown a duplicated-framework problem (228 MB of widget JS attached to /apps/mydash/ across opencatalogi + pipelinq + procest + docudesk + mydash). The fixes landed in those repos; this PR captures the pattern in the template so future apps don't repeat it.

What changed

File Why
webpack.config.js Adds optimization.splitChunks with stable-filename -shared-vendor + -shared-nc-vue chunks; adds exampleWidget entry-point
lib/Dashboard/ExampleWidget.php Minimal IWidget. load() attaches the two shared chunks before the per-widget bundle (order: vendor → nc-vue → widget)
src/exampleWidget.js Webpack entry that registers via OCA.Dashboard.register. Hard-coded id matches Widget::getId()
src/views/widgets/ExampleWidget.vue Minimal NcDashboardWidget with axios fetch + graceful empty state
lib/AppInfo/Application.php $context->registerDashboardWidget(ExampleWidget::class)
README.md "Adding a dashboard widget" how-to + directory-tree update

How an app cloning this template removes the widget

Apps without dashboard widgets delete:

  • lib/Dashboard/ + src/exampleWidget.js + src/views/widgets/
  • the registerDashboardWidget(...) line in Application.php
  • the exampleWidget entry in webpack.config.js

The splitChunks block is harmless with only main + adminSettings entries (produces small shared chunks that two entries reuse) and starts paying off the moment a widget is added.

Test plan

  • npm install && npm run build succeeds
  • js/ contains app-template-shared-vendor.js, app-template-shared-nc-vue.js, app-template-exampleWidget.js
  • App enables in a Nextcloud install
  • Open /apps/dashboard/ (or mydash), confirm "Example widget" appears in the widget picker

Wires the ConductionNL bundling pattern from ADR-004 (Build / bundling)
into the template so apps cloned from this repo get a working dashboard
widget out of the box and never trip the appName/devtool/duplicate-framework
pitfalls that landed across opencatalogi/pipelinq/procest/docudesk.

What is added:

- webpack.config.js: optimization.splitChunks with stable-filename shared
  chunks for Vue + @nextcloud/vue + pinia + icons + @conduction/nextcloud-vue.
  Each entry-point keeps only entry-specific code; shared chunks load once.
- lib/Dashboard/ExampleWidget.php: minimal IWidget. load() attaches shared
  chunks BEFORE the per-widget bundle (vendor → nc-vue → widget). Comments
  explain why and reference ADR-004.
- src/exampleWidget.js: webpack entry that registers the Vue renderer via
  OCA.Dashboard.register. Hard-coded id matches Widget::getId() from PHP.
- src/views/widgets/ExampleWidget.vue: minimal NcDashboardWidget that fetches
  /api/items via @nextcloud/axios with try/catch + graceful empty state.
- AppInfo/Application.php: registerDashboardWidget(ExampleWidget::class).
- README: 'Adding a dashboard widget' how-to listing the 5 registration
  points and pointing at ADR-004 for the full rationale.

Apps that don't need a dashboard widget delete:
  - lib/Dashboard/ + src/exampleWidget.js + src/views/widgets/
  - the registerDashboardWidget(...) line in Application.php
  - the exampleWidget entry in webpack.config.js

The splitChunks block is harmless with only main + adminSettings entries
(produces small shared chunks that two entries reuse) and starts paying off
the moment a widget is added.
@github-actions

github-actions Bot commented May 5, 2026

Copy link
Copy Markdown
Contributor

Quality Report — ConductionNL/nextcloud-app-template @ 1752fc1

Check PHP Vue Security License Tests
lint
phpcs
phpmd
psalm
phpstan
phpmetrics
eslint
stylelint
composer ✅ 100/100
npm ✅ 215/215
PHPUnit
Newman
Playwright ⏭️

Coverage: 0% (0/3 statements)


Quality workflow — 2026-05-05 07:02 UTC

Download the full PDF report from the workflow artifacts.

@rubenvdlinde

Copy link
Copy Markdown
Contributor Author

Validated locally:

exampleWidget (3.42 MiB)
    app-template-shared-nc-vue.js  2.88 MB
    app-template-shared-vendor.js  0.34 MB
    app-template-exampleWidget.js  0.19 MB

Per-widget bundle is 190 KB (just widget code). Shared chunks load once across the page. Same pattern as pipelinq/procest/docudesk and matches ADR-004.

@rubenvdlinde rubenvdlinde merged commit 0d95a46 into development May 5, 2026
25 checks passed
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant