개발환경과 운영환경을 맞춤으로써 배포시 잠재적 문제를 미리 확인할 수 있기 때문에 개발환경에서도 유사한 환경을 맞춰주는 것이 좋다.
ajax 방식의 api 연동은 cors 정책 때문에 반드시 서버 필요하다.
프론트엔드 개발환경에서 이러한 개발용 서버를 제공해주는 것이 webpack-dev-server
$ npm i -D webpack-dev-server
//package.json
{
"scripts": {
"start" : "webpack-dev-server"
}
}
개발 서버를 실행할 때 명령어 인자로 --progress
를 추가하면 빌드 진행율을 보여줌 → 빌드 시간이 길어질 경우 사용하면 좋음//webpack.config.js
module.exports = {
devServer: {
contentBase: path.join(__dirname, "dist"),
publicPath: "/",
host: "localhost",
overlay: true,
port: 8080,
hot: true,
stats: "errors-only",
historyApiFallback: true,
},
}
웹팩 서버에 기능을 추가할 수 있는 여지를 제공
// webpack.config.js
module.exports = {
devServer: {
before: (app, server, compiler) => {
app.get("/api/keywords", (req, res) => {
res.json([
{ keyword: "이탈리아" },
{ keyword: "세프의요리" },
{ keyword: "제철" },
{ keyword: "홈파티" },
])
})
},
},
}
axios로 api를 호출하여 데이터를 반환시킨다
특정 목업 폴더를 만들어 api 응답을 담은 파일을 저장한 뒤, 이 폴더를 api로 제공해주는 기능
→ 목업 갯수가 많다면 직접 컨트롤러를 작성하는 것보다 목업 파일로 관리하는 것 추천
$ npm i -D connect-api-mocker
목업파일 생성
//GET.json
[
{ "keyword": "이탈리아" },
{ "keyword": "세프의요리" },
{ "keyword": "제철" },
{ "keyword": "홈파티 " }
]
// webpack.config.js:
const apiMocker = require("connect-api-mocker")
module.exports = {
devServer: {
before: (app, server, compiler) => {
app.use(apiMocker("/api", "mocks/api"))
},
},
}
로컬호스트 8081 포트에 서버 구성되어 있다면
const model = {
async get() {
// const result = await axios.get('/api/keywords');
// 직접 api 서버로 요청한다.
const { data } = await axios.get("http://localhost:8081/api/keywords")
return data
},
}
localhost:8080에서 localhost:8081로 ajax 호출을 하지 못하는 이유는 CORS 정책 때문이라는 오류메시지가 뜬다. 요청하는 리소스에 “Access-Control-Allow-Origin” 헤더가 없다는 의미이기도 함
CORS(Cross Origin Resource Shaing) 브라우저와 서버간의 보안상의 정책으로
브라우저가 최초로 접속한 서버에서만 ajax 요청을 할 수 있다는 내용
api 응답 헤더에 “Access-Control-Allow-Origin”: *” 헤더를 추가한 뒤 응답하면, 브라우저에서 응답 데이터를 받을 수 있음
// server/index.js
app.get("/api/keywords", (req, res) => {
res.header("Access-Control-Allow-Origin", "*") // 헤더를 추가한다
res.json(keywords)
})
웹팩 개발 서버에서 api 서버로 프록싱 → 웹팩 개발 서버는 proxy속성으로 이를 지원
// webpack.config.js
module.exports = {
devServer: {
proxy: {
"/api": "http://localhost:8081", // 프록시
},
},
}
API 호출 코드
// src/model.js
const model = {
async get() {
// const { data } = await axios.get('http://localhost:8081/api/keywords');
const { data } = await axios.get("/api/keywords")
return data
},
}
싱글페이지어플리케이션은 브라우저에서 데이터를 들고 있기 때문에 리프레시 후에 모든 데이터가 초기화되어버리거나 다른 부분을 수정했을 때 입력한 폼 데이터가 날아가는 경우 전체 화면을 갱신하는 것에 대한 불편함이 존재
전체 화면을 갱신하지 않고 변경한 모듈만 갱신해주는 기능
// webpack.config.js:
module.exports = {
devServer = {
hot: true,
},
}
devServer.hot 옵션을 켜면 웹팩 개발 서버 위에서 module.hot
객체가 생성
if(moduel.hot){
console.log("핫모듈 켜짐")
module.hot.accept("./result.js", ()=>{
console.log("result 모듈 변경됨")
})
}
HMR 인터페이스를 구현한 로더만이 핫 로딩을 지원함.
style-loader
가 이에 해당됨