Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migration to Vue 3 #13

Open
ShGKme opened this issue Jan 14, 2025 · 5 comments
Open

Migration to Vue 3 #13

ShGKme opened this issue Jan 14, 2025 · 5 comments

Comments

@ShGKme
Copy link

ShGKme commented Jan 14, 2025

Vue 3 Migration

Vue 2 EOL is 31 Dec 2023. Vue 3 migration is required.

Nextcloud Libraries overview

Library Vue 2 Vue 3 Comments
Frontend libraries
🟢 @nextcloud/vue v8 (master) v9-alpha (next) Everything is ready, but not main yet
🟡 @nextcloud/dialogs v6 (main) branch:vue3 Outdated...
🟡 @nextcloud/upload v1 (main) branch:vue3 Outdated...
🔴 @nextcloud/password-confirmation v5 (main) - Can be used in Vue 3 projects with a small package.json change
Frontend tools and configs
🟢 @nextcloud/eslint-config v8 (main) v8 (main) 👯 Demi support
🟢 @nextcloud/vite-config v1 (stable1) v2
🟡 @nextcloud/webpack-vue-config v6 (master) branch:vue3 Draft for universal version
🔴 @nextcloud/cypress v1-beta (main) - Required for @nextcloud/upload
Deprecated libraries
🟢 nextcloud-vue-collections v0.13.0 (stable0) v1.0.0-alpha (main) 🪦 Deprecated
🔴 @nextcloud/vue-richtext v2 (master) - 🪦 Deprecated
🔴 @nextcloud/vue-dashboard v2 (master) - 🪦 Deprecated

Nextcloud Apps overview

App Status Comments
Tasks 🟢 Migrated
Talk 🟡 WIP Mostly migrated but abandoned
Server 🔴 Not planned yet
. -- TBC --

Proposal for libraries

Supporting to 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

@susnux
Copy link

susnux commented Jan 14, 2025

🚀 Vue 3 🚀

I think this is only a library issue, because as soon as those are available apps can migrate whenever they want.
So it boils down to:

  • nextcloud-vue
  • nextcloud-upload
  • nextcloud-dialogs

The password confirmation should normally not be important as no components are exported, this should be framework agnostic.
This currently can lead to issues because of vue dependency version clash. But if a proper framework agnostic solution is too complex, then we could also provide a bundled version for vue2 apps (vue3 bundled in the library) while vue3 apps can benefit from treeshaking and sharing vue code (we are talking about 150kb for vue2 apps).
➡ So both versions use the same source code.

The same I think is possible for the dialogs library.

I also do not think we need to care too much about keeping changes small, we do not do this when we do other major changes. Especially as there is quite few activity once a new major is release.
I do not mean to make everything breaking but only to directly do it the Vue 3 way if needed, instead of Frankenstein Vue 2 into Vue 3 code (example would be modelValue vs value).


Note about apps public API relying on Vue

💯 I agree! This is rather bigger issue as I think those APIs should all be fully framework agnostic.
It is not only the components shared, but also some expectations like that objects will be reactive, when passed through apps and API.

@ShGKme
Copy link
Author

ShGKme commented Jan 14, 2025

The password confirmation should normally not be important as no components are exported, this should be framework agnostic.
This currently can lead to issues because of vue dependency version clash. But if a proper framework agnostic solution is too complex, then we could also provide a bundled version for vue2 apps (vue3 bundled in the library) while vue3 apps can benefit from treeshaking and sharing vue code (we are talking about 150kb for vue2 apps).
➡ So both versions use the same source code.

That is exactly what is implemented in the linked PR.

Caveats: changing bundle size from 29.64 kB to 833.74 kB

@ShGKme

This comment has been minimized.

@susnux

This comment has been minimized.

@ShGKme
Copy link
Author

ShGKme commented Jan 14, 2025

Ah, or did you mean, that we can do

{
  "dependencies": {
    "@nextcloud/vue": "^8 || ^9",
    "vue": "^2 || ^3"
  }
}

?

Added this to the options.

Nope, this requires building in post-install...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants