Skip to content

Migration to Vue 3 #13

Open
Open
@ShGKme

Description

@ShGKme

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
Mail 🔴 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:

  1. Always mark removed API as deprecated in the previous version.
  2. When API is changed, provide a compatible

Then migrating to a new version is:

  1. Stop using any deprecated API
  2. Migrate
  3. Bump version in dependencies
  4. 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:

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 the currentInstance
  • Vue_2 checks getCurrentInstance 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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions