본문 바로가기

Styling tool/SCSS

[scss] vite에서 scss 파일 빌드 시 경로 문제 해결, 경로 자동완성 설정하기

문제 설명

vite + react + typescript 기반 프로젝트에서 scss를 도입하였다.

scss 파일은 vite에서 js 파일에 아래처럼 간단하게 import 하여 사용할 수 있다.

 

import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import './index.css'
import App from "./App.tsx";

createRoot(document.getElementById("root")!).render(
  <StrictMode>
    <App />
  </StrictMode>
);

 

문제는 scss 내에서 import를 할 때 발생했다.

아래처럼 scss 내에서 @import를 하니, 소스 코드 내 디렉토리 경로와 빌드된 파일 내 경로가 꼬였는지 모르겠는데, 파일을 이상한 경로에서 찾으며 에러가 표출되었다.

@import "../../css/token/tokens.css";

 

에러 코드

[plugin:vite:css] [postcss] ENOENT: no such file or directory, 
open 'C:\Users\Desktop\my-project1\css\token\tokens.css'

 

해결 방법

경로 별칭(path alias) 추가

추측컨데, 번들 이전 경로를 번들링할 때 resolve에 문제가 생기는 것 같아서 경로 별칭을 이용한 절대 경로 선언을 만들었다.

 

이는 vite.config.js 를 이용해 만들 수 있다.

import react from "@vitejs/plugin-react";
import { fileURLToPath } from "url";
import { dirname, resolve } from "path";
import { defineConfig } from "vite";

const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);

// https://vite.dev/config/
export default defineConfig({
  plugins: [react()],
  resolve: {
    alias: {
      "@": resolve(__dirname, "src"),
      "@krds": resolve(__dirname, "src/components/krds-uiux"),
    },
  },
});

 

.scss에서 절대 경로를 사용하는 예시

// index.scss

// 안되던 상대 경로 코드
// @import "../../css/token/tokens.css";

// 변경된 코드 : 절대 경로, path alias
@import "@/shared/styles/css/token/tokens.css";

// 혹은 아래처럼 더 간단하게도 가능
// @import "@styles/css/token/tokens.css";

 

typescript 설정 추가

vite에 경로 별칭을 추가한 것과 별개로 타입스크립트의 타입 검사 및 컴파일링을 위해 경로 별칭을 타입스크립트 설정 파일에 추가해야 한다.

{
  "compilerOptions": {
    // alias
    "baseUrl": ".", 
    "paths": {
      "@/*": ["src/*"],
      "@styles/*": ["src/shared/ui/styles/*"]
    }
  },
  "include": ["src"]
}

 

경로 자동 완성 기능: path Intellisense

vite 설정이나 타입스크립트 검사를 위한 경로 별칭 설정과 별개로, import 경로 설정 시 자동완성을 위해서는 vscode에서 추가적인 익스텐션을 많이 사용한다.

대표적으로 Path Intellisense(이하, 인텔리센스)와 Path Autocomplete가 있는데, 여기서는 전자를 설치하여 사용하고 있다.

 

인텔리센스를 설치하면 .js나 .ts파일에서 import 시 자동으로 경로 완성을 할 수 있다.

하지만, scss 나 css에서는 이러한 경로 완성 기능을 지원하지 않으므로 이 부분은 별도의 설정이 필요하다.

 

 

1. 프로젝트의 루트 위치에 /.vscode/settings.json 을 생성한다. 

그리고 아래처럼 작성하여 인텔리센스에서 경로 별칭을 사용하도록 설정한다.

 

// .vscode/settings.json 
{
  "path-intellisense.mappings": {
    "@src": "${workspaceRoot}/src",
    "@krds": "${workspaceRoot}/src/components/krds-uiux"
  },
  "path-intellisense.extensionOnImport": true
}

 

그러나, 여기에는 버그가 있는 것으로 추측된다.

위에서 보다시피, 지금까지 설정한 경로는 @와 @krds 였는데, 위 설정은 그것과 다르다.

만약 @와 @krds로 설정하는 경우, .scss에서 import에 경로 별칭을 사용해보면 @는 자동완성이 되는데, @krds는 자동완성이 되지 않는다.

아마도 @krds는 @에 덮어씌워지는 어떤 판정이 뜨는 것 같다.

그래서 이 경로 별칭은 서로 간에 절대 include 관계, 즉, 한쪽이 어느 한쪽을 포함하는 관계가 되면 안된다. 그렇게 되면 번들링이나 타입 검사에는 문제가 없지만 경로 자동 완성을 쓸 수 없다.

 

따라서, vite와 typescript 설정 파일도 아래처럼 추가해주자

 

vite.config.js

import react from "@vitejs/plugin-react";
import { fileURLToPath } from "url";
import { dirname, resolve } from "path";
import { defineConfig } from "vite";

const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);

// https://vite.dev/config/
export default defineConfig({
  plugins: [react()],
  resolve: {
    alias: {
      "@": resolve(__dirname, "src"),
      "@src": resolve(__dirname, "src"),
      "@krds": resolve(__dirname, "src/components/krds-uiux"),
    },
  },
});

 

ts.config.json

{
  "compilerOptions": {
    // alias
    "baseUrl": ".", 
    "paths": {
      "@/*": ["src/*"],
      "@src/*": ["src/*"],
      "@styles/*": ["src/shared/ui/styles/*"]
    }
  },
  "include": ["src"]
}