728x90

node.js의 module.exports와 exports

(노트: 이 글은 Node.js 6.1.0 릴리즈 이후에 작성되었습니다.)

요약

  • module.exports는 require() 함수를 사용했을 때 반환 받는 변수라고 생각해봅시다. 비어 있는 객체가 기본값이며 어떤 것으로도 자유롭게 변경할 수 있습니다.
  • exports 자체는 절대 반환되지 않습니다! exports는 단순히 module.exports를 참조하고 있습니다. 이 편리한 변수를 사용하면 모듈을 작성할 때 더 적은 양의 코드로 작성할 수 있습니다. 이 변수의 프로퍼티를 사용하는 방법도 안전하고 추천하는 방법입니다.

exports.method = function () { /* ... */ } // vs. module.exports.method = function () { /* ... */ }

간단한 모듈 예제

먼저 예제로 사용할 코드가 필요합니다. 간단한 계산기로 시작합니다.

// calculator.js module.exports.add = (a, b) => a + b

다음처럼 사용할 수 있습니다.

// app-use-calculator.js const calculator = require('./calculator.js') console.log(calculator.add(2, 2) // 출력: 4

모듈 감싸기

Node.js는 require()로 모듈을 불러올 때 함수 래퍼(wrapper) 형태를 사용해 내부적으로 감싸서 호출합니다.

(function (exports, require, module, __filename, __dirname) { // calculator.js의 내용은 여기에 추가해 실행합니다. module.exports.add = (a, b) => a + b });

module 객체

변수 “module”은 객체로 현재 모듈을 나타냅니다. 이 변수는 각 모듈에 지역적이며 비공개(private) 입니다. (모듈 코드에서만 접근할 수 있습니다.)

// calcualtor-printed.js module.exports.add = (a, b) => a + b console.log(module) // 이 모듈을 require('./calculator-printed.js')로 호출하면 다음과 같은 결과를 볼 수 있습니다. // // Module { // id: '/Users/laz/repos/module-exports/calculator-printed.js', // exports: { add: [Function] }, // parent: // Module { ... } // filename: '/Users/laz/repos/module-exports/calculator-printed.js', // loaded: false, // children: [], // paths: [ ... ] // }

module.exports

  • 객체 참조로 require() 호출을 하면 받는 값입니다.
  • Node.js에 의해 자동으로 생성됩니다.
  • 일반 JavaScript 객체를 참조합니다.
  • 또한 기본값은 비어 있습니다. (앞서 코드에서는 add() 메소드를 추가했습니다.)

다음 두 방법으로 module.exports를 사용합니다.

  1. 공개(public) 메소드를 붙여 사용합니다. (앞서 작성한 예제가 이 방법입니다.)
  2. 직접 작성한 객체나 함수로 대체하는 방식을 사용합니다.

왜 대체하는 방식으로 사용할까요? 대체하는 방식으로 사용하면 다른 클래스를 임의적으로 수정해 반환하는 것도 가능합니다. 다음 ES2015 예제를 보겠습니다.

// calculator-base.js module.exports = class Calculator { add(a, b) { return a + b } substract(a, b) { return a - b } }

이 calculator-base 예제에서는 클래스를 내보냈습니다. 다음 예제에서는 “Calcaulator” 클래스를 확장한 후, 클래스의 개체를 내보냅니다.

// calculator-advanced.js const Calculator = require('./calculator-base.js') class AdvancedCalculator extends Calculator { multiply(a, b) { return a * b } devide(a, b) { return a / b } } module.exports = new AdvancedCalculator()

// app-use-advanced-calculator.js const calculator = require('calculator-advanced.js') console.log(calculator.add(2, 2)) // 출력: 4 console.log(calculator.multiply(3, 3)) // 출력: 9

exports 별칭(alias)

  • exports는 편의 변수로 모듈 작성자가 코드를 덜 작성하도록 돕습니다.
  • 이 변수의 프로퍼티를 사용하는 방식은 안전하고 추천하는 방법입니다. (예를 들면 exports.add = function () { /* ... */ } 식으로)
  • exports  require() 함수에서 반환되지 않습니다. (module.exports는 반환하지만요!)

좋은 예제와 나쁜 예제를 확인합니다.

// calculator-exports-exmaples.js // 좋음 module.exports = { add(a, b) { return a + b } } // 좋음 module.exports.subtract = (a, b) => a - b // 가능함 exports = module.exports // 위에서 작성한 코드보다 간단하고 짧은 코드 exports.multiply = (a, b) => a * b // 나쁨, exports는 바깥으로 전달되지 않음 exports = { divide(a, b) { return a / b } }

노트: module.exports를 함수나 객체로 대체하는 경우는 일반적인 접근법입니다. 이렇게 대체하면서도 여전히 exports 축약을 사용하고 싶다면 exports를 새로 대체할 객체를 가리키도록 설정해야 합니다. (위에서도 이런 방법을 사용헀습니다.)

exports = module.exports = {} exports.method = function () { /* ... */ }

결론

변수명은 exports지만 실제로 내보내지 않는다는 사실은 좀 혼란스러울 수 있습니다. 막 node.js를 시작한 사람이라면 특히 그럴겁니다. 공식 문서에서도 이 부분이 조금 이상합니다.

exports와 module.exports의 관계가 마술처럼 느껴진다면 exports는 무시하고 module.exports만 사용하도록 지침을 드립니다.

제 경우엔 이런 코드가 마술이라고 생각하지 않습니다. 개발자라면 사용하는 플랫폼과 언어가 어떻게 동작하는지 깊게 이해하려는 노력을 항상 해야합니다. 이처럼 깊게 이해하는 과정에서 프로그래머는 값진 자신감과 지식을 얻으며 코드 품질, 시스템 구조와 생산성에 긍정적인 영향을 주게 됩니다.

제 글을 읽어주셔서 감사합니다. 의견이나 생각은 언제나 환영하니 덧글로 남겨주세요.

 

edykim.com/ko/post/module.exports-and-exports-in-node.js/

728x90

[Nodejs] Class사용 및 상속(extends)하기

출처: https://fenderist.tistory.com/313 [Devman]

728x90

하드웨어 디바이스와 통신에 가장 쉽고 많이 사용되는것이 시리얼포트이다. NodeJS에서 시리얼 포트를 사용하려면 Chris Williams가 만든 serialport 모듈을 사용하면 된다.

먼저 serialport 모듈을 설치한다.

$ npm install --save-dev serialport

> serialport@1.6.2 install /home/test/node_modules/serialport
> node-pre-gyp install --fallback-to-build

[serialport] Success: "/home/test/node_modules/serialport/build/serialport/v1.6.2/Release/node-v11-darwin-x64/serialport.node" is installed via remote
serialport@1.6.2 ../node_modules/serialport
├── bindings@1.2.1
├── sf@0.1.7
├── nan@1.7.0
├── optimist@0.6.1 (wordwrap@0.0.2, minimist@0.0.10)
└── debug@2.1.3 (ms@0.7.0)


설치가 완료되면 시리얼 포트를 열어준다.

$ node
> var serialport = require("serialport");
undefined
> SerialPort = serialport.SerialPort;
{ [Function: SerialPort]
  super_:
   { [Function: Stream]
     super_: { [Function: EventEmitter] listenerCount: [Function] },
     Readable:
      { [Function: Readable]
        ReadableState: [Function: ReadableState],
        super_: [Circular],
        _fromList: [Function: fromList] },
     Writable:
      { [Function: Writable]
        WritableState: [Function: WritableState],
        super_: [Circular] },
     Duplex: { [Function: Duplex] super_: [Object] },
     Transform: { [Function: Transform] super_: [Object] },
     PassThrough: { [Function: PassThrough] super_: [Object] },
     Stream: [Circular] } }
> var serialPort = new SerialPort("/dev/cu.usbmodem14131", {
      baudrate: 9600,
      parser: serialport.parsers.readline("\n")
});
> serialPort = new SerialPort("/dev/cu.PL2303-00003014", {
... baudrate: 9600,
... parser: serialport.parsers.readline("\n")
... });
{ domain: null,
  _events: {},
  _maxListeners: 10,
  fd: null,
  paused: true,
  bufferSize: 256,
  readable: true,
  reading: false,
  options:
   { baudrate: 9600,
     parser: [Function],
     baudRate: 9600,
     dataBits: 8,
     stopBits: 1,
     parity: 'none',
     rtscts: false,
     xon: false,
     xoff: false,
     xany: false,
     bufferSize: 256,
     platformOptions: { vmin: 1, vtime: 0 },
     dataCallback: [Function],
     disconnectedCallback: [Function] },
  path: '/dev/cu.PL2303-00003014' }


위에서 '/dev/cu.PL2303-00003014' 부분은 시스템에 맞게 바꿔주면 된다. 리눅스라면 보통 '/dev/ttyUSB0' 같은 이름이고 윈도우라면 'COM1' 같은 이름이 된다.

테스트하기 위해 아두이노에 0.1초마다 숫자를 하나씩 증가시켜 시리얼포트로 출력하도록 하는 스케치를 업로드 해 준다.

setup() { 
  Serial.begin(9600); 


int i=0; 
void loop() { 
  Serial.println(i++); 
  delay(100); // poll every 100ms 
}

Reading from the port

시리얼포트에서 값을 읽어 화면에 표시하기 위해 다음의 코드를 작성해 'dump.js'라는 이름으로 저장해준다. 

var serialport = require("serialport"); 
var SerialPort = serialport.SerialPort; 

var serialPort = new SerialPort("cu.PL2303-00003014", { 
  baudrate: 9600, 
  parser: serialport.parsers.readline("\n") 
}); 
serialPort.on("open", function () { 
  console.log('open'); 
  serialPort.on('data', function(data) { 
    console.log(data); 
  }); 
});

이제 아두이노를 USB-to-Serial 케이블에 연결하고 dump.js를 실행한다.

$ node jump.js
...
5
6
7
....
^C


좀 더 상세한 정보와 예제 코드는 https://www.npmjs.com/package/serialport 를 참조하면 된다.

 

arsviator.blogspot.com/2015/03/nodejs.html

728x90

깃(GIt) 사용시 현재 로컬 저장소(local repository)에 연결되어 있는 원격 저장소(remote repository)를 연결을 끊고 다시 연결 하는 방법을 간단히 포스팅 합니다.

 

먼저 git remote -v 명령어를 사용하여 현재 연결되어 있는 원격 레파지토리를 확인해 봅시다.

$ git remote -v
origin https://github.com/IfUwanna/Tool.git (fetch)
origin https://github.com/IfUwanna/Tool.git (push)

 

github 원격 저장소와 연결되어 있는 것을 확인 하실 수 있습니다. 해당 원격 저장소의 연결을 제거하기 위해서 git remote remove <name> 옵션을 사용해 주시면 연결되어 있는 저장소를 간단하게 끊을 수 있습니다. 

$ git remote remove origin

 

이후 다시 -v 옵션을 통해 확인해 보면 연결된 원격 저장소가 없는 것을 확인 하실 수 있습니다.

 

 

다시 원격저장소와 연결하고 싶으실 경우엔 git remote add <name> <url> 옵션을 사용하시면 됩니다.

$ git remote add origin https://github.com/IfUwanna/Tool.git

 

이외에도 git remote 명령어는 아래와 같이 원격 저장소에 대한 다양한 관리 기능을 제공하니 참고해 주세요. 

NAME git-remote - Manage set of tracked repositories SYNOPSIS git remote [-v | --verbose] git remote add [-t <branch>] [-m <master>] [-f] [--[no-]tags] [--mirror=<fetch|push>] <name> <url> git remote rename <old> <new> git remote remove <name> git remote set-head <name> (-a | --auto | -d | --delete | <branch>) git remote set-branches [--add] <name> <branch>... git remote get-url [--push] [--all] <name> git remote set-url [--push] <name> <newurl> [<oldurl>] git remote set-url --add [--push] <name> <newurl> git remote set-url --delete [--push] <name> <url> git remote [-v | --verbose] show [-n] <name>... git remote prune [-n | --dry-run] <name>... git remote [-v | --verbose] update [-p | --prune] [(<group> | <remote>)...] DESCRIPTION Manage the set of repositories ("remotes") whose branches you track. OPTIONS -v, --verbose Be a little more verbose and show remote url after name. NOTE: This must be placed between remote and subcommand.

출처: https://ifuwanna.tistory.com/263 [IfUwanna IT]

출처: https://ifuwanna.tistory.com/263 [IfUwanna IT]

 

 



출처: https://ifuwanna.tistory.com/263 [IfUwanna IT]

+ Recent posts