bug(NcButton): does not work as `router-link` anymore.
This got completely lost in the refactoring.
NcButtondoes not work as arouter-linkanymore.
Originally posted by @raimund-schluessler in 2c92c40
NcButton is not wrapped in a router-link element anymore when the to prop is set. This breaks quite some places, most prominently the use in NcBreadcrumb. While the app still navigates when to is set, the element does not behave as a router-link should, as it is not an a element anymore.
@susnux Unfortunately, I am not well familiar with script setup yet and I am not sure I can fix this well. If you would have time to look into this, that would be great!
Regression from #6033.
Did you test with npm link or installed?
Did you test with
npm linkor installed?
I did test both, latest main via npm link and installed 9.0.0-rc.2, but it does not make a difference. Both are affected.
@raimund-schluessler Does it happen on production, or on development to you?
I only tested development, I think.
Although, no, now that I think about I tested the last RC and that must've been a production build. But development I tested after, and it also happens there.
I only tested development, I think.
For us it only happend on mixed build: production app build with dev nextcloud/vue or dev build with production lib.
I cannot test it right now, sorry.
I tried again now with RC4 and a production build, and it still happens for me when used in NcBreadcrumb. I didn't test a pure NcButton though. But looking at the code of NcButton, it seems to me it is never rendered as an a if only :to is provided:
https://github.com/nextcloud-libraries/nextcloud-vue/blob/10f74796ed9d7bc916e4d058b8745030fc33dd8d/src/components/NcButton/NcButton.vue#L687
since isLink is only true if one provides an :href. This is a different behaviour than a standard router-link as it was before #6033.
This still does not work for me. In NcButton const hasVueRouterContext = inject(routerKey, null) !== null is always false, although the app uses VueRouter. Is there any adjustment required for this to work?
There are unit tests covering this 👀 How do you register the router?
It is registered here: https://github.com/raimund-schluessler/inventory/blob/17e98514b6783722e755893223f5d9b0e8104077/src/main.js#L25-L40
and the router is created here: https://github.com/raimund-schluessler/inventory/blob/17e98514b6783722e755893223f5d9b0e8104077/src/router.js#L250-L253
There are unit tests covering this 👀 How do you register the router?
Maybe this only works in tests. As the docs say this is Internal and "Allows overriding the router instance returned by useRouter in tests.":
https://router.vuejs.org/api/variables/routerKey.html
Maybe this only works in tests.
No it is basically the full implementation of useRouter:
function useRouter() {
return inject(routerKey);
}
We could use useRouter as a public API, but it has no default value and warns if there is no vue-router
I checked your app and I cannot reproduce this.
Steps I did:
- checkout current main branch of
nextcloud-vue - run
npm build - run
npm pack - checkout current main branch of
inventory - update dependency to the packed one of nextcloud-vue
- run
npm dev - Run app in Nextcloud
@raimund-schluessler in your package.json you have all dependencies in fixed versions. It is not correct in most of the cases. It means, for example, if some lib needs ^1.2.3 version and your app says 1.2.2, then this lib will be installed twice in slightly different versions, even a single version works fine.
I don't see it a problem for this specific issue, but it will cause issues with dependencies.
We could use useRouter as a public API, but it has no default value and warns if there is no vue-router
Well I think it is somewhat public if their developers suggesting me to use that. And also they state it in their docs to work for tests - not sure how likely it is to break as that would break all tests 🤷
But then I would rather use this solution:
const hasVueRouter = typeof resolveComponent('RouterLink') !== 'string
I checked your app and I cannot reproduce this.
Steps I did:
1. checkout current main branch of `nextcloud-vue` 2. run `npm build` 3. run `npm pack` 4. checkout current main branch of `inventory` 5. update dependency to the packed one of nextcloud-vue 6. run `npm dev` 7. Run app in Nextcloud
Thanks for checking, this is weird. I do this and it does not work, neither NcButton nor NcBreadcrumbs are router-links:
- Checkout current
mainof bothnextcloud-vueand the app and install deps withnpm ci. - Build
nextcloud-vuewithnpm run build. - Link it with
npm link. - Link it in the app with
npm link @nextcloud/vue. - Build the app with
npm run build.
@raimund-schluessler in your
package.jsonyou have all dependencies in fixed versions. It is not correct in most of the cases. It means, for example, if some lib needs^1.2.3version and your app says1.2.2, then this lib will be installed twice in slightly different versions, even a single version works fine.
Thanks for the hint. That is a leftover of the time the app was using renovate bot to keep the deps up-to-date. It insisted on this. I will change it.
@raimund-schluessler What nodejs and npm version you check with? Could you provide detailed steps to reproduce or illustrate the issue? Screenshots of the problem, for example. Or an archive with the built files to compare them with our or to check in browsers.
Also @raimund-schluessler please check explicitly with npm pack solution instead of npm link - for me linking rather never works as intended.
npm link should never be used in this scenario. With npm link dependency resolving is not used. Vue, vue-router and other dependencies that are stateful and supposed to be shared are duplicated.
nextcloud-vue
| node_modules
| | vue 🔷
| | vue-router 🔷
| dist
| | main.js
| | import { ... } from 'vue' (resolves as ../node_modules/vue🔷)
| | import { ... } from 'vue-router' (resolves as ../node_modules/vue-router🔷)
app
| node_modules
| | vue ♦️
| | vue-router ♦️
| js
| | main.js
| | import { ... } from 'vue' (resolves as ../node_modules/vue♦️)
| | import { ... } from 'vue-router' (resolves as ../node_modules/vue-router♦️)
| | import { ... } from '@nextcloud/vue' (uses vue🔷 and vue-router🔷)
In Vue it breaks rendering and reactivity. In Vue-Router it makes app and lib using different injection symbol
That could be the explanation why it doesn't work for me then. I will try with npm pack in the evening and report.
Thanks a lot for your help. Indeed, the problem was npm link. With npm pack it works fine.