TIL | node.js 이것저것

Autumn·2021년 1월 26일
0

TIL

목록 보기
9/19
post-thumbnail

코드스쿼드의 cs10 미션들은 node.js를 이용해서 진행 중이다. 종종 모듈을 사용하는데, ES6의 export/import 문법이 더 최신이라고 해서 export/import 방식으로 쓰는 것을 선호해왔다. 그런데 오늘!! 문제 발생!!

ES6 모듈과 commonJS 모듈을 혼용해서 사용하지 말자

node.js 환경에서 ES6 방식으로 모듈을 사용하려면, package.json 파일 안에 {"type": "module"} 이라고 써줘야 한다. 이렇게 쓰지 않으면 에러가 나고, type:"module"을 쓰거나 mjs 확장자로 쓰라고 친절히 알려준다.

그 이후 나는 Class의 constructor에 모듈을 불러오고 싶어서 아래와 같이 작성했다.

// constructor 안...
this.readline = require('readline');

그런데 자꾸 에러가 난다. ReferenceError: require is not defined...
constructor 안에 import로 써보기도 했는데 아예 허용되지 않는 문법이었다. Class 밖에 아예 빼서 다음과 같이 쓰면 작동이 된다.

import readline from 'readline';

require는 대체 왜 안되는걸까???
알고보니 ES6 모듈과 commonJS 모듈을 혼용해서 쓴 게 문제였다. package.json에 아무런 설정도 안해주면 디폴트값은 {"type": "commonjs"} 이다. 실제로 테스트해보니 type module일 때는 require가 안 되고, type commonjs일 때는 import가 안 됐다. 후우우... 할 것도 많은데 이거 때문에 계속 삽질을... 🤦🏻

혼용해서 쓸 수 있는 방법도 있긴 한 것 같다. 말로만 듣던 바벨을 사용한다던지.. 하지만 아직 공부하진 않았다. 호호


node.js의 이벤트

node.js에도 이벤트가 있다는 것을 이번 미션 하면서 처음 알았다. 이해 못한 채로 그냥 복붙해서 쓰던 readline도 알고보니 이벤트를 핸들링하는 것이었다. eventEmitter라는 키워드를 새로 알게 되었는데, 브라우저에서는 사용자가 뭔가를 클릭한다던지 하는 눈에 보이는 이벤트가 있는 반면 node.js의 이벤트는 뭘 뜻하는 건지 와닿지가 않았다. 지금까지 이해한 바로는 eventEmitter를 사용하면 임의로 이벤트를 정해줄 수 있다는 것이다. 내가 이벤트 이름을 '마마마' 라고 지으면 그냥 '마마마' 이벤트가 발생하는 것이다.

한편 이벤트를 사용하기 위해서는 node.js에 있는 events 모듈을 불러와야 한다. 근데 events 모듈에서 불러오면 클래스로 불러와지는 것 같다. 인스턴스를 생성해야 비로소 이벤트를 발생시키거나 받는 메서드를 사용할 수 있다.

import EventEmitter from 'events';
const emitter = new EventEmitter();

export default emitter

맨 아랫줄의 export는 이 코드 자체를 새로 파일 eventEmitter.js에 썼기 때문에 다른 파일에서 쓸 수 있도록 모듈을 export해주기 위함이다. 만약 같은 파일 안에서 emitter를 쓴다면 export를 써주지 않아도 된다.


node.js에서 이벤트 발생시키기

emitter.emit('event이름'); // 'event이름' 이라는 이벤트를 발생시킴
emitter.on('event이름', callback); // on은 addEventListener와 같은 역할
			    	// 이벤트가 발생하면 콜백함수 실행
  • emitter로 이벤트를 발생시킬 때는 마음대로 이름을 지으면 된다. 그 이름이랑 똑같은 것을 on 메서드의 인자로 넣으면 알아서 처리한다.

// 클래스 내부의 메서드 parse와 addList
parse() {
    this.rl.on("line", function(line) {
      const [menu, count] = line.split(':').map(Number);
      emitter.emit('newOrder', menu, count)
      // this.rl.close();
    })
  }
addList() {
  emitter.on('newOrder', (menu, count) => {
    console.log(menu, count);
  })
}
  • emitargument로 어떤 것이든 추가로 넣을 수 있는데 (옵셔널), 이 인자를 써주면 on의 callback에서 바로 인자로 넣어줄 수 있기 때문에 마치 emit에서 return을 한 것 같은 효과가 있다.
profile
한 발짝씩 나아가는 중 〰 🍁 / 자잘한 기록은 아래 🏠 아이콘에 연결된 노션 페이지에 남기고 있어요 😎

8개의 댓글

comment-user-thumbnail
2021년 1월 26일

우왕...😲 CommonJS, ES6모듈이 뭔지 공부해봐야겠어요 노드와 친해지고 싶다 호호

1개의 답글
comment-user-thumbnail
2021년 1월 26일

어텀 잘 읽고가요~ 저도 그래서 import가 안되는거였군여

1개의 답글
comment-user-thumbnail
2021년 1월 27일

commonJS 방식은 이제 거의 안쓰는 추세인듯 합니다~
ESM을 사랑해주세요~

1개의 답글
comment-user-thumbnail
2021년 1월 29일

방금 import 때문에 헷갈려서 어텀 포스팅 보고 고쳤어요! 👍👍 잘 봤어요~!

1개의 답글