简体   繁体   中英

How to import index.vue files without specifying the file name using vue 3 and vite?

I started working recently on a Vue 3 application which runs with vite and I am trying to restructure the directories so that I can group components and related sub-components in folders.

I am currently using /path/to/MyComponent/index.vue to import the higher-hierarchy component, and I would like to write the import statement without specifying the file name, so that I could do something like this:

import MyComponent from `@/path/to/MyComponent`

where the files structure looks like the following:

path
│   
└───to
    │   
    └───MyComponent
        │   index.vue
        │   SubComponent.vue
        │   ...

I tried to play with the resolve.alias property in the vite.config.ts file, but I wasn't successful. Anyone managed to achieve this?

This is one of the attempts:

export default defineConfig({
...
resolve: {
    alias: [
        {
            find: "@",
            replacement: fileURLToPath(new URL("./src", import.meta.url)),
        },
        {
            find: /(^(?!.*[.](ts|js|tsx|jsx|vue|)$))/,
            replacement: "$1/index.vue",
        },
    ],
},
...

After trying various things I found a solution in line with my original post involvin modifying the vite.config.ts file resolve.alias property.

In addition I had to modify the tsconfig.json file to make sure that typescript compiler is also able to resolve the path to the index.vue file.

This is how I achieved importing a index.vue component only referencing the parent folder name:

1. Vite configuration

// vite.config.ts

export default defineConfig({
    resolve: {
        alias: [
            {
                find: /@\/components\/((?!.*[.](ts|js|tsx|jsx|vue)$).*$)/,
                replacement: fileURLToPath(
                    new URL("./src/components/$1/index.vue", import.meta.url)
                ),
            },
            {
                find: "@",
                replacement: fileURLToPath(new URL("./src", import.meta.url)),
            },
            // ...

The above configuration code will tell vite to check if the import statement contains with @/components and does NOT end with any of the following extensions: ts|js|tsx|jsx|vue . Eg @/components/MyComponent .

When these criteria are met the find path will be replaced with the path to the index.vue file within the src/components folder. Eg @/components/MyComponent/index.vue .

The only limitations of the above solution is that it targets a specific folder (in this case the components folder). However we can add more alias objects to match any other folder where we want to implement this import pattern.

2. Typescript configuration

If using typescript ESLint will throws two errors: Missing file extension and Unable to resolve path to module . This because the typescript compiler is agnostic of the above vite configuration.

For this reason I also had to modify the tsconfig.json file as following:

{
    "compilerOptions": {
        "baseUrl": ".",
        "paths": {
            "@/components/*": ["./src/components/*", "./src/components/*/index.vue"],
            "@/*": ["./src/*"]
        }
    }

The above code will leverage Typescript module resolution path mapping to map everything that matches @/components/* to ./src/components/* , where * represents the path within the ./src/components . This path is relative to where the tsconfig.json file reside (as defined by the baseUrl parameter).

If a component is not found, Typescript compiler will look inside ./src/components/*/index.vue .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM