refactor client eject, refactor client apis - boostcampwm-2022/web33-Mildo GitHub Wiki

โœ‚๏ธ ๋ถ„๋ฐฐ๋œ ์ด์Šˆ

  • eject ๋˜๋Œ๋ฆฌ๊ธฐ
  • apis ๊ฐœ์„  (axios ํƒ€์ž…, ์ธ์Šคํ„ด์Šค)
  • ๋กœ๋”ฉ jotai suspense

๐Ÿšฉ ๊ตฌํ˜„ ๋ชฉํ‘œ

  • eject ๋˜๋Œ๋ฆฌ๊ธฐ
  • ๋กœ๋”ฉ jotai suspense๋กœ ๋ณ€๊ฒฝ
  • apis ๋ชจ๋“ˆ ๊ฐœ์„ 

๐Ÿ€ ์„ธ๋ถ€ ๋ชฉํ‘œ

  • eject ๋˜๋Œ๋ฆฌ๊ธฐ
  • jotai suspense ํ•™์Šต ๋ฐ ๋กœ๋”ฉ ๊ตฌํ˜„
  • apis ๋ชจ๋“ˆ ๊ฐœ์„ 
    • axios interceptor ์ ์šฉ
    • axios response ํƒ€์ž… ์ ์šฉ

๐Ÿ–ฅ๏ธ ๊ตฌํ˜„ ๋‚ด์šฉ

Axios interceptor ์ ์šฉ

  • ํ˜„์žฌ ์ฝ”๋“œ

    // apis.ts
    import axios from 'axios';
    
    const request = async (
      path: string,
      method: 'get' | 'post' | 'delete',
      data?: Record<string, unknown> | undefined
    ) => {
      const apiServerURL =
        process.env.REACT_APP_CLIENT_ENV === 'development'
          ? process.env.REACT_APP_API_SERVER_URL_DEVELOPMENT
          : process.env.REACT_APP_API_SERVER_URL_PRODUCTION;
    
      try {
        const response = await axios({
          url: `${apiServerURL}${path}`,
          method,
          withCredentials: true,
          data
        });
    
        ...
      } catch (error) {
        console.warn(error);
      }
    
      return { ok: false };
    };
    
    export default {
      getAllArea: () => {
        return request('/seoul', 'get');
      },
      ...
      addBookmark: (areaName: string, userId: string) => {
        return request(`/auth/${userId}/bookmark/${areaName}`, 'post');
      },
      deleteBookmark: (areaName: string, userId: string) => {
        return request(`/auth/${userId}/bookmark/${areaName}`, 'delete');
      }
    };
    
    • ๋ฐ”๋‹๋ผ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—์„œ ์ผ๋˜ fetch ๋ชจ๋“ˆ์„ ์กฐ๊ธˆ ๋ณ€๊ฒฝํ•ด์„œ ๊ทธ๋Œ€๋กœ ์ ์šฉํ–ˆ๋‹ค.
  • ๋ณ€๊ฒฝ ์ฝ”๋“œ

    const apiServerURL =
      process.env.REACT_APP_CLIENT_ENV === 'development'
        ? process.env.REACT_APP_API_SERVER_URL_DEVELOPMENT
        : process.env.REACT_APP_API_SERVER_URL_PRODUCTION;
    
    const axiosInstance = axios.create({
      baseURL: `${apiServerURL}`,
      withCredentials: true
    });
    
    const request = async (
      path: string,
      method: 'get' | 'post' | 'delete',
      data?: Record<string, unknown> | undefined
    ) => {
      axiosInstance.interceptors.request.use(
        config => {
          config.method = method;
          if (data) {
            config.data = data;
          }
    
          return config;
        },
        error => {
          console.log(error);
          return Promise.reject(error);
        }
      );
    
      try {
        const response = await axiosInstance(path);
    
        return response.data;
      } catch (error) {
        console.warn(error);
      }
    
      axiosInstance.interceptors.response.use(
        response => {
          return response.data;
        },
        error => {
          console.log(error);
        }
      );
    
      return { ok: false };
    };
    

๐Ÿ“– ํ•™์Šต ๋‚ด์šฉ

eject ๋˜๋Œ๋ฆฌ๊ธฐ

eject ์™œ ํ–ˆ๋Š”๊ฐ€?

  • CRA์™€ ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ๊ฐ€ ์–ด๋–ป๊ฒŒ ๋™์ž‘ํ•˜๋Š”์ง€ ๊ถ๊ธˆํ•ด์„œ ๋œฏ์–ด๋ดค๋‹ค.

    ๊ด€๋ จ ๋งํฌ

    • ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ ์ปดํŒŒ์ผ ๊ฒฐ๊ณผ๋ฌผ์ด ์–ด๋””์— ์ƒ์„ฑ๋˜๋Š”๊ฐ€?
    • ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ ์ปดํŒŒ์ผ๊ณผ ๋ฒˆ๋“ค๋ง ์ˆœ์„œ๋Š” ์–ด๋–ป๊ฒŒ ๋˜๋Š”๊ฐ€?
    • bundle.js ๋Š” ์–ด๋””์— ์žˆ๋Š”๊ฐ€?

์™œ ๋˜๋Œ๋ฆฌ๋Š”๊ฐ€?

  • ๊ถ๊ธˆํ•œ ์ ์ด ์–ด๋А์ •๋„ ํ•ด์†Œ๋˜์—ˆ๊ณ  ๋”์ด์ƒ eject๋œ ํŒŒ์ผ๋“ค์„ ๊ฑด๋“œ๋ฆด ํ•„์š”๊ฐ€ ์—†๊ธฐ ๋•Œ๋ฌธ์— ๋˜๋Œ๋ฆฌ๋ ค ํ•œ๋‹ค.
  • eject๋ฅผ ์“ฐ๋ฉด ์•ˆ ๋˜๋Š” ์ด์œ ์— ๋Œ€ํ•ด ํ•™์Šต
    1. Webpack, Babel ๋“ฑ CRA์˜ ๋ชจ๋“  ์„ค์ •์„ ์ง์ ‘ ์œ ์ง€๋ณด์ˆ˜ ํ•ด์•ผ ํ•œ๋‹ค.
    2. CRA์˜ ์žฅ์ ์ธ One Build Dependency๋ฅผ ์žƒ๊ฒŒ ๋œ๋‹ค. ํŒจํ‚ค์ง€๋ฅผ ์„ค์น˜ํ•  ๋•Œ ๋‹ค๋ฅธ ํŒจํ‚ค์ง€๋“ค๊ณผ์˜ ์˜์กด์„ฑ์„ ์‹ ๊ฒฝ์จ์•ผ ํ•œ๋‹ค.

๋˜๋Œ๋ฆฌ๋Š” ๋ฐฉ๋ฒ•

  • ์—†๋‹ค. ๋Œ€์‹  ์ผ์ผ์ด ์‚ญ์ œ/์„ค์น˜๋ฅผ ํ†ตํ•ด ๋ณต๊ตฌ
  1. srcipts , config , node_modules ๋””๋ ‰ํ† ๋ฆฌ ์‚ญ์ œ
  2. react-scripts ๋ชจ๋“ˆ ์„ค์น˜
  3. package.json ์—์„œ scripts ์†์„ฑ ์ˆ˜์ •
    • ์ˆ˜์ • ์ „ ์ฝ”๋“œ

      "scripts": {
        "start": "cross-env REACT_APP_CLIENT_ENV=development node scripts/start.js",
        "build": "cross-env REACT_APP_CLIENT_ENV=production node scripts/build.js",
        "test": "node scripts/test.js"
      },
      
    • ์ˆ˜์ • ํ›„ ์ฝ”๋“œ

      "scripts": {
        "start": "cross-env REACT_APP_CLIENT_ENV=development react-scripts start",
        "build": "cross-env REACT_APP_CLIENT_ENV=production react-scripts build",
        "test": "react-scripts test",
        "eject": "react-scripts eject"
      },
      

์ฐธ๊ณ  ์‚ฌ์ดํŠธ

Axios interceptor

axios

๐Ÿšง Trouble Shooting

jotai suspense ์—๋Ÿฌ

๐ŸŽธ ๊ธฐํƒ€