slothis · English

How to Fix "Cannot find module '#q-app/wrappers'" in Vue + Quasar

2025-03-20 · Original (Korean)

This article was translated from the original Korean post with AI assistance. Prices in parentheses are approximate conversions. Read the original Korean post →
Arghhhhhh


You might run into an error like this, or the one below it.
Error [ERR_PACKAGE_PATH_NOT_EXPORTED]: No "exports" 
Or
 ERROR(vue-tsc)  Cannot find module '#q-app/wrappers' or its corresponding type declarations.

My current environment:
  • vue 3.4.18
  • quasar 2.16.0
  • quasar/app-vite 2.1.4
I'm not sure exactly when Quasar changed how this works, but the usage in my current version is different from the old way. You'll definitely run into this issue if you're using the CLI with Vite. reference

import { defineConfig } from "@quasar/app-vite";

If that was the old way, now...
import { defineConfig } from '#q-app/wrappers'

You have to import it like this. This is when it throws an error saying it can't import #q-app. If you ask ChatGPT or Cursor.ai, they'll tell you to delete your node_modules and run npm install again, try running quasar clean --qconf, or just go back to the old import method. Since this is a recent change, it seems the AI models haven't learned it yet.

The root cause is actually a bug. A patch was released, but it feels more like a temporary workaround than a perfect fix.

If baseUrl is defined in your tsconfig.json, it clashes with the tsconfig.json that Quasar generates and uses internally (the one Quasar uses is /.quasar/tsconfig.json, defined in the extends key).
Related GitHub issue

How to fix it

Delete the baseUrl and path entries from your tsconfig.json.

Here is the recommended tsconfig.json file:
{
  "extends": "./.quasar/tsconfig.json",
  "compilerOptions": {
    "esModuleInterop": true,
    "skipLibCheck": true,
    "target": "esnext",
    "allowJs": true,
    "resolveJsonModule": true,
    "moduleDetection": "force",
    "isolatedModules": true,
    "module": "preserve",
    "noEmit": true,
    "lib": [
      "esnext",
      "dom",
      "dom.iterable"
    ]
  },
Note that vite.config.js has a similar setting, but you can ignore it since that's just an alias path for Vite to reference. Only tsconfig causes the conflict.