절대 경로 설정하기 without TS

aken·2023년 11월 3일
0

TypeScript를 쓰지 않는 프로젝트라면 어떻게 절대 경로를 설정할까?

구글링을 한 결과 정말 간단했다. 최상위 폴더에 jsconfig.json파일을 추가하여 아래 코드를 넣어주면 된다.

{
    "compilerOptions": {
        "baseUrl": "src"
    },
    "include": [
        "src"
    ]
}

하지만 내가 생각하는 것과 다르게 import 해오는 순간이 있었다.
만약 폴더 구조와 파일 위치가 아래와 같다고 하자.

📦components
 ┣ 📂common
 ┃ ┗ 📜Button.jsx
 ┗ 📜Header.jsx

절대 경로로 설정했다고 생각했지만, Button.jsx에서 선언된 변수를 Header.jsx에서 import할 때 실제로는 상대 경로로 import하고 있었다.

// components/Header.jsx

import Button from './common/Button';

const Header = () => {}

해결

따라서 추가적으로 craco와 react-app-alias를 설치했다.

  • craco: CRA 프로젝트 환경 설정을 확장
    • CRA는 설정을 변경하거나 확장하기 어려우므로 craco를 통해 config 설정을 override하여 환경 설정을 확장한다.
  • react-app-alias: React에서 모듈을 상대경로 대신 별칭으로 참조할 수 있게 해주는 패키지

설치를 완료했으면 pakage.json과 같은 위치에 jsonconfig.json을 생성하여 원하는 절대 경로 형식을 작성한다.

{
  "compilerOptions": {
    "baseUrl": "src",
    "paths": {
      "@assets/*": ["assets/*"],
      "@pages/*": ["pages/*"],
      "@common/*": ["components/common/*"],
      "@components/*": ["components/*"],
      "@hooks/*": ["hooks/*"],
      "@styles/*": ["styles/*"],
      "@store/*": ["store/*"],
      "@constants/*": ["constants/*"],
      "@utils/*": ["utils/*"]
    }
  },
  "include": ["src"]
}

또한 package.json과 같은 위치에 craco.config.js를 생성하여 아래와 같이 작성한다.

const { CracoAliasPlugin } = require('react-app-alias');

module.exports = {
  plugins: [
    {
      plugin: CracoAliasPlugin,
      options: {
        source: 'jsconfig',
        baseUrl: './src',
      },
    },
  ],
};

이제 package.jsonscripts를 수정하면 절대 경로로 설정된다.

"scripts": {
    "start": "craco start",
    "build": "craco build",
    "test": "craco test",
},

storybook은 절대 경로를 인식하지 못한다?!

아래 코드처럼 stories 파일을 만들어서 UI test를 하려고 했으나 storybook이 절대 경로를 인식하지 못했다.

// Button.stories.js

import Button from '@common/Button';

const meta = {
  title: 'Button',
  component: Button,
};
// ...

역시나 storybook도 추가적으로 환경 설정을 해야 했었다. (참고)

.storybook/main.js에서 configwebpackFinal를 설정하면 이제 storybook에서도 절대 경로를 파악할 수 있다.

// .storybook/main.js

const path = require('path');

const config = {
  stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|mjs|ts|tsx)'],
  addons: [
    '@storybook/addon-links',
    '@storybook/addon-essentials',
    '@storybook/preset-create-react-app',
    '@storybook/addon-onboarding',
    '@storybook/addon-interactions',
  ],
  framework: {
    name: '@storybook/react-webpack5',
    options: {},
  },
  docs: {
    autodocs: 'tag',
  },
  staticDirs: ['../public'],
  webpackFinal: async (config) => {
    config.resolve.alias['@'] = path.resolve(__dirname, '../src');
    config.resolve.alias['@components'] = path.resolve(__dirname, '../src/components');
    config.resolve.alias['@common'] = path.resolve(__dirname, '../src/components/common');
    return config;
  },
};
export default config;

0개의 댓글