IT/Project

[팀 프로젝트 기록] webpack, web-dev-server, cors, proxy 삽질기

프티 2022. 2. 9. 03:31
반응형

클라이언트와 서버 간의 포트가 다르면 클라이언트에서 api 요청을 할 때 cors 정책에 위반이 된다.

이를 해결할 수 있는 방법으로 프록시 서버를 구축하여 서버와 서버 간의 통신을 하도록 해서 우회하는 것을 선택하였다.

 

이때 사용한 것이 웹팩 데브 서버이다.

이를 위해 웹팩과 웹팩 데브 서버에 대해서 알아보았고 내용을 정리해보았다.

 

웹팩으로 해결하려는 문제

  1. 자바스크립트 유효 범위
    es6 modules 문법과 웹팩의 모듈 번들링으로 해결
    - es6 modules 문법
    import, from, export, default와 같이 모듈 관리 전용 키워드를 사용하므로 가독성이 좋다.
    비동기 방식으로 작동하고 모듈에서 실제로 쓰이는 부분만 불러오기 때문에 성능과 메모리 부분에서 유리하다.
  2. 브라우저 별 http 요청 숫자의 제약
    tcp 스펙에 따라 한 번에 서버로 보낼 수 있는 http 요청 숫자는 제약되어 있다.
    따라서 http 요청 숫자를 줄이는 것이 웹앱의 성능을 높여줄 뿐만 아니라 사용자가 사이트를 조작하는 시간을 앞당길 수 있다.
    웹팩을 이용해 파일을 하나로 합치면 http 요청 숫자 제약을 피할 수 있다.
  3. 사용하지 않는 코드의 관리
  4. Dynamic Loading & Lazy Loading 미지원
    웹팩의 code splitting 기능을 이용하여 원하는 모듈을 원하는 타이밍에 로딩할 수 있다.
    - code splitting?
    하나의 큰 번들을 여러 개의 작은 번들들로 쪼개준다.
    이를 이용하면 필요할 때 필요한 번들만 로드 함으로써 초기 로딩 시간을 줄여주고, 유저가 현재 필요하지 않은 코드는 로드하지 않음으로써
    앱의 성능을 크게 향상할 수 있다.
const path = require("path");

module.exports = {

  mode: "development",

  entry: {

    index: "./src/index.js",

    another: "./src/another-module.js"

  },

  output: {

    filename: "[name].bundle.js",

    path: path.resolve(__dirname, "dist")

  }

};

하나의 번들이 아닌 index.bundle.js와 another.bundle.js로 쪼개는 방식이다.

위의 webpack.config.js 설정은 cra로 만든 리액트가 아닐 때 접근할 수 있는 방식이다.

 

웹팩 데브 서버

 

  • 디스크에 저장되지 않는 메모리 컴파일을 사용하기 때문에 컴파일 속도가 빨라짐
  • Webpack.config.js에도 devServer 옵션을 통해 옵션을 지정하여 사용이 가능
    - webpack.config.js
    entry(의존성 트리의 루트 파일 설정), output(번들링 된 파일의 경로와 이름 설정), module(js 외의 여러 파일들을 번들링 할 수 있게 하는 설정)으로 옵션을 세팅하여 번들할 수 있도록 하는 파일

 

Webpack-dev-server의 동작 원리

  1. 서버 실행 시 소스 파일들을 번들링 하여 메모리에 저장 소스 파일을 감시
  2. 소스 파일이 변경되면 변경된 모듈만 새로 번들링
  3. 변경된 모듈 정보를 브라우저에 전송
  4. 브라우저는 변경을 인지하고 새로고침 되어 변경사항이 반영된 페이지를 로드

 

웹팩 데브 서버는 개발 시 메모리 컴파일에 의해 빠른 리로딩을 가능하게 하여 편리하다는 장점이 있다.

또한 프록시 설정을 하면 api를 가지고 있는 백엔드 서버와 api 요청을 하는 클라이언트 사이의 cors에 막히지 않고
서버 간 통신으로 api를 응답받을 수 있게 한다.

 

따라서 필요한 포트는 클라이언트, 웹팩 데브 서버, 백엔드 서버 3개이다

우리는 각각의 포트를 3000, 5000, 7000으로 합의하였다.

=> 이 부분에서 오해를 했다. 웹팩 데브 서버와 클라이언트의 포트가 다르다고 생각했는데,

웹팩 자체가 리액트에 내장되므로, 웹팩 데브 서버의 포트와 리액트로 생성한 클라이언트 포트는 같은 것이었다.

따라서 포트는 3가지가 될 수 없다.

 

webpack.config.js의 devServer라는 객체로 옵션을 설정하는데,

Before 함수를 사용하면 목업 api 설정이 가능하다.

 

카테고리 json 파일을 받아올 때 클라이언트 public에 json을 넣을 수도 있겠지만 before 함수에서 바로바로 불러오는 방법도 있는 것 같다.

하지만 불러오고 state 저장되기 때문에 가장 좋은 방법은 아니라고 생각이 든다.

=> 여기서 몰랐던 점이 있었다. 아래에서 설명하겠다.

 

이렇게 알아본 정보를 토대로 webpack.config.js에 devServer를 설정해주어야겠다고 생각했다.

하지만 우리 프로젝트에서는 cra 보일러 플레이트로 리액트를 생성했기 때문에 수정을 위해서는 두 가지 방법이 있었다.

 

방법

첫 번째, npm run eject로 프로젝트에 숨겨져 있는 모든 설정들을 밖으로 빼내어 수정하는 방법

두 번째, customize-cra로 webpack.config.js의 설정에 override 하는 방법

 

첫 번째 방법

cra는 내부적으로 사용하는 모든 npm 모듈을 캡슐화하므로 package.json을 깔끔하게 관리할 수 있다.

하지만 복잡한 작업을 하면서 모듈과 상호작용을 해야 하는 경우 npm run eject로 모든 설정들을 빼낼 수 있다.

하지만 주의해야 한다. 이 작업은 단방향이기 때문에 돌이킬 수 없기 때문이다.

또한 모듈 간의 의존성을 생각하며 작업해야 하기 때문에 나 같은 초보자는 쉽사리 npm run eject를 할 수 없었다..

따라서 두 번째 방법을 선택하였다.

 

두 번째 방법

npm run eject를 대신하는 또 하나의 방법으로 customize-cra npm 패키지를 사용하는 방법이다.

이는 webpack.config.js를 override 하여 내가 설정한 속성들로 덮어씌울 수 있다.

root 경로에 config-overrides.js를 생성하고 설정 값을 작성한다.

const { overrideDevServer } = require("customize-cra");

function devServerConfig() {
  return (config) => {
    return {
      ...config,
      historyApiFallback: true,
      hot: true,
      proxy: {
        "/api": {
          target: "http://localhost:7000",
          changeOrigin: true,
          pathRewrite: {
            "^/api": "/",
          },
        },
      },
      onBeforeSetupMiddleware: (devServer) => {
        devServer.app.get("/api/key", (req, res) => {
          res.json([{ key: "aaa" }]);
        });
      },
    };
  };
}

module.exports = {
  devServer: overrideDevServer(devServerConfig()),
};

devServer의 target에 백엔드 서버 주소를 설정하였고 아래에 onBeforeSetupMiddleware 값을 설정해주었다.

onBeforeSetupMiddleware는 클라이언트가 요청한 것을 웹팩 데브 서버가 백엔드 서버와 통신하지 않고 자체적으로 응답하도록 하는 설정이다.

 

결론

이렇게 설정을 마치고 클라이언트와 서버 간의 통신을 무사히 할 수 있었.,..으나

 

웹팩 데브 서버는 개발 환경을 위한 세팅이지 배포를 위한 세팅이 아니었다.

위에서 공부했듯 오로지 개발의 효율을 높여준다는 장점만 나열했는데,

당연히 개발과 배포 모두를 위한 환경을 만들었다고 생각했던 것이었다.

 

따라서 onbefore.. 미들웨어를 사용한다고 해도 목업을 위한 설정일 뿐 실제 배포 환경에서는 사용할 수 없는 기능이다.

즉 로딩 속도를 높여준다는 것을 개발 한정인 것.

 

하루 동안 삽질을 한 것이다..

 

하지만 웹팩과 웹팩 데브 서버를 세팅하면서 개발을 할 때에는 참 좋다는 것을 알았다^^..

결국 백엔드 서버에 cors 미들웨어를 등록함으로써 간단히 cors 정책을 우회할 수 있었고,

나는 삽질을 했다!

반응형