ecsimsw
Webpack dev server의 포트가 자동으로 바뀐다? / Vue-Cli와 portfinder 본문
Webpack dev server의 포트가 자동으로 바뀐다? / Vue-Cli와 portfinder
JinHwan Kim 2021. 6. 27. 04:08프론트 앱 서버의 포트가 자동으로 변경된다?
되게 신기한 경험을 했다. Vue (webpack dev server)와 Spring boot (톰캣)를 띄웠는데 이 둘을 실행하는 순서에 따라 webpack dev server가 다른 포트로 뜨고, 작동하지 않는 경우도 있었다.
시나리오는 다음과 같다. 프론트 서버, 백 서버 모두 8080으로 설정한 상태이다.
1. 백 서버를 띄우고 프론트 서버를 띄우면 프론트-백 각각 localhost:8081 / localhost:8080으로 뜨고, 정상 작동한다.
2. 프론트 서버를 띄우고 백 서버를 띄우면 프론트-백 각각 localhost:8080 / localhost:8080으로 뜨고, 프론트 앱 서버가 무시된다.
1번 프론트서버가 8081로 뜬 이유 / Vue cli와 portfinder
결론부터 말하면 포트가 이미 사용 중인 경우, vue cli에서 port를 바꿔서 server를 띄운다. 포트가 이미 점유되어 있으면 해당 포트에 +1 해서 다시 사용 가능한지 확인을 반복하는 형식이다.
그래서 백 서버가 8080으로 뜬 상태에서는 8080을 점유 당했음을 확인하고 8081로 변경되어 서버가 뜬 것이다.
사용 가능한 포트는 portfinder 라이브러리를 이용한다. 이는 맨 아래에 'Vue cli와 portfinder 코드 직접 확인하기'로 해당 로직을 직접 따라가도 좋을 것 같다.
2번 프론트 서버가 무시당한 이유 / IPv4와
1번을 알고나니 왜 web dev server를 먼저 실행하면 프론트 서버, 백 서버 모두 8080으로 뜨는지 알았다. vue-cli이 8080으로 먼저 떠서 차마 피할 수 없었던 것이다.
이렇게 되면 web dev server가 무시당한다. 이 상황에서 localhost:8080으로 접속하면 더 이상 web dev server을 타지 않고 tomcat 서버만 타게 된다. 이건 왜 이럴까? 왜 톰캣은 8080이 이미 점유된 상태에서 port already in used 에러를 출력하지 않았을까?
현재 8080 포트를 사용하는 프로세스를 출력해보고 답을 찾을 수 있었다.
web dev server는 IPv4으로 localhost:8080을 사용하고, tomcat은 IPv6로 localhost:8080을 사용하고 있었다. 이때, IPv6가 IPv4보다 우선 순위를 갖기 때문에 localhost:8080에서 web dev server가 무시되고, tomcat 만 응답했던 것이다.
확인을 위해 이번에는 tomcat을 IPv4로 띄워보았고, 포트 물림으로 tomcat server가 못 뜨는 것을 확인할 수 있었다. (물론 반대로 web pack server를 IPv6로 띄우는 방법도 있을 것이다.)
-Djava.net.preferIPv4Stack=true
Jar를 실행할 때 JVM_OPTS 옵션을 추가하거나, Gradle에서 빌드 설정으로 tomcat IP 프로토콜 종류를 설정할 수 있었다.
정리하자면
시나리오를 정리하면 다음과 같다.
시나리오1
1. tomcat을 IPv6/localhost:8080으로 띄운다.
2. webpack dev server를 IPv4/localhost:8080으로 띄운다. -> port change
3. webpack dev server가 IPv4/localhost:8081로 뜬다.
시나리오2
1. webpack dev server를 IPv4/localhost:8080으로 띄운다.
2. tomcat을 IPv6/localhost:8080으로 띄운다.
3. tomcat이 요청 처리 우선 순위를 갖는다. (webpack dev server가 무시 당한다.)
시나리오3
1. webpack dev server를 IPv4/localhost:8080으로 띄운다.
2. tomcat을 IPv4/localhost:8080으로 띄운다 -> port already in use
생각보다 쉬운 문제로 프론트엔드를 전혀 몰라 돌아 돌아 갔던 것 같다. Vue-cli, Webpack dev server라는 키워드를 찾는 것 조차 시간이 걸렸다. 포트가 변경되다니....
Vue cli와 portfinder 코드 직접 확인하기
해당 부분의 코드를 vuejs/vue-cli, node-portfinder에서 직접 확인할 수 있다. 흐름이 보일 수 있도록 필요한 부분만 남기고 그 외 부분을 생략했다.
vue-cli.serve.js -> portfinder.getPortPromise() -> getPort() -> testPort() -> onError(), nextPort() -> port = port+1 순서로 따라가면 될 것이다.
/vuejs/vue-cli/packages/@vue/cli-service/lib/commands/serve.js
//vuejs/vue-cli/packages/@vue/cli-service/lib/commands/serve.js
const defaults = {
host: '0.0.0.0',
port: 8080,
https: false
}
const portfinder = require('portfinder')
portfinder.basePort = args.port || process.env.PORT || projectDevServerOptions.port || defaults.port
const port = await portfinder.getPortPromise()
const urls = prepareURLs(
protocol,
host,
port,
isAbsoluteUrl(options.publicPath) ? '/' : options.publicPath
)
/http-party/node-portfinder/lib/portfinder.js
exports.getPortPromise = function (options) {
...
return new Promise(function(resolve, reject) {
exports.getPort(options, function(err, port) {
if (err) {
return reject(err);
}
resolve(port);
});
});
}
exports.getPort = function (options, callback) {
...
return _async.eachSeries(exports._defaultHosts, function(host, next) {
debugGetPort("in eachSeries() iteration callback: host is", host);
return internals.testPort({ host: host, port: options.port }, function(err, port) {
...
}, function(err) {
...
});
};
internals.testPort = function(options, callback) {
...
function onError (err) {
...
var nextPort = exports.nextPort(options.port);
internals.testPort({
port: nextPort,
host: options.host,
server: options.server
}, callback);
}
...
};
exports.nextPort = function (port) {
return port + 1;
};
** Webpack dev server
webpack dev server는 applicaiton 개발을 도와주는 웹팩이 제공하는 도구이다. 웹 팩의 빌드 대상 파일이 변경되었을 때 코드만 변경하고 저장하는 것으로 웹팩으로 빌드하고 브라우저를 새로고침 해준다.
아래처럼 proxy 설정을 흔하게 사용한다. 추가로 changeOrigin 설정으로 cors 문제를 해결한다.
// webpack.config.js
module.exports = {
devServer: {
proxy: {
'/api': {
target: 'example.com', // proxy to
changeOrigin: true // cors :: same origin 처리
}
}
}
};
'KimJinHwan > Project' 카테고리의 다른 글
좌표가 부채꼴 안에 포함되어 있는지 알고 싶어요. (6) | 2021.11.03 |
---|---|
우리 팀에서 Flyway를 사용하는 이유 (5) | 2021.07.17 |
Spring boot, JPA / Giggle (0) | 2020.10.05 |
JSP, Servlet / 익명 질문과 답변 (1) | 2020.05.20 |
영화 추천 서비스 / TF-IDF, NLP (0) | 2020.03.14 |