typescript, react를 함께 사용할 겸 프로젝트를 진행하여 실습처럼 공부하려고 했었다.
이를 위해 webpack을 설정하던 중 계속 devserver을 통해 해당 프로젝트를 돌려도 Cannot GET /
이라는 텍스트와 함께 돌아가지 않았다.
문제를 해결하다보니 될때도 있고 안될 때도 있고 왔다갔다하는 이상한 상황이 되버렸다.
내 자신이 설정을 잘못 건드는 것이 확실한데 어떠한 것이 확실한지 몰라서 먼저 리스트를 만들어서 해결해 보기로 하였다.
결국 문제는 webpack 설정 이였다.
Cannot GET /
로 페이지가 표시되는 이유는 devServer가 참조해야할 index.html
파일이index_bundle.html
으로 되어있기 때문이었다.
일단 당시 webpack의 설정은 아래와 같았다.
// webpack.config.js
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
module.exports = {
entry: "./src/index.tsx",
resolve: {
extensions: [".ts", ".tsx", ".js"],
},
output: {
path: path.join(__dirname, "public"),
filename: "main.js",
},
module: {
rules: [
{
test: /\.tsx?$/,
loader: "ts-loader",
},
],
},
devServer: {
contentBase: path.join(__dirname, "public"), // 콘텐츠를 제공할 경로지정
compress: true, // 모든 항목에 대해 gzip압축 사용
hot: true, // HRM(새로 고침 안해도 변경된 모듈 자동으로 적용)
port: 9000, // 접속 포트 설정
},
plugins: [
new CleanWebpackPlugin({
cleanAfterEveryBuildPatterns: ["dist", "public"],
}),
new HtmlWebpackPlugin({
template: "./src/index.html", // 적용될 html 경로
filename: "./index_bundled.html", // 결과 파일명
meta: {
// meta 태그를 추가
viewport: "width=device-width, initial-scale=1, shrink-to-fit=no",
},
hash: true, // 모든 스크립트, css 파일에 고유한 컴파일 해시 추가하여 캐시를 무효화
showErrors: true, // 오류 정보가 html에 기록됨
}),
],
};
여기에서 잘못된 것은 htmlWebpackPlugin
의 설정중 filename
이 index_bundled.html
인 것이다.
new HtmlWebpackPlugin({
template: "./src/index.html", // 적용될 html 경로
filename: "./index_bundled.html", // 결과 파일명
...
)}
filename
은 내보낼 HTML 파일명으로 index_bundled.html
로 값을 설정하면 index_bundled.html
이 생성된다.
그리고 devserver
를 보면 아래와 같다.
devServer: {
contentBase: path.join(__dirname, "public"), // 콘텐츠를 제공할 경로지정
compress: true, // 모든 항목에 대해 gzip압축 사용
hot: true, // HRM(새로 고침 안해도 변경된 모듈 자동으로 적용)
port: 9000, // 접속 포트 설정
},
이는 webpack-dev-server
명령어 실행시 Webpack으로 번들링된 결과물이contentBase
에 의해서 루트 폴더를 public
으로 저장되게 된다.
따라서, 이 설정으로는 Webpack으로 번들링된 결과물이 index_bundled.html
로 나오며 devServer는 public
폴더를 루트로 잡아 스크립트를 참조하게 된다.
그러나, devServer는 기본으로 index.html 파일을 참조하므로 index_bundled.html
를 찾지 못해 Cannot GET /
만을 내보내는 것이었다. 💡💡
아래와 같이 HtmlWebpackPlugin 설정에서 filename
부분을 삭제 혹은 filename: ./index.html
을 해서 해결할 수 있었다.
new HtmlWebpackPlugin({
template: "./src/index.html", // 적용될 html 경로
filename: "./index.html"
// 혹은 아예 filename 부분을 삭제하면됨
...
)}
💡
webpack-dev-server
로 번들링한 결과물이 파일 탐색기에서 보이진 않지만 정상적으로 애플리케이션에 로딩된다.
📖 추가로 Webpack 공식문서를 찾아 htmlWebpackPlugin 을 보니 아래와 같은 내용을 찾을 수 있었다.
구글 번역기(
구글 번역기 최고다)를 돌려 위의 사진을 번역하면 아래와 같다.번들을 제공하려면 HTML 템플릿이 필요하며 일반적으로
index.html
파일입니다. 스크립트 참조가 HTML에 추가되었는지 확인하십시오. webpack-dev-server는 이를 자동으로 삽입하지 않습니다.
조금 더 효율적으로 찾을 수 있었던 문제였는데 여러가지를 시도해보고 않되서 중간중간에 딴 짓을 많이 했었다.
문서를 좀 더 찾아볼 걸이라는 생각이 드는 삽질이였다.