quasar-ui-qcalendar icon indicating copy to clipboard operation
quasar-ui-qcalendar copied to clipboard

Unable to use QCalendar component extension in Vue3+Vite Quasar CLI app

Open SleepingRobot opened this issue 3 years ago • 6 comments

Describe the bug Unable to use QCalendar component extension in fresh Vue3+Vite Quasar CLI app

To Reproduce Steps to reproduce the behavior:

  1. Generate new v2 App (Vue 3 + JS + Vite) with Quasar CLI
  2. Run quasar ext add @quasar/qcalendar@next
  3. Run quasar dev
  4. Browser console warning:
runtime-core.esm-bundler.js:38 [Vue warn]: A plugin must either be a function or an object with an "install" function.
  1. Add <q-calendar /> or <q-calendar-month /> or <q-calendar-day /> to IndexPage.vue
  2. Additional browser console warning:
runtime-core.esm-bundler.js:38 [Vue warn]: Failed to resolve component: q-calendar-month
If this is a native custom element, make sure to exclude it from component resolution via compilerOptions.isCustomElement. 
  at <IndexPage onVnodeUnmounted=fn<onVnodeUnmounted> ref=Ref< null > > 
  at <RouterView> 
  at <QPageContainer> 
  at <QLayout view="lHh Lpr lFf" > 
  at <MainLayout onVnodeUnmounted=fn<onVnodeUnmounted> ref=Ref< Proxy {…} > > 
  at <RouterView> 
  at <App>

Expected behavior QCalendar component to render and for these console warnings to not be thrown

Desktop:

  • OS: Ubuntu 22.04 LTS
  • Browser: Chrome version 101.0.4951.54 (Official Build) (64-bit)

Additional context quasar v2.6.6 @quasar/app-vite v1.0.0-beta.14

SleepingRobot avatar May 04 '22 17:05 SleepingRobot

It looks like there is a build bug with the QCalendar component. For now, until I can figure out how to fix it, do not use the QCalendar wrapper, unless you import it directly from the src folder. For using other calendar types, create a boot file and import the specific calendar there (including QCalendar). You may need to set the transpile options in your quasar.config.js as well.

For instance:

import Plugin from '@quasar/qcalendar/src/QCalendarDay'
export default ({ app }) {
  app.use(Plugin)
}

hawkeye64 avatar May 08 '22 15:05 hawkeye64

This happens without vite too.

Installing with quasar ext add @quasar/qcalendar@next or Create and register a boot file give me the same warning. And i add the transpile option for the boot file

kevinmelo avatar May 09 '22 20:05 kevinmelo

Any solutions?

vladyslav-mikhieiev avatar Jun 21 '22 13:06 vladyslav-mikhieiev

I do have the same issue. When I use one of the components, i.e. Q-day, it works, but it won't with Q-Calendar...

Failed to resolve component: q-calendar If this is a native custom element, make sure to exclude it from component resolution via compilerOptions.isCustomElement.

lukepower avatar Jun 21 '22 14:06 lukepower

I believe I have found the issue. the register file points to @quasar/quasar-ui-qcalendar/dist/types/index which has no default export or function to register. When I modified it to import VuePlugin from '@quasar/quasar-ui-qcalendar/dist/index.umd' the registration completes, components seem to work as expected without importing them into the vue template and the console warning [Vue warn]: A plugin must either be a function or an object with an "install" function is gone.

Tracing this back to the package.json of quasar-ui-qcalendar, changing the module attribute to "module": "dist/index.umd.js", rather than "module": "dist/index.esm.js", fixes the issue as well. The index.esm.js file also doesn't have a default export nor function to register, so it might have been an oversight referencing the index.cjs.js file as the module file..

Karnith avatar Jul 07 '22 20:07 Karnith

Looking at the index.esm.js I see there is an install function, though it it part of the index variable object which is then brought into the Plugin object as 'default': index. Quasar registry seem to want the install function at the root of the object, so it is unable to find it. If index.esm.js is to be used for the module attribute in package.json, adding 'install': index.install to the Plugin object in this file seems to fix the registration since the registration can find the install function.

Karnith avatar Jul 07 '22 22:07 Karnith

any solution?

amersarosong avatar Oct 24 '22 06:10 amersarosong

The workaround I found was by importing the component/styles individually:

<script setup>
import {
  QCalendar,
  isBetweenDates,
  padNumber,
  parsed,
  today,
} from '@quasar/quasar-ui-qcalendar/src/index.js'
import '@quasar/quasar-ui-qcalendar/src/QCalendarVariables.sass'
import '@quasar/quasar-ui-qcalendar/src/QCalendarTransitions.sass'
import '@quasar/quasar-ui-qcalendar/src/QCalendar.sass'
const form = ref({
  selectedDate: '',
})
</script>

<template>
  <div>
    <QCalendar view="week" />
  </div>
</template>

edshen17 avatar Dec 04 '22 22:12 edshen17

@Karnith you got something right, but that's not really what's happening here

QCalendar app-extension imports the plugin here

https://github.com/quasarframework/quasar-ui-qcalendar/blob/3f489729013d11a88e89f41e9bf31f0c430c110f/app-extension/src/boot/register.js#L2

That VuePlugin is a default export defined here

https://github.com/quasarframework/quasar-ui-qcalendar/blob/ec946b4b61455e28ee325379ccb01a36d3e3a833/ui/build/entry/index.esm.js#L4

Which in turns in obtained by a star import here

https://github.com/quasarframework/quasar-ui-qcalendar/blob/ec946b4b61455e28ee325379ccb01a36d3e3a833/ui/build/entry/index.esm.js#L1

The ESM entry file is then processed with rollup at build time

https://github.com/quasarframework/quasar-ui-qcalendar/blob/ec946b4b61455e28ee325379ccb01a36d3e3a833/ui/build/script.javascript.js#L89-L98

If we then compare to the generated ESM entry file (dist/index.esm.js), rollup encapsulates a default export within a default export (the default: index @Karnith noticed), hiding install function into the inner default export. The fact that other calendars ESM entries avoid the star import notation and work just fine when registered manually, while the only broken ones are QCalendar and the ESM index file, both of which point to the same file and use the star import notation, I'm pretty sure that's the problem

QCalendarDay https://github.com/quasarframework/quasar-ui-qcalendar/blob/ec946b4b61455e28ee325379ccb01a36d3e3a833/ui/build/entry/QCalendarDay.esm.js#L1

index https://github.com/quasarframework/quasar-ui-qcalendar/blob/ec946b4b61455e28ee325379ccb01a36d3e3a833/ui/build/entry/index.esm.js#L1


Considering that there's a

https://github.com/quasarframework/quasar-ui-qcalendar/blob/ec946b4b61455e28ee325379ccb01a36d3e3a833/ui/build/entry/index.esm.js#L3

right after the star import, I'd guess the star import was simply a mistake. Removing it and rebuilding shows that the default export isn't nested anymore and install function is now correctly added. I tested it locally on my project and it seems to work

@hawkeye64 let me know if I got everything right, this should be a simple fix

IlCallo avatar Feb 08 '23 15:02 IlCallo

In the meantime, I used pnpm patch @quasar/quasar-ui-qcalendar@next to generated a patched version adding install:index.install after default:index in dist/QCalendar.esm.js, dist/QCalendar.esm.min.js, dist/index.esm.js, dist/index.esm.min.js and it's working fine

I think yarn have a similar feature too

IlCallo avatar Feb 08 '23 15:02 IlCallo

Fixed into latest release (alpha-16)

IlCallo avatar Feb 08 '23 18:02 IlCallo