Outsider's Dev Story

Stay Hungry. Stay Foolish. Don't Be Satisfied.
RetroTech 팟캐스트 44BITS 팟캐스트

Grunt 플러그인: grunt-connect-proxy

이전 글에서 grunt-contrib-connect를 소개했는데 실제 프로젝트를 수행하다 보면 정적 웹서버만으로는 충분하지 않고 웹서버를 백엔드 서버로 프락시를 해야 하는 경우가 있다. 퍼블리싱 작업을 한다면 정적 웹서버만으로 충분하겠지만, 보통은 ajax 호출을 하는 백엔드 서버가 있으므로 이 서버와 connect 서버를 연결하고 싶을 수 있다. 이 부분은 JavaScript에서 서버에 대한 호스트를 변수로 두고 환경에 따라 바꿔치기하면서 개발할 수도 있지만 CORS를 지원하는 백엔드 서버가 아니라면 브라우저의 동일출처정책때문에 호출도 제대로 되지 않는다.

grunt-connect-proxy

이럴 때 사용할 수 있는 것이 grunt-connect-proxy이다. grunt-connect-proxy는 grunt-contrib-connect에 연결에서 일부 URL을 다른 서버를 리버스 프록시로 연결한다.

connect: {
  dev: {
    options: {},
  }
}

위와 같은 connect 설정이 있다고 해보자. grunt-contrib-connect에도 다양한 설정이 있지만 여기서는 별로 중요치 않다. npm install grunt-connect-proxy --save-dev으로 grunt-connect-proxy를 설치한 뒤 Gruntfile에서 태스크를 불러오고 다음과 같은 설정을 추가한다.

connect: {
  dev: {
    options: {
      middleware: function (connect, options) {
         var proxy = require('grunt-connect-proxy/lib/utils').proxyRequest;
         return [
            proxy,
            connect.static(options.base),
            connect.directory(options.base)
         ];
      }
    },
    proxies: [
      {
        context: ['/api'],
        host: '127.0.0.1',
        port: 3000
      }
    ]
  }
}

grunt-connect-proxy의 문서를 보면 설정이 꽤 헷갈리게 쓰여 있는데 proxies설정과 middleware 설정을 모두 추가해야 한다. proxies에서는 리버스프락시를 할 대상 서버를 지정한다. 여기서 connect서버는 8000포트로 실행되는데 그중에서 /api로 시작하는 모든 요청은 127.0.0.1:3000으로 보낸다. 그래서 모든 요청은 127.0.0.1:8000으로 보내면서도 일부 요청은 다른 서버에서 응답을 받아서 보낼 수 있다. URL 패턴이 다양하다면 context 배열에 추가하면 된다. 그리고 proxies 설정만으로는 충분하지 않고 grunt-contrib-connect 옵션에 미들웨어를 등록해서 프락시가 동작하도록 해야 한다. grunt-connect-proxy에서 제공하는 프락시를 가져와서 미들웨어에서 요청을 프락시가 먼저 처리하고 그다음에 connect가 처리하도록 바꿔준 것이다.

$ grunt configureProxies:dev connect:dev:keepalive
Running "configureProxies:dev" (configureProxies) task
Proxy created for: /api to 127.0.0.1:3000

Running "connect:dev:keepalive" (connect) task
Waiting forever...
Started connect web server on http://0.0.0.0:8000

connect태스크를 실행하기 전에 configureProxies 태스크를 먼저 실행해야 한다.(여기서 이름은 connect 태스크의 이름과 같다.) 그러면 위처럼 실행하면 로그에서 프락시가 실행된 것을 볼 수 있다. http://0.0.0.0:8000/api/로 요청을 보내면 정적서버가 아닌 프락시 한 서버의 응답이 오는 것을 볼 수 있다.

옵션

  • context: 프락시 할 URL을 지정하고 /로 시작하고 /로 끝나면 안 된다.
  • host: 프락시 할 서버의 호스트(http/https는 적지 않는다.)
  • port: 프락시 할 서버의 포트. 기본값: 80
  • https: https로 프락시 할 것인지 여부. 기본값: false
  • changeOrigin: 프락시 서버에 요청을 보낼 때 출처를 변경할 것인지 여부. 기본값: false
  • xforward: "x-forwarded-for": "127.0.0.1", "x-forwarded-port": 50892, "x-forwarded-proto": "http"같은 x-forward 헤더를 프락시 요청에 추가할 것인지 여부. 기본값: false
  • appendProxies: false로 설정하면 grunt-contrib-connect로 여러 서버를 설정할 때 프락시가 각각 동작하도록 설정을 격리한다. 기본값: true
  • rewrite: 객체로 전달하고 프락시를 할 때 URL을 재작성한다. {'^/changingcontext': '/anothercontext'}처럼 킷값에 정규표현식을 사용해서 값에 해당하는 URL로 교체해서 재작성한다.
  • timeout: 연결에 대한 타임아웃. 기본값 2분(120,000ms)
  • headers: 프락시하는 요청에 추가할 헤더
  • ws: true로 설정하면 웹소켓을 프락시한다. 기본값 false

추가로 grunt-connect-proxy에서도 livereload도 지원한다.

2014/04/23 00:03 2014/04/23 00:03