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

[kit] resolveAlias should sort keys by length first #14735

Closed
MorevM opened this issue Aug 28, 2022 · 4 comments · Fixed by nuxt/framework#7018 or nuxt/framework#8453
Closed

[kit] resolveAlias should sort keys by length first #14735

MorevM opened this issue Aug 28, 2022 · 4 comments · Fixed by nuxt/framework#7018 or nuxt/framework#8453

Comments

@MorevM
Copy link
Contributor

MorevM commented Aug 28, 2022

Environment

It doesn't matters, but

  • Operating System: Windows_NT
  • Node Version: v16.15.1
  • Nuxt Version: 3.0.0-rc.8
  • Package Manager: yarn@1.22.18
  • Builder: vite
  • User Config: alias, components, css, srcDir, dir, telemetry, modern, modules, vite, nitro, autoImports, typescript

Reproduction

Describe the bug

Source of resolveAlias function

import { resolveAlias } from '@nuxt/kit';

const aliases = {
  "~": "root/",
  "~components": "root/some/deep/nested/components/"
};

console.log(resolveAlias("~components/something.vue", aliases));

It outputs: root/components/something.vue
Expected output - root/some/deep/nested/components/something.vue

Additional context

I can make a PR after confirming that this isn't done intentionally

Logs

No response

@TheDutchCoder
Copy link
Contributor

TheDutchCoder commented Aug 28, 2022

I believe this is how @rollup/plugin-alias works (which is what Vite uses under the hood).
If you have a "catch-all" alias, like ~, you need to define it last in order to not get conflicts with other aliases that use the same (partial) string.

Example:

const aliases = {
  "#": "./src",
  "#components": "./src/components/"
};
// would resolve '#components/foo.vue' to './src/components/foo.vue, correct

// vs
const aliases = {
  "#": "./src",
  "#components": "./src/deeper/nested/components/"
};
// would resolve '#components/foo.vue' to './src/components/foo.vue, incorrect

// vs
const aliases = {
  "#components": "./src/components/",
  "#": "./src"
};

// would resolve '#components/foo.vue' to './src/components/foo.vue, correct

The example would work in both cases just because the alias is only one level deep, but would cause problems like you're experiencing when having multiple levels.

If memory servers me well, TypeScript does the same thing, it probably just iterates through the keys and matches the first.

Maybe this should just be noted in the docs?

@MorevM
Copy link
Contributor Author

MorevM commented Aug 28, 2022

@TheDutchCoder this is not a Vite issue - it works as expected when using import aliases in components/composables/etc
This is only about @nuxt/kit resolveAlias method which can be used by module authors

Maybe this should just be noted in the docs?

Actually no, because Nuxt internally appends custom aliases to own predefined set.
With that behavior this note should be "You can't use the aliases started with ~ or @ or you need to redefine all Nuxt defaults yourself, otherwise plugins relied on resolveAlias will fail" which is clearly not what we are aiming for (terrible DX)

// nuxt.options.alias
{
  // Nuxt predefined aliases
  "~~": "/<rootDir>",
  "@@": "/<rootDir>",
  "~": "/<rootDir>",
  "@": "/<rootDir>",
  "assets": "/<rootDir>/assets",
  "public": "/<rootDir>/public"

  // Any other aliases passed down via nuxt.config.ts
  '~components': '/views/components/'
  // ... and more
}

@TheDutchCoder
Copy link
Contributor

@MorevM Ah fair enough. Maybe prepending them would solve the issue?

@MorevM
Copy link
Contributor Author

MorevM commented Sep 24, 2022

@danielroe this is still an issue in rc.11

Reproduction link:
https://stackblitz.com/edit/node-8f2trm?file=index.js

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
3 participants