Quasar plugins don't work when inside npm packages
What happened?
I am creating a app extension where the quasar notify method will be implemented as a utility file for all projects to utilise. I received the following error when I was using Vite.

I have also attempted to register the plugin via this but it isnt working as well.
conf.framework.plugins.push('Notify')
What did you expect to happen?
No error should be expected which I faced while using webpack
Reproduction URL
No link given as it is an app extension
How to reproduce?
It happens when running the quasar application with vite.
Flavour
Quasar CLI with Vite (@quasar/cli | @quasar/app-vite)
Areas
App Extension API
Platforms/Browsers
Firefox
Quasar info output
Global packages
NPM - 8.5.5
yarn - 1.22.18
@quasar/cli - 1.3.2
@quasar/icongenie - Not installed
cordova - Not installed
Important local packages
quasar - 2.7.6 -- Build high-performance VueJS user interfaces (SPA, PWA, SSR, Mobile and Desktop) in record time
@quasar/app-vite - 1.0.6 -- Quasar Framework App CLI with Vite
@quasar/extras - 1.15.1 -- Quasar Framework fonts, icons and animations
eslint-plugin-quasar - Not installed
vue - 3.2.37 -- The progressive JavaScript framework for building modern web UI.
vue-router - 4.1.3
pinia - 2.0.17 -- Intuitive, type safe and flexible Store for Vue
vuex - Not installed
vite - 2.9.14 -- Native-ESM powered web dev build tool
eslint - 8.21.0 -- An AST-based pattern checker for JavaScript.
electron - Not installed
electron-packager - Not installed
electron-builder - Not installed
register-service-worker - 1.7.2 -- Script for registering service worker, with hooks
@capacitor/core - Not installed
@capacitor/cli - Not installed
@capacitor/android - Not installed
@capacitor/ios - Not installed
Quasar App Extensions
--My component library--
Relevant log output
TypeError: (intermediate value).create is not a function
Additional context
No response
Hi @tanyongkuan! 👋
It looks like you provided an invalid or unsupported reproduction URL. Do not use any service other than Codepen, jsFiddle, StackBlitz, Codesandbox, and GitHub. Make sure the URL you provided is correct and reachable. You can test it by visiting it in a private tab, another device, etc. Please edit your original post above and provide a valid reproduction URL as explained.
Without a proper reproduction, your issue will have to get closed.
Thank you for your collaboration. 👏
I have also attempted to register the plugin via this but it isnt working as well.
conf.framework.plugins.push('Notify')
That's the way to go, but we can't be sure if you did it correctly or if there is something wrong.
Reproduction URL No link given as it is an app extension
I am pretty sure the app-ext code doesn't transfer via telepathy. So, we would need a GitHub repo to investigate the situation.
Here's the repository.
https://github.com/tanyongkuan/notify-project
I was able to reproduce the problem.
Repro steps
-
Run these commands
mkdir notify-app-ext-test cd notify-app-ext-test git clone [email protected]:tanyongkuan/notify-project.git app-ext yarn create quasar # App - Quasar v2 - Vite cd quasar-project yarn add --dev file:../app-ext # Install the app-ext locally -
Change
scriptsection ofquasar-project/src/pages/IndexPage.vueto the following:<script setup> import { sendNotify } from 'quasar-app-extension-not-prj/src/js/utility'; sendNotify('positive', 'test'); </script> -
Start the project:
yarn quasar dev
The problem
Quasar has an auto-loading/tree-shaking mechanism. The most important part of this problem is related to the JS transform part that is applied through the Quasar Vite Plugin. Normally, this:
import { Notify } from 'quasar'
gets turned into this:
import Notify from 'quasar/src/plugins/Notify'
But, that doesn't seem to be the case with app extensions, since they are not really processed as part of the app. So, quasar/src/plugins/Notify inside the app gets processed and installed, but the app-ext uses quasar, which points to the Quasar's usual pre-built bundles. So, Notify gets installed in one of them, but is not accessible in the other. So, we should add some kind of mechanism or configuration to transpile the app-ext, just like possible in app-webpack through the conf.build.transpileDependencies.push(/* ... */). This is also causing duplicates of Quasar in the build, increasing the bundle size.
Workaround
Manually transforming the imports. Instead of importing it the usual way, e.g.:
import { Notify } from 'quasar'
you can do this:
import Notify from 'quasar/src/plugins/Notify'
and similarly with other plugins/utils/components/etc., where needed as well.
Thanks for the explanation!
Just stumbled upon this while porting some "old" code from vuex/webpack into new vite/pinia quasar project. I don't know why this issue is closed when this is a bug(breaking change) that also does not match the documentation any more.
It's still a problem on version 2.11.10
If not imported directly from the fully qualified path, under certain conditions that I don't know well, (I've tried in a fresh installation and everything works fine) it throws that error.
And logging the Notify object shows that there's no create function at all, but there's a install on it's place alogn with setDefaults and registerType.
@FlacorLopes I faced the same problem some days ago. I can't reproduce it right now anymore. Maybe I missed to install the plugin last time:
createApp(App)
.use(Quasar, {
plugins: { Notify }
})
.mount("#app");
Just wanna quickly highlight my solution to this problem:
Add Notify into the plugins section of quasar.config.js did the trick for me
framework: {
config: {},
// ...
// Quasar plugins
plugins: ['Notify'],
},
The issue should have stayed open for further investigation and fixes, so we are re-opening it.
The workaround provided earlier got changed and should be import Notify from 'quasar/src/plugins/notify/Notify' instead. If you are using TS in your library code, then you need to augment it, e.g.
declare module 'quasar/src/plugins/notify/Notify' {
import { Notify } from 'quasar';
export default Notify;
}
It might be helpful to mention that, when inside Vue render scope, $q.notify and similar should work. So, you can also give const $q = useQuasar() way a chance as another workaround.
@yusufkandemir thanks for the help over on Discord.
Looking at the notify code, create is defined within the install method, so seems it needs to be installed. As such, I don't think I can use Notify at all within a plain NPM package any more.
Maybe an app extension has to be used after all?
Any progress with this?
I tried researching myself a bit, but I was unable to find something solid as the origin of this problem I understand Yusuf's workaround, but it seems that it is not always working. Conditions when it does/doesn't are totally random to me at the moment.
Hello! I followed the workaround that @yusufkandemir suggested, by moving my notification helper in a Composable (so that we stay in a Vue render scope). It worked well in my case. Here's my snippet :
// useNotificationService.ts
export function useNotificationService() {
const $q = useQuasar()
const notify = (...) => {
$q.notify({ ... })
}
return { notify }
}
And the usage in some component :
<script setup>
import { useNotificationService } from 'useNotificationService.ts'
// ...
const notificationService = useNotificationService()
notificationService.notify(...)
</script>