prefix
module.exports = {
output: {
path: path.resolve("./examples/dist"),
filename: "app.js",
publicPath: "/assets/"
}
}
Webpack설정을 위와같이 했을때, <img src="picture.jpg">
라는 코드를 Webpack은 <img src="/assets/picture.jpg">
이렇게 바꿀것이다.
그래서 내 앱이 http://server.com/
에서 돌아가고 있다면, 브라우저는 http://server.com/assets/picture.jpg
파일을 읽어들일것이다.
이런 prefix의 기능을 활용해서 js / css / font파일이 cdn서버에서 가져와질 수 있도록 할 수 있다. publicPath : "http://cdn.com/"
이렇게 해놓으면 파일들의 root path가 다 cdn.com
으로 되서 저 서버에서 해당 파일들이 가져와질것이다.
(같은 이야기지만) file-loader에서도 prefix의 역할로써 publicPath가 사용된다.
webpack-dev-server
prefix의 개념과는 별로 상관없이, webpack-dev-server에서 publicPath를 제대로 설정해 주지 않으면 auto-reload가 안되는 문제가 있다.
localhost:8080/
React APP이 root path(localhost:8080/
)에서 작동한다면 publicPath는 따로 지정 안해도 소스코드를 수정하면 알아서 reload될것이다(auto-reload).
localhost:8080/user/
서비스의 규모가 커서 페이지 별로 따로 React APP을 만들었다면, 주소창도 localhost:8080/user/
이런식으로 될것이다. 예를들어서, 나는 관리자 페이지와 유저 페이지를 하나의 React APP으로 구성하지 않고 따로따로 만들었는데, localhost:8080/user/
에 들어올때 돌려주는 index.html / main.js / style.css 파일 따로, localhost:8080/admin/
에 들어올때 돌려주는 index.html / main.js / style.css파일 따로 준비했다. 당연히 package.json 파일과 webpack.config.js파일도 각각 따로 준비했다.
이런 경우에는 publicPath를 꼭 지정해 줘야한다. 만약 index.html파일에 <script src="main.js"></script>
이렇게 직접 적어놨다면, publicPath를 /user
로 지정해야한다. 이렇게 해야 auto-reload가 제대로 작동한다. 그 이유는 아래와 같다. (참고로 src="main.js"
로 하면 브라우저는 현재 주소가 localhost:8080/user
이기 때문에, localhost:8080/user/main.js
파일을 요청한다)
그리고 직접 index.html에 <script src="main.js"></script>
를 적은게 아닌 경우에도 흠....이건 잘 모르겠다. 테스트를 해봐야겠다.
main.js in memory
webpack-dev-server는 소스코드가 수정되면 자동으로 auto-reload를 진행한다. 순서는 다음과 같다.
- 소스코드를 수정하면
- entry포인트부터 좌라락 js파일들을 읽어서 main.js로 build하고
- 브라우저에게 socket통신으로 알람을 보낸다("야 새로고침해라!")
- 브라우저는 새로고침을 하고 main.js를 요청한다
- webpack은 새로 빌드된 main.js를 돌려준다.
그런데 주의해야할것은 webpack-dev-server에서 build되는 main.js파일은 실제 하드디스크에 저장되는게 아니다. 다시말하면 우리가 output으로 지정한 path에 저장되는게 아니다. 단지 build된 main.js은 메모리(RAM)에만 존재할 뿐이다. 그래서 소스코드를 수정할때마다 HD에 저장하는 번거로움이 없기 때문에 빠릿빠릿하게 auto-reload가 되는것이다.
우리가 RAM에 있는 main.js를 브라우저에게 던져주기 위해서는 publicPath를 잘 설정해 줘야한다. publicPath를 /user
라고 설정했다면, webpack-dev-server는 브라우저가 localhost:8080/user/main.js
파일을 요청할때 저 파일이 하드디스크에 있다 하더라도, RAM에 있는 main.js파일을 돌려준다. 그런데 이런 상황에서 publicPath를 설정해 주지 않았다면, webpack-dev-server는 하드디스크에 있는(소스코드 수정이 반영안된) main.js파일을 돌려줄 것이다. 하드디스크에도 없으면 에러를 낼것이다.
간단히 정리하자면, publicPath는 prefix기능을 기본으로 하지만, webpack-dev-server에서는 현재 React App이 돌아가는 서버 주소 + publicPath 를 메모리의 주소값처럼 사용한다. 그래서 하드디스크에 저장된 main.js파일이 아닌 방금 따끈따끈하게 빌드된 RAM에 있는 main.js를 돌려주는것이다.