본문 바로가기

React & Angularjs

1. React HMR ( Hot Module Replace ) 셋팅

Overview



브라우저 리로드 없이 모듈을 바꿔치기 해주는 것을 HMR 이라 부른다. 이는 webpack-dev-server 가 해주는 일이고, webpack dev server 는 HMR 을 위해 아래와 같은 4가지의 기능을 한다.


1. 라이브러리 들을 브라우저에 주입시켜 준다. ( Libraries injected into the browser to perform HMR (webpack hmr) )

2. 브라우저 안에 있는 라이브러리는 서버안에서의 라이브러리 파일들의 변화를 웹소켓 통신을 통해 감지한다. ( Libraries in the browser to listen to changes in the server( i.e. webSocket client) )

3. hot 이 되는지 서버로부터 다른 정보를 가져오는게 되는건지?? ( 이건 무슨말인지 잘 모르겠네요... ㅜㅠ 아시는 분은 답변 좀 부탁드릴게요 ~!! ) ( Needs to know if “hot” is enabled and other info from the server (webSocket info from webpack-dev-server) )

4. 바뀐 부분의 내용을 hot chunk 로 만들수 있는 플러그인이 필요하다. ( Needs a plugin to generate hot chunks that contain the changed parts (HMRPlugin). )

출처 : https://medium.com/@rajaraodv/webpacks-hmr-react-hot-loader-the-missing-manual-232336dc0d96#.huwi8o1hb



위의 사이트를 가보면 HMR 을 실행시키는 3가지 방법에 대해 설명해 주고 있다.

1. CLI 명령어에서 옵션을 통해

2. webpack.conf 파일에서 설정을 통해

3. npm 모듈을 경유해서 


react-create-app 에선 3번의 방법을 택해 사용하고 있고, ( 애초에 webpack dev server 를 run 시키는 부분이 npm 모듈이 작성된 start.js 코드에 들어 있다. ) 그 부분이 어디 설정되어 있는지 보도록 하자.


start.js



hot 이 true 라고 설정된 부분이 끝이긴하다. 이러면 HMR 설정이 끝난것이다. ( 아... 뭔가 겁나 장황하게 설명해놓고 ㅡㅡ;; 이렇게 끝나니;; 참;;; ㅋㅋ )




react 프로젝트 진행시 필요한 loader 추가 설치하기

이미 전 포스트에서 간략하게 설명은 했지만 여기서 추가적인 로더와 설치방법에 대해 좀더 자세히 알아보자!


react-hot-loader 설치/설정

$ npm install –save react-hot-loader@1.3.0

webpack.config.dev.js

...
loaders: [
      // Process JS with Babel.
      {
        test: /\.(js|jsx)$/,
        include: paths.appSrc,
        loaders: ['react-hot', 'babel?' + JSON.stringify(require('./babel.dev'))]
      },
...


loaders 를 통해 multiple loader 의 설정이 가능하다. 기존의 single loader 에서 넘겨야 하는 query는 뒤에 JSON.stringify 를 통해 넘겨줄 수 있다. ( 이게 버전 3으로 넘어가면서는 설정하는 방법이 바뀌는것 같음 )

entry: [
    require.resolve('webpack-dev-server/client') + '?/http://0.0.0.0:8080',
    //require.resolve('webpack/hot/only-dev-server'),
    require.resolve('webpack/hot/dev-server'),

 - only-dev-server : 이 설정의 경우 syntax 에러가 있으면 브라우저를 reload 하지 않는다. 그래서 React apps 에서는 이 설정을 추천한다고 하는데... 음... 왜지?? 난 개인적으로 이 설정보단 리로드가 되고 에러메시지를 표현해주는게 낫지 않은가..?? 라고 생각해서 아래 설정을 쓸거다! ㅋㅋ ( doesn’t reload the browser upon syntax errors. This is recommended for React apps because it keeps the state. )

 - dev-server  : 디폴트 설정이고, 브라우저 전체를 리로드한다. tries HMR (default). If there is any issue, it reloads the entire browser.


proxy 설정

var devServer = new WebpackDevServer(compiler, {
    ...
    proxy : {
      '/api/*': 'http://localhost:8081'
    }
    ...


하지만 만약 아래와 같은 경우로 api 와 web server 를 동일하게 놔두고, api path 이외에 다른 path 가 proxy 되야 하는 경우 ( 위의 사이트에서는 web server 로 node 를 띄워 ejs 파일이 html 로 랜더링 되려는 경우를 예로 듬 ) production 에서는 문제가 없지만 develop 환경에서는 문제가 될 수 있다.

==>> 음... 나의 경우에는 사실 api 서버는 정말 api 만을 위해 존재하고 CDN 을 위한 web server 구성으로 따로 생각중이어서... 아래와 같이 proxy 설정을 또 잡을 필요는 없다. 근데 하나 이야기 하고 싶은게 있어서 +_+!! ㅋㅋ



var devServer = new WebpackDevServer(compiler, {
    ...
    proxy : {
      '*': 'http://localhost:8081'
    }
    ...


자 이렇게 모든 url 을 proxy 가 타도록 설정했다고 치자. 그럼 이런 의문이 들것이다.

미친거 아냐..?? ㅡㅡ 다 proxy 를 타면 css도 js 도 뭐도 다 타것네... 라고 생각이 들었는데

webpack-dev-server 에는 publicPath overrides proxy settings 라는 것이 있다 !!



publicPath overrides proxy settings

만약 우리가 클라이언트 딴 (browser 딴 ) 에서 아래와 같은 경로로 request 를 날렸다고 한 경우 해당 resource는 우리가 띄운 webpack 서버가 아닌 web/was 서버에서 가져오고 싶은경우 잘 동작할 것이다.


1. “/” (to load index file from compiled index.ejs),

2. “/stylesheets/style.css” (to load style.css)

3. “/api/serverTime” (to return serverTime api value).


근데 /static/js/bundle.js 와 같이 webpack 서버에서 가져와야 되는 resource 까지 전부 proxy 되면?? 음... 쫌 망이지 않나?? 라고 생각했는데 webpack-dev-server 에 publicPath 라는 설정이 존재하드라!! 아래 설명을 읽어보면 publicPath 에 등록된 resource 들은 proxy 보다 우선적으로 작동한다. 즉, proxy 에 설정된 path 를 씹어버린다는 것이다. ( 아 표현이 쫌 과격한가... ㅋㅋ override 한다는 것이다. )

This means if you are loading bundle.js from a different directory that doesn’t match publicPath settings (you’ll have to setup ANOTHER proxy on the Express server that’s running on port 3000 (that points back to localhost:8080). This will be super confusing.

Also, you don’t have to use publicPath at all. If you don’t set it or set it to ‘/’, just make sure that the ejs files load bundle.js like so:

<script src=”/bundle.js”></script>



여튼 이정도 하면 HMR with react-hot-loader, proxy 설정은 끝난것 같다!! ㅜㅠㅜㅠ