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

Bad component types since nuxt v3.11.0 #26311

Open
antoinezanardi opened this issue Mar 17, 2024 · 7 comments · Fixed by #26607
Open

Bad component types since nuxt v3.11.0 #26311

antoinezanardi opened this issue Mar 17, 2024 · 7 comments · Fixed by #26607

Comments

@antoinezanardi
Copy link
Contributor

antoinezanardi commented Mar 17, 2024

Environment

  • Operating System: Darwin
  • Node Version: v21.6.2
  • Nuxt Version: 3.11.0
  • CLI Version: 3.10.1
  • Nitro Version: 2.9.4
  • Package Manager: pnpm@8.15.4
  • Builder: -
  • User Config: app, css, devtools, experimental, googleFonts, i18n, image, modules, nitro, pinia, primevue, runtimeConfig, tailwindcss, typescript, vite
  • Runtime Modules: @nuxtjs/tailwindcss@6.11.4, @nuxt/test-utils/module@3.12.0, nuxt-primevue@0.3.1, @nuxtjs/i18n@8.2.0, @nuxt/image@1.4.0, @nuxtjs/google-fonts@3.2.0, @aksharahegde/nuxt-glow@1.1.2, @pinia/nuxt@0.5.1
  • Build Modules: -

Reproduction

You can reproduce the issue with my repo on this PR : antoinezanardi/werewolves-assistant-web-next#260

Describe the bug

When I tried to update to the latest version of nuxt v3.11.0, I have encountered an issue which is, I believe, related to components generated types.

When I try to lint the project (with pnpm run lint:fix), it warns me that some components I'm using in dynamic imports are of type any, even if the application is perfectly building.

Here is an example of the issue in a vue component :

<script lang="ts" setup>
import { storeToRefs } from "pinia";

import GameBuryDeadBodiesPlayground from "~/components/pages/game/GamePlaying/GamePlayground/GamePlaygroundContent/GameBuryDeadBodiesPlayground/GameBuryDeadBodiesPlayground.vue";
import GameChooseCardPlayground from "~/components/pages/game/GamePlaying/GamePlayground/GamePlaygroundContent/GameChooseCardPlayground/GameChooseCardPlayground.vue";
import GameChooseSidePlayground from "~/components/pages/game/GamePlaying/GamePlayground/GamePlaygroundContent/GameChooseSidePlayground/GameChooseSidePlayground.vue";
import GameNoActionPlayground from "~/components/pages/game/GamePlaying/GamePlayground/GamePlaygroundContent/GameNoActionPlayground/GameNoActionPlayground.vue";
import GameRequestAnotherVotePlayground from "~/components/pages/game/GamePlaying/GamePlayground/GamePlaygroundContent/GameRequestAnotherVotePlayground/GameRequestAnotherVotePlayground.vue";
import GameTargetPlayground from "~/components/pages/game/GamePlaying/GamePlayground/GamePlaygroundContent/GameTargetPlayground/GameTargetPlayground.vue";
import GameUsePotionsPlayground from "~/components/pages/game/GamePlaying/GamePlayground/GamePlaygroundContent/GameUsePotionsPlayground/GameUsePotionsPlayground.vue";
import GameVotePlayground from "~/components/pages/game/GamePlaying/GamePlayground/GamePlaygroundContent/GameVotePlayground/GameVotePlayground.vue";
import { useGamePlay } from "~/composables/api/game/game-play/useGamePlay";
import type { GamePlayType } from "~/composables/api/game/types/game-play/game-play.types";
import { useGameStore } from "~/stores/game/useGameStore";

type GamePlaygroundTypeComponent =
  | typeof GameBuryDeadBodiesPlayground // 🚨 Starting from here, the components are of type `any` for `eslint` 
  | typeof GameChooseCardPlayground // 🚨
  | typeof GameChooseSidePlayground // 🚨
  | typeof GameNoActionPlayground // 🚨
  | typeof GameRequestAnotherVotePlayground // 🚨
  | typeof GameTargetPlayground // 🚨
  | typeof GameUsePotionsPlayground // 🚨
  | typeof GameVotePlayground; // 🚨

const gameStore = useGameStore();
const { game } = storeToRefs(gameStore);

const { currentPlayType } = useGamePlay(game);

const gamePlaygroundTypeComponentToRender = computed<GamePlaygroundTypeComponent | undefined>(() => {
  const { currentPlay } = game.value;
  if (currentPlay?.action === "use-potions") {
    return GameUsePotionsPlayground;
  }
  const currentGamePlayTypeComponents: Record<GamePlayType, GamePlaygroundTypeComponent> = {
    "bury-dead-bodies": GameBuryDeadBodiesPlayground,
    "choose-card": GameChooseCardPlayground,
    "choose-side": GameChooseSidePlayground,
    "no-action": GameNoActionPlayground,
    "request-another-vote": GameRequestAnotherVotePlayground,
    "target": GameTargetPlayground,
    "vote": GameVotePlayground,
  };

  return currentPlayType.value ? currentGamePlayTypeComponents[currentPlayType.value] : undefined;
});
</script>

But this issue doesn't show up only in eslint, but even in stryker-js (a mutation tests runner). It can't resolve any of the components with the message below :

tests/unit/specs/components/layouts/default/NavBar.nuxt.spec.ts(5,20): error TS2307: Cannot find module '~/components/layouts/default/NavBar/NavBar.vue' or its corresponding type declarations.
tests/unit/specs/components/layouts/default/ParametersMenu/ParametersMenu.nuxt.spec.ts(11,28): error TS2307: Cannot find module '~/components/layouts/default/NavBar/ParametersMenu/ParametersMenu.vue' or its corresponding type declarations.
tests/unit/specs/components/pages/about/AboutAvailableRoles/AboutAvailableRoles.nuxt.spec.ts(7,43): error TS2307: Cannot find module '~/components/pages/about/AboutAvailableRoles/AboutAvailableRoleDescription/AboutAvailableRoleDescription.vue' or its corresponding type declarations.
tests/unit/specs/components/pages/about/AboutAvailableRoles/AboutAvailableRoles.nuxt.spec.ts(8,33): error TS2307: Cannot find module '~/components/pages/about/AboutAvailableRoles/AboutAvailableRoles.vue' or its corresponding type declarations.
tests/unit/specs/components/pages/about/AboutAvailableRoles/AboutAvailableRoles.nuxt.spec.ts(9,38): error TS2307: Cannot find module '~/components/shared/misc/TextProgressSpinner/TextProgressSpinner.vue' or its corresponding type declarations.

Apart of these tools, the vitest can run all tests without errors and the app is starting fine… All of these were working in v3.10.0 of nuxt.

Is it maybe a problem with the way I'm importing the components in the vue and tests files ? I tried to resolve them from the #components path, same issue. Maybe I need to add something in the tsconfig.json file for correct type resolving ?

Thanks a lot for your help ❤️

Additional context

No response

Logs

No response

Tasks

No tasks being tracked yet.
@danielroe
Copy link
Member

This is likely the change to typescript.shim (which is disabled as volar now has support for better typings in the IDE and in vue-tsc. Try setting it to true.

@antoinezanardi
Copy link
Contributor Author

It works like a charm with typescript.shim: true !

But I have a feeling I'm missing a great feature. Do you think I need to investigate more into the way I'm importing components in stryker and vitest or is it a problem with these tools themselves ?

@antoinerey
Copy link
Contributor

Hey! 👋 We're also facing the same issue on our end, and indeed setting typescript.shim kinda fixes the typechecking false alarm.

There's one situation where we do not have access to the Nuxt configuration to set this typescript.shim though: standalone Nuxt modules with no playground. We rely on the nuxt-module-build prepare command to generate the types, and there is no way to ask this command to generate the shim again. The workaround could be to manually generate the shim file ourselves. Not ideal, but I think we could live with this.

My wondering is more about the change itself, why we changed this property from true to false. The PR states that it's related to VSCode and the fact that the "Takeover mode" and the "TypeScript Vue Plugin" extension are now deprecated.

I get that, but it seems that it not only impacts VSCode but also typechecking through nuxi typechecking, vue-tsc, or tsc. However, not all Vue component imports suffer from this (as 95% of our imports are fine), so it seems there's a specific pattern that's not "supported" anymore. Do you have any idea what could be the issue here? What kind of pattern (or anti-pattern) @antoinezanardi and I are using that triggers such misbehaviour?

@danielroe
Copy link
Member

This is a fair point and I might consider reversing this change for the benefit of third party tooling until we have a better way to get Volar’s plugin into the tsconfig.

@antoinerey
Copy link
Contributor

Here's a PR that reverts to the old (v3.10.x) behaviour. #26607

@antoinerey
Copy link
Contributor

I would argue that the issue is still there, even after merging #26607. I'll copy/paste what I shared there (I believe it's been overlooked before merging the PR).


For what it's worth, our typechecking fails even though we're using the nuxi typecheck command. I've created the following minimal reproduction: stackblitz.com/edit/nuxt-starter-vvj2wc.

It's a mono-repository with one application and two modules. One module exposes a HelloWorld component via its package.json exports property. I'm not exposing the component through the addComponent function as I don't want it to be available through #imports.

Note that both modules are identical. They both rely on @nuxt/module-builder to generate the types and prepare everything. I'm not relying on nuxi prepare playground here as there is no playground.

Still, the typechecking steps fail on the consumer app, but also on the consumer module (module-2). While there is a way to force the shim generation on the application (and thus silence the issue), there is no such mechanism in the modules.

I guess my underlying question is "why does the typechecking fail even though we're using nuxi typecheck and thus vue-tsc under the hood?".

Copy link
Member

@antoinerey That does sound like a different matter if it's reproducible with type-checking only. Let me reopen the linked issue.

@danielroe danielroe reopened this Apr 3, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants