24

I have a vue3 project using Vite/Vitest, as recommanded in Vue.js documentation.

Here is the structure of the project:

src
  components
    // my Vue components here, potentially in sub-folders. For example:
    HelloWorld.vue 
  router
    index.ts
  App.vue
  main.ts
vitest
  components
    // My test specs. For example:
    HelloWorld.spec.ts
// ...
tsconfig.app.json
tsconfig.json
tsconfig.vite-config.json
tsconfig.vitest.json
vite.config.ts

The @/ alias for src folder is resolved properly in components files. However, in my test files, I get an error: cannot find module.

For example, in HelloWorld.spec.ts:

import HelloWorld from '@/components/HelloWorld.vue'; // <-- error !
import { describe, it } from 'vitest';

describe('HelloWorld', () => {
  it('should day hello', () => {
    // ...
  });
});

tsconfig.app.json

{
  "extends": "@vue/tsconfig/tsconfig.web.json",
  "include": [
    "env.d.ts",
    "src/**/*",
    "src/**/*.vue"
  ],
  "exclude": [
    "vitest/**/*"
  ],
  "compilerOptions": {
    "composite": true,
    "baseUrl": ".",
    "paths": {
      "@/*": [
        "./src/*"
      ]
    },
    "strict": true,
    "experimentalDecorators": true
  }
}

vite.config.js

import vue from '@vitejs/plugin-vue';
import { fileURLToPath, URL } from 'url';
import { defineConfig } from 'vite';

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [vue()],
  resolve: {
    alias: {
      '@': fileURLToPath(new URL('./src', import.meta.url)),
    },
  },
  test: {
    include: ['./vitest/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'],
  },
});
Eria
  • 2,653
  • 6
  • 29
  • 56
  • You could first try with a more standarized way to build aliases in **vite.config.js**: `alias: { "@": "./src" }` . If it's not working, or if you want to keep the same config, I suggest you to publish a **reproducible project**. – flydev Jun 02 '22 at 13:10
  • The alias config came as-is with the initialization of the project, using `npm init vue@latest`. But I tried other configs and none is working. – Eria Jun 03 '22 at 08:12
  • Yes - then you should give us a [reproducible project](https://stackoverflow.com/help/minimal-reproducible-example), i suspect a typescript config issue or it could be also possible that you hit a recent issue which require the project to be built at least one time before setting the `test.include`. – flydev Jun 03 '22 at 09:05
  • Do you also use a vitest.config.js file? – Frido Emans Jun 06 '22 at 14:11
  • no, I don't use a specific config file for vitest – Eria Jun 07 '22 at 09:51
  • Any idea why we should exclude test files in `tsconfig.app.json`? Because including this files instead of excluding them solves the problem. – Eria Jun 13 '22 at 20:02
  • The reason is to avoid these files being compiled. You can be more "precise" about what you want to do with these files by using the typescript `configurations` option. – flydev Jun 14 '22 at 12:04
  • why is it a problem if the tests files are compiled? – Eria Jun 15 '22 at 08:19
  • same prob for me also. I tried to configure the `resolve.alias` vite config property but it still not working – Adri HM Jul 04 '22 at 08:23
  • @AdriHM, look at my comment of June 13. It may help. – Eria Jul 05 '22 at 12:34

3 Answers3

39

You just have to specify the aliases in your vitest.config.js file:

import path from 'path'
import vue from '@vitejs/plugin-vue'

export default {
  plugins: [vue()],
  test: {
    globals: true,
    environment: 'jsdom',
  },
  resolve: {
    alias: {
      '@': path.resolve(__dirname, './src')
    },
  },
}
Penny Liu
  • 15,447
  • 5
  • 79
  • 98
Adri HM
  • 2,314
  • 2
  • 17
  • 30
3

For SvelteKit users I ran into similar issue and had to add $lib to vitest.config.js

import { defineConfig } from 'vitest/config';
import { svelte } from '@sveltejs/vite-plugin-svelte';
import path from 'path';

export default defineConfig({
  plugins: [svelte({ hot: !process.env.VITEST })],
  test: {
    globals: true,
    environment: 'jsdom',
  },
  resolve: {
    alias: {
      $lib: path.resolve(__dirname, './src/lib'),
    },
  },
});
Penny Liu
  • 15,447
  • 5
  • 79
  • 98
Ian Samz
  • 1,743
  • 20
  • 20
1

The final solution that worked for me was to include the test files in tsconfig.vitest.json:

tsconfig.app.json (unchanged from question post)

{
  "extends": "@vue/tsconfig/tsconfig.web.json",
  "include": [
    "env.d.ts",
    "src/**/*",
    "src/**/*.vue"
  ],
  "exclude": [
    "vitest/**/*"
  ],
  "compilerOptions": {
    "composite": true,
    "baseUrl": ".",
    "paths": {
      "@/*": [
        "./src/*"
      ]
    },
    "strict": true,
    "experimentalDecorators": true
  }
}

tsconfig.vitest.json

{
  "extends": "./tsconfig.app.json",
  "include": [
    "vitest/**/*",
  ],
  "exclude": [],
  "compilerOptions": {
    "composite": true,
    "lib": [],
    "types": [
      "node",
      "jsdom"
    ],
  }
}
Eria
  • 2,653
  • 6
  • 29
  • 56