Description
Vue 3 Migration
Vue 2 EOL is 31 Dec 2023. Vue 3 migration is required.
Nextcloud Libraries overview
Repository | Vue 2 | Vue 3 | Comments |
---|---|---|---|
--- 📚 Frontend libraries --- | |||
🟢 @nextcloud/vue | v8 (stable8) | v9-rc (main) | Everything is ready, RC released, final release soon |
🟢 @nextcloud/dialogs | v6 (stable6) | v7-rc (main) | RC released |
🟡 @nextcloud/upload | v1 (main) | branch:vue3 | Outdated... |
🟢@nextcloud/password-confirmation | v5 (stable5) | v6-rc (main) | RC released |
--- 🛠️ Frontend tools --- | |||
🟢 @nextcloud/eslint-config | v9 (main) | v9 (main) | 👯 Demi support |
🟢 @nextcloud/vite-config | v1 (stable1) | v2 (main) | |
🟢 @nextcloud/webpack-vue-config | v6 (master) | v6 (master) | 👯 Demi support |
🔴 @nextcloud/cypress | v1-beta (main) | - | Required for @nextcloud/upload but deprecated in favor of @nextcloud/e2e-test-server |
--- 🪦 Deprecated libraries --- | |||
🟢 nextcloud-vue-collections | v0.13.0 (stable0) | v1.0.0-alpha (main) | |
🔴 @nextcloud/vue-richtext | v2 (master) | - | |
🔴 @nextcloud/vue-dashboard | v2 (master) | - |
Nextcloud Apps overview
App | Status | Comments |
---|---|---|
Server and apps | 🔴 Not planned yet | Requires bundling change to support Vue 2 and Vue 3 in different apps |
Activity | 🔴 Not planned yet | |
Photos | 🔴 Not planned yet | |
Viewer | 🔴 Not planned yet | |
First run wizard | 🟢 Migrated | Migrated for Nextcloud 32 |
Guests | 🔴 Not planned yet | |
Log Reader | 🔴 Not planned yet | |
--- Groupware --- | ||
Calendar | 🔴 Not planned yet | |
Contacts | 🔴 Not planned yet | |
🔴 Not planned yet | ||
--- Talk --- | ||
Talk | 🟡 WIP | Mostly migrated but abandoned |
Notifications | 🔴 Not planned yet | |
--- Office --- | ||
Deck | 🟡 WIP | |
Notes | 🔴 Not planned yet | |
Text | 🔴 Not planned yet | |
--- Workflowengine --- | ||
Automated file tagging | 🔴 Not planned yet | |
File access control | 🔴 Not planned yet | |
File retention | 🔴 Not planned yet | |
--- Apps --- | ||
Tasks | 🟢 Migrated | |
Forms | 🟡 WIP | |
Polls | 🟡 WIP | |
. | -- TBC -- |
Proposal for libraries
Supporting separated versions for Vue 2 and Vue 3 is complicated in the long run.
- Introduce a Vue 3 compatible version for every supported library
- Make a Vue 3 compatible version the default version (
main
) - Make the first Vue 3 compatible release with minimal (breaking) changes to reduce migration effort and maintenance
cost
Option 1: Forward-compatibility
To make migration simple, we may develop new major versions with forward compatibility from the previous version.
Ideally migrating to a new major version should be as simple as changing the version number in the package.json
.
To archive this, we need to:
- Always mark removed API as deprecated in the previous version.
- When API is changed, provide a compatible
Then migrating to a new version is:
- Stop using any deprecated API
- Migrate
- Bump version in dependencies
- Migrate all the rest (should be minimal)
Option 2: demi-support
In some cases, the difference between Vue 2 and Vue 3 versions are minimal (mostly dependencies).
In theory, it is possible to build/publish both from the same source via:
- Universal dependencies
- Example:
@nextcloud/eslint-config
- Example:
- Bundled dependencies at a cost of bundle size
- Conditional dependencies
Note about apps public API relying on Vue
Some apps (e.g. viewer, workflowengine) have extension API via Vue components. This means that a Vue component from one
app (with one Vue library) is used in a Vue-component tree in another app (with another Vue library).
In general case, it is not supported by Vue. Even with Vue 2 apps it may not work without Module Federations. It will
not work with Vue 2 + Vue 3 mix at all.
Example: nextcloud-libraries/nextcloud-vue#6360
Explanation
Vue is stateful, and its rendering implementation uses Vue internal state.
workflowengine
├─── Vue_1
└─── <Workflow>
└── <ConvertToPdf> - A component from ConvertToPdf app
├─── Vue_2
└─── <NcSelect>
In this case, we have Vue.js framework twice in the document. It would be fine if they are used in different, separated
apps, rendering different nodes.
But in the Workflow app, <ConvertToPdf>
and <NcSelect>
component instances are rendered by Vue_1
module while they
actually include and use Vue_2
.
During the rendering:
Vue_1
creates<NcSelect>
component instance and sets it as thecurrentInstance
Vue_2
checksgetCurrentInstance
and has nothing.Vue_2
doesn't render anything.
In the past it worked at chance, because:
- Not very different Vue versions were used
- e.g. Vue 2.7 workflow plugin may break in Vue 2.6 Workflow app
- Workflow components were simple objects and didn't import anything from Vue
Alternatives:
- Provide API to mount app inside an app
- Web Components
Some for other APIs, like exposing Vue Router instance or store as a public API.
Migration guide for Nextcloud Apps
How to prepare for the migration
TBC
How to migrate
TBC