이번에 프로젝트를 세팅하는 중 파일들이 많아질 것을 예상하여 모듈 import를 상대경로가 아닌 @
alias를 이용한 절대경로로 import하기로 했다.
먼저 두 가지 방법이 있는데 tsconfig.json
설정은 동일하다.
- vite.config.ts에서 path resolve alias를 설정해주면 된다
- path resolver plugin인
vite-tsconfig-paths
를 사용하면 된다.
tsconfig.json에 절대경로를 설정하기 위해서 baseUrl
을 통해서 절대 경로 위치를 잡아준 후 paths property
에 하위 폴더 위치를 잡아주면 된다.
먼저 프로젝트에서 설정한 폴더 구조이다.
절대 경로의 root directory는 src
로 잡아 @ alias
로 표시해주고 하위 디렉토리 위치들은 paths
property 내부에 선언해준다.
<tsconfig.json>
"compilerOptions": {
/* ... */
/* absolute paths */
"baseUrl": "./src",
"paths": {
"@/*": ["/*"],
"@/components/*": ["components/*"],
"@/libs/*": ["libs/*"],
"@/db/*": ["db/*"],
"@/types/*": ["types/*"],
"@/assets/*": ["assets/*"],
"@/constants/*": ["constants/*"],
"@/mocks/*": ["mocks/*"]
}
}
vite-tsconfig-paths없이 적용하는 것은 간단하다. tsconfig.json에서 절대경로 설정을 통해 가독성이 편한 파일 경로를 import하게 제공(위의 tsconfig.json에서 baseUrl & paths alias)했다면 vite에게 파일의 위치를 path resolve alias를 통해 알려주어야 한다.
import * as path from 'path';
export default defineConfig({
plugins: [react()],
resolve: {
alias: [
{ find: '@/', replacement: path.resolve(__dirname, 'src') },
{
find: '@/components',
replacement: path.resolve(__dirname, 'src/components'),
},
{ find: '@/libs', replacement: path.resolve(__dirname, 'src/libs') },
{ find: '@/db', replacement: path.resolve(__dirname, 'src/db') },
{ find: '@/types', replacement: path.resolve(__dirname, 'src/types') },
{ find: '@/assets', replacement: path.resolve(__dirname, 'src/assets') },
{
find: '@/constants',
replacement: path.resolve(__dirname, 'src/constants'),
},
{ find: '@/mocks', replacement: path.resolve(__dirname, 'src/mocks') },
],
},
});
vite-tsconfig-paths plugin을 이용하면 vite.config.ts파일에 그저 plugin을 추가해주기만 하면 된다.
export default defineConfig({
plugins: [react(), tsconfigPaths()]
});
처음에 적용하기 위해서 블로그를 참조했었는데 plugin을 사용하는데도 vite.config.ts에도 path resolve alias를 다시 설정해주는 사람들을 여럿 봐서 그럼 plugin이 필요없지 않나?? 생각을 했다.
그러다가 plugin은 path resolver이므로 결국 해주는 것은 tsconfig.json파일을 읽어서 vite가 파일 경로를 알아먹을 수 있게 설정해주는 것이 아닌가?? 생각하다가 한 번 만들어 보기로 했다.
import * as path from 'path';
import * as fs from 'fs';
try{
const tsconfigPath = path.resolve(__dirname, './tsconfig.json');
const tsconfigContent = JSON.parse(fs.readFileSync(tsconfigPath, 'utf-8'))
console.log('tsconfigContent', tsconfigContent);
} catch (error) {
console.error(`Couldn't resolve the path by vite!`);
}
// https://vitejs.dev/config/
export default defineConfig({
plugins: [react()],
});
하지만, json file을 객체형태로 parsing하는 과정에서 아래와 같은 오류가 났다.
< ⚠️ 에러 >
⚠️ 이는 원래 json file은 주석을 허용하지 않지만, tsconfig 파일은 json 파일이지만 주석을 허용한다.
따라서 주석으로 인한 오류이므로 주석을 제거
해주는 과정이 필요하다.
str.replace(/\/\*[\s\S]*?\*\/|(?<=[^:])\/\/.*|^\/\/.*/g, '')
try {
const tsconfigPath = path.resolve(__dirname, './tsconfig.json');
const tsconfigContent = fs.readFileSync(tsconfigPath, 'utf-8');
// ! 주석 제거
const removedCommentsTSConfig = JSON.parse(
tsconfigContent.replace(/\/\*[\s\S]*?\*\/|(?<=[^:])\/\/.*|^\/\/.*/g, ''),
);
console.log('removedCommentsTSConfig', removedCommentsTSConfig);
} catch (error) {
console.error(`Couldn't resolve the path by vite!`);
}
// https://vitejs.dev/config/
export default defineConfig({
plugins: [react()],
});
오류 없이 object로 잘 parsing이 된다. 이제 해줘야 할 것은 vite-tsconfig-paths plugin 없이 적용
에서 했던 것처럼 vite에서 파일 경로를 알려줘야 한다.
import * as path from 'path';
import * as fs from 'fs';
import { defineConfig, AliasOptions, Alias } from 'vite';
import react from '@vitejs/plugin-react';
let alias: AliasOptions = [];
try {
const tsconfigPath = path.resolve(__dirname, './tsconfig.json');
const tsconfigContent = fs.readFileSync(tsconfigPath, 'utf-8');
// ! 주석 제거
const removedCommentsTSConfig = JSON.parse(
tsconfigContent.replace(/\/\*[\s\S]*?\*\/|(?<=[^:])\/\/.*|^\/\/.*/g, ''),
);
const { baseUrl, paths: tsPaths } = removedCommentsTSConfig.compilerOptions;
alias = Object.entries(tsPaths).map(
([absolutePath, resolvedPath]) =>
({
find: absolutePath.replace(/\/\*$/, ''), // ! 끝에 /* 제거
replacement: path.resolve(
__dirname,
`${baseUrl}/${resolvedPath[0].replace(/\/\*$/, '')}`, // ! 끝에 /* 제거
),
}) as Alias,
);
} catch (error) {
console.error(`Couldn't resolve the path by vite!`);
}
// https://vitejs.dev/config/
export default defineConfig({
plugins: [react()],
resolve: {
alias // 👉🏻 vite에게 path resolve된 alias할당
}
});
내가 원하는 형태로 path가 resolve됐는지 console.log(alias)로 확인해보자.
설정을 잘 한 것 같은데 절댕경로 import linting이 안 될 때가 있다. 이는 vscode를 뒤지다가 아래 설정을 바꿔주어 해결할 수 있었다.
shortest가 default값으로 되어 있는데 설명에 따라 non-relative
로 바꿔주면 해결할 수 있다.
사실상 처음에 plugin을 사용해도 vite 설정 파일을 수정해주어야 하는 줄 알았는데 팀원이 @components
가 아닌 @/components
로 쓰면 어떻냐는 의견에 코드를 수정하는 도중 궁금증이 들어 잘못된 지식을 바로 잡을 수 있었다. 덕분에 갑자기 간단하게 vite-tsconfig-paths plugin을 구현을 해 보았다. 내가 만든 코드를 넣어보고 싶었지만 어떤 잠재적인 오류가 발생할 지 몰라 path resolver plugin(vite-tsconfig-paths)를 사용하기로 했다.
remove comments with javascript
vite-tsconfig-paths plugin
vite typescript absolut path setting