12

I'm trying to replace vue-cli with vite. I have a vite.config.js so I can use alias for imports:

export default {
    alias: {
        '@': require('path').resolve(__dirname, 'src'),
    },
};

Then in my main.ts I try to import my css file (I tried it with or without the .module:

import { createApp } from 'vue';
import App from './App.vue';
import router from './router';

import '@/assets/app.module.css';

createApp(App).use(router).mount('#app');

But I get this error:

[vite] Failed to resolve module import "@/assets/app.module.css". (imported by /src/main.ts)

What am I doing wrong?

Boussadjra Brahim
  • 82,684
  • 19
  • 144
  • 164
Thomas
  • 6,325
  • 4
  • 30
  • 65

4 Answers4

6

As of vite@2.1.5 I could solve resolution of @ and ~ aliases in the following way:

  • add vite-aliases

  • modify vite.config.js as described in the readme.md

  • add an alias for the referenced scss file using the ~ alias as follows:

    aliases.push({ find: '~bootstrap', replacement: 'bootstrap' })
    

now vite.config.js looks as follows:

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { getAliases } from 'vite-aliases'

const aliases = getAliases();

// add aliases to import scss from node_modules here

aliases.push({ find: '~bootstrap', replacement: 'bootstrap' })

// https://vitejs.dev/config/

export default defineConfig({
  plugins: [vue()],
  resolve: {
    alias: aliases
  },
  css: {
    preprocessorOptions: {
      scss: {
        additionalData: '@import "@scss/shared.scss";'
      }
    }
  }
})

this allowed me to import scss files as follows:

in src/main.ts:

import '@scss/main.scss'

in src/scss/main.scss:

@import "~bootstrap/scss/bootstrap";

Obviously, if you need to import more scss files from a subdirectory of node_modules, sou need to add some more aliases to aliases. Leaving out the tilde alias for importing bootstrap.scss worked, but it would not be recognized by my IDE. Adding the css.preprocessorOptions.scss.additionalData causes the shared.scss to be imported in each vue SFC.

Remigius Stalder
  • 1,921
  • 2
  • 26
  • 31
  • 2
    Simply using `resolve: { alias: { '~bootstrap': path.resolve(__dirname, 'node_modules/bootstrap') }}` works, no need for `vite-aliases` plugin. Pointed me in the right direction, though, thanks. Not sure why, but `'~': path.resolve(__dirname, 'node_modules/')` doesn't work, for some reason, so you have to add an entry for every plugin referenced into an scss `@import`. – tao Dec 12 '21 at 00:50
  • thanks a lot the answer and @tao comment saved the day – AlaaL Mar 03 '22 at 06:10
5

Tested

just wanted to add: For anyone still looking at this answer you need to add resolve so it work, as documented in the website. I didn't added the slashes '/@/' This works for me:

example:

resolve: {
    alias: {
      '@': require('path').resolve(__dirname, 'src')
    }
  },

https://vitejs.dev/config/#resolve-alias

Non404
  • 1,130
  • 2
  • 12
  • 22
3

According to those code lines

alias a path to a fs directory
the key must start and end with a slash
'/@foo/': path.resolve(__dirname, 'some-special-dir')

so try out :

 '/@/': require('path').resolve(__dirname, 'src'),
Boussadjra Brahim
  • 82,684
  • 19
  • 144
  • 164
  • Yes this seems to be the case. I can now import the css with @/assets/app.css, but it seems I now need to import my TS and .vue files with /@/components/ or VSCode complains. – Thomas Oct 23 '20 at 22:29
  • do you mean that you have to change every relative path to `@/` absolute one? – Boussadjra Brahim Oct 24 '20 at 06:29
  • 2
    I think this is not a vite issue, but a VSCode one. I need to add a minimal tsconfig.json after all so it is happy again – Thomas Oct 24 '20 at 09:17
3

@Boussadjra Brahim answered the original question, I just want to add some insights for other who have problems with VSCode and the vite setup. Here is my minimalistic tsconfig.json

{
    "compilerOptions": {
        "baseUrl": ".",
        "esModuleInterop": true,
        "moduleResolution": "node",
        "paths": {
            "@/*": [
                "src/*"
            ]
        },
        "target": "esnext"
    },
    "include": [
        "src/**/*.ts",
    ]
}
  • esModuleInterop: I needed it to be able to import seedrandom from 'seedrandom';
  • moduleResolution: was needed for importing from vue
  • path: needed to not have to import everything with /@/ but only @/
  • target: was needed to have gettersand setters in my models (get x, set x)
Thomas
  • 6,325
  • 4
  • 30
  • 65