코드스쿼드의 cs10 미션들은 node.js를 이용해서 진행 중이다. 종종 모듈을 사용하는데, ES6의 export/import 문법이 더 최신이라고 해서 export/import 방식으로 쓰는 것을 선호해왔다. 그런데 오늘!! 문제 발생!!
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에도 이벤트가 있다는 것을 이번 미션 하면서 처음 알았다. 이해 못한 채로 그냥 복붙해서 쓰던 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를 써주지 않아도 된다.
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);
})
}
emit
의 argument
로 어떤 것이든 추가로 넣을 수 있는데 (옵셔널), 이 인자를 써주면 on
의 callback에서 바로 인자로 넣어줄 수 있기 때문에 마치 emit
에서 return을 한 것 같은 효과가 있다.
우왕...😲 CommonJS, ES6모듈이 뭔지 공부해봐야겠어요 노드와 친해지고 싶다 호호