반응형

기본적으로 Javascript의 원시 타입(Undefined, Null, Boolean, Number, String 등)을 제외한 모든 객체는 mutable하다.

즉 생성된 이후에 언제든 변경될 수 있다.

 

이런 mutable한 객체를 immutable하게 변경하는 것도 가능하다. 다음의 두 옵션을 활용해볼 수 있다.

 

1. Object.defineProperty를 통한 설정

let customObj = {};
Object.defineProperty(customObj, "newKey", {value: "newValue"});

위와 같이 Object.defineProeprty 메소드를 사용하면 newKey의 값은 읽기 전용이되어 수정하는 것이 불가해진다.

이 메소드는 writable 옵션을 포함하고 있는데 기본 값이 false이다.

하지만 새로운 프로퍼티를 추가하는 것은 얼마든 가능하며, {writable: true} 옵션을 설정할 경우 수정이 가능해진다.

let customObj = {};
Object.defineProperty(customObj, "newKey", {value: "newValue"});

customObj.anotherKey = "anotherValue"; // 새로운 프로퍼티를 추가할 수 있다.
// customObj = {newKey: "newValue", anotherKey: "anotherValue"}

customObj.anotherKey = "theOtherValue"; // 수정도 가능하다.
// customObj = {newKey: "newValue", anotherKey: "theOtherValue"}

customObj.newKey = "anotherValue"; // 하지만 writable: false인 프로퍼티의 경우 암묵적으로 무시된다.
// customObj = {newKey: "newValue"}

Object.defineProperty(customObj, "theOtherKey", {value: "theOtherValue", writable: true});
customObj.theOtherKey = "newValue"; // 수정이 가능하다.
// customObj = {theOtherKey: "newValue"}

 

2. Object.freeze 를 통한 설정

let customObj = {};
customObj.newKey = "newValue";
Object.freeze(customObj);

위와 같이 freeze를 사용하게 되면 객체가 말그대로 얼어 붙는다. 추가하거나 삭제, 수정 모두가 불가해진다.

let customObj = {};
customObj.newKey = "newValue";
Object.freeze(customObj);

// 모든 편집 작업이 암묵적으로 무시된다.
customObj.anotherKey = "anotherValue"; // 추가할 수 없다.
// customObj = {newKey: "newValue"}

delete customObj.newKey; // 제거할 수 없다.
// customObj = {newKey: "newValue"}

customObj.newKey = "anotherValue"; // 수정할 수 없다.
// customObj = {newKey: "newValue"}

 

 

특정 프로퍼티를 immutable하게 하려면 Object.defineProperty를, 객체 자체를 immutable하게 하려면 Object.freeze를 활용하면 된다.

반응형
반응형

nodejs 프로젝트 구성 시, 페이지를 표출하기 위한 서버와 api 통신을 위한 서버를 분리하는 경우가 많다.

분리하면 각각을 별도로 작업할 수 있어 전체적인 서비스에 주는 영향을 줄일 수 있지만, 그 만큼 관리해야 하는 서버가(포트가) 늘어나는 것도 사실이다.

 

따라서 작은 서비스의 경우 api 통신을 위한 서버를 분리하지 않고 합쳐서 진행할 수도 있다.

서버를 실행하면 페이지의 리소스에 접근이 가능하고, path에 따라 api 통신을 하기도 하는 것이다.

 

대략 아래와 같은 구조를 갖는 서버가 될 것이다.

const express = require("express");
const app = express();
const fetch = require("node-fetch");

app.use("/", express.static(__dirname + "/"));
app.get("/api", (req, res) => {
  fetch("some_api_url")
    .then((response) => {
      res.send(response);
      res.end();
    });
});

app.listen(8080);

결과만 보았을 때, 동작하는 데에는 큰 이상이 없다. 

 

하지만 webpack을 도입하면서(webpack devserver)는 문제가 생긴다.

webpack devserver는 위에서 작성한 서버를 실행시켜주지 않는다. 단지 엔트리 파일과 아웃풋을 지정하고 devServer의 포트 등을 설정하면 그에 맞는 별도의 개발 서버가 실행되고, 출력된 아웃풋을 사용하면 되는 것이다.

 

따라서 webpack devserver를 활용하려는 경우도 위 코드를 그대로 실행하거나, api 호출 부분을 분리해서 실행해야한다.

webpack devserver 도입으로 인해 구동이 필요한 서버가 하나에서 여럿으로 분리되는 것은 그리 좋지 않은 방법이므로,

위 코드를 그대로 실행한 채 webpack devserver를 추가로 실행한다.

(api 호출이 아닌 다른 부분에서 영향이 줄만한 곳이 있다면 주석 처리 등 임시 작업이 필요할 수 있다)

 

devServer 설정이 다음과 같다고 하면,

devServer: {
  contentBase: ".",
  port: 9090,
}

 

현재 :8080 에는 api 서버가, :9090 에는 devServer 가 실행중인 것으로 볼 수 있다.

 

devServer 도입 전 상황을 다시 생각해보면 리소스 호출과 api 호출이 같은 포트를 사용하였기 때문에 이미 코드상에서 호스트가 생략된 상태일 것이다. 

devServer 도입 후에는 두 서버의 포트가 달라지기 때문에 호스트와 포트를 명시하지 않으면 404에러가 발생한다.

이런 경우에 사용할 수 있는 것이 proxy이다.

devServer: {
  contentBase: ".",
  port: 9090,
  proxy: {
    "/api/*": {
      target: "http://localhost:8080",
    },
  },
}

위와 같이 proxy를 설정하면 api 요청에 대해서는 :8080 포트를 사용하도록 처리된다.

 

네이밍의 차이로 인해 경로가 달라져야 한다면, 다음과 같이 rewrite 하는 것도 가능하다.

devServer: {
  contentBase: ".",
  port: 9090,
  proxy: {
    "/api/*": {
      target: "http://localhost:8080",
      pathRewrite: {"^/api": "/agent"}, // /api로 시작하는 문자를 /agent 로 변경
    },
  },
}
반응형
반응형

크롬 개발자 도구로 디버깅을 하던 도중, 작성한 파일명이 아닌 VM으로 시작하는 파일이 열리며 하이라이팅이 잘못 표시되는 현상이 발생했다.

 

VM으로 시작하는 파일은 블랙박스로 간주되는 것으로 eval, iframe 등을 사용하면 나타난다고 하는데, 내 코드에는 그런 부분이 없었다.

같은 이름의 파일이 여러번 로드되면 그런 경우가 발생할 수도 있다고 하는데, 코드에서 여러번 같은 파일을 로드하지도 않았다.

 

중단점과 관련한 이슈가 많았는데 그런 경우에는 debugger라는 키워드를 코드에 삽입하여 코드를 중단시키면 된다는 것이었는데

나의 경우에는 중단점이 걸리긴 하나 중단점과 무관한 위치에서 코드가 멈추어 있었다.

 

개발자도구를 껐다가 다시 켜고, 캐시도 제거해보았으나 현상은 계속 발생하였다.

그러던 중 URL에 붙어있던 해시를 제거하고 페이지에 접속하면 정상적인 동작을 하는 것을 발견했다.

 

이 해시는 페이지 로드 이후에 동적으로 삽입된 것인데 그게 개발자 도구에 어떤 영향을 준 것 같다.

 

요약:

URL에 해시가 붙은 채로 접속하면 현상이 발생하고, 해시를 제거하고 접속하면 정상 동작하였다.

 

추가:

html 페이지에 script 태그 내에서 스크립트 코드를 작성한 경우 현상이 발생한다.

html 페이지와 script를 분리해서 관리하고 html 페이지에서는 script를 로드만 하도록 하자.

반응형

+ Recent posts