-
[Node.js] module.exports 와 exports 차이언어/Node.js 2024. 4. 20. 15:34
결론부터 말씀 드리면 module.exports 와 exports 는 사실상 같은 동작을 합니다.
- exports 객체는 module.exports의 단축형태입니다.
- exports가 module.exports의 객체를 call by reference 방식으로 바라보고 있으며, 최종적으로 리턴값은 module.exports라는 것이다.
- export는 property(속성을 내보내는) 방식으로 사용
- module.exports는 바로 사용 가능
call by reference 방식이란?
프로그래밍 언어에서 사용되는 개념 중 하나로, 함수에 인수를 전달하는 방법을 설명하는 용어이다.
call by reference에서는 함수에 인수로 변수의 메모리 주소(참조)를 전달합니다. 이는 원래 변수의 값을 변경할 수 있게 합니다. 따라서 함수 내에서 해당 변수의 값을 변경하면 호출된 함수 외부에서도 변경된 값을 확인할 수 있습니다.
*인수란 함수에 전달되는 값으로, 함수가 호출될 떄 함수 내부로 전달됩니다.
// 인수 설명 function add(a, b) { return a + b; } let result = add(3, 5); // 함수 add를 호출하면서 인수 3과 5를 전달함 console.log(result); // 출력: 8
여기서 매개변수와 인수를 헷갈릴 수 있는 데, 매개변수와 인수는 함수를 호출할 때의 변수와 값에 해당한다.
따라서 여기서는 a,b 는 매개변수 3,5는 인수에 해당한다.
*참조란(reference) 메모리 상의 어떤 위치를 가리키는 값입니다. 프로그래밍에서 변수는 값이 아닌 메모리 위치를 참조하며, 이를 통해 변수는 해당 메모리 위치에 저장된 값을 참조하게 됩니다.
// 예시 let a = 5; let b = a; // 변수 b는 변수 a의 값을 참조합니다. console.log(b); // 출력: 5 a = 10; console.log(b); // 출력: 5 (변수 b는 변수 a의 값을 복사하여 참조하고 있으므로 변수 a의 변경은 변수 b에 영향을 주지 않습니다.)
그래서 어떻게 쓰라고?
exports
// exports 사용 예시 // 모듈 파일: math.js // add 함수와 multiply 함수를 exports 객체에 할당 function add(a, b) { return a + b; } function multiply(a, b) { return a * b; } exports.add = add; exports.multiply = multiply;
위의 코드에서는 'add' 함수와 'multiply' 함수를 exports 객체에 할당하여 내보냅니다. 이 모듈을 가져올 때는 여러 함수를 포함한 객체를 가져올 수 있습니다.
// 다른 파일에서 모듈을 가져옴 const math = require('./math.js'); console.log(math.add(2, 3)); // 출력: 5 console.log(math.multiply(2, 3)); // 출력: 6
그냥 exports =add; 하면 안될까?
- exports는 객체 참조를 가리킵니다: exports는 실제로 객체를 가리키는 변수입니다. 따라서 exports가 가리키는 객체를 변경하면 모듈의 외부에서 해당 객체에 대한 참조를 잃을 수 있습니다.
- module.exports와 exports의 관계: exports는 module.exports의 참조를 가리킵니다. module.exports는 실제로 내보낼 값이 담긴 객체를 가리키며, exports는 이 객체를 간편하게 접근하기 위한 단축키입니다.
따라서 exports = add;를 사용하면 exports는 새로운 객체인 add를 가리키게 됩니다. 하지만 이는 module.exports와는 별개의 객체를 가리키게 되므로, exports를 통해 내보낸 것은 무시됩니다. 모듈 시스템은 module.exports가 가리키는 객체를 사용하여 모듈을 내보내기 때문에, exports에 할당된 값은 무시되고, module.exports가 가리키는 객체만이 실제로 모듈로 내보내집니다.
따라서 exports 객체의 속성(property)을 추가하여 내보내는 것이 바람직합니다. 예를 들어, exports.add = add;와 같이 사용하는 것이 적절합니다.
module.exports
// modul.exports // 모듈 파일: math.js // add 함수를 직접 module.exports에 할당 function add(a, b) { return a + b; } module.exports = add;
위의 코드에서는 add 함수를 직접 module.exports에 할당하여 내보냅니다. 이 모듈을 가져올 때는 해당 함수만 가져올 수 있습니다.
// 다른 파일에서 모듈을 가져옴 const add = require('./math.js'); console.log(add(2, 3)); // 출력: 5
그러면 아래 코드는 될까?
// 모듈 파일: math.js // add 함수와 multiply 함수를 exports 객체에 할당 function add(a, b) { return a + b; } function multiply(a, b) { return a * b; } module.exports = add; module.exports = multiply;
// 다른 파일에서 모듈을 가져옴 const math = require('./math.js'); console.log(math.add(2, 3)); // 출력: 5 console.log(math.multiply(2, 3)); // 출력: 6
작동하지 않는다. 이유는 module.exports에 값을 할당할 때, 이전에 할당된 값은 덮어씌워지기 때문이다.
즉, module.exports에 두 번 할당하는 것은 두 번째 할당문이 첫 번째 할당문을 덮어씌우게 되어 첫 번째 할당문이 무시되기 때문이다.
따라서 위의 코드에서 module.exports = multiply;가 실행되면, module.exports는 multiply 함수를 가리키게 되고, 이전에 할당된 add 함수에 대한 참조는 사라지게 됩니다.
그러므로 위의 코드는 multiply 함수만을 내보내게 됩니다. add 함수는 내보내지 않습니다.
만약 add와 multiply 함수를 모두 내보내고 싶다면, 객체를 사용하여 다음과 같이 할 수 있습니다.
// 모듈 파일: math.js // add 함수와 multiply 함수를 객체로 묶어서 내보냄 function add(a, b) { return a + b; } function multiply(a, b) { return a * b; } module.exports = { add, multiply };
// 다른 파일에서 모듈을 가져옴 const math = require('./math.js'); console.log(math.add(2, 3)); // 출력: 5 console.log(math.multiply(2, 3)); // 출력: 6
번외
근데 여기서 module.export의 성질을 이용해서 장난쳐보자.
아래는 작동할까?
function add(a, b) { return a + b; } function multiply(a, b) { return a * b; } module.exports = add; module.exports = multiply;
// 다른 파일에서 모듈을 가져옴 const math = require('./math.js'); console.log(math.multiply(2, 3));
두 번 할당 하는 경우에 두 번째 할당문이 첫 번째 할당문을 덮어씌우게 된다고 했다,
그러면 다른 파일에서
const math = require('./math.js');
console.log(math.multiply(2, 3));
하게 되면 제대로 작동할까?
안된다. TypeError: math.multiply is not a function과 같은 오류가 발생한다.
참고한 블로그 : NODE JS - 모듈이란? , module.export 와 exports의 차이 :: 아빠개발자의 노트 (tistory.com)
도움 : chat gpt
'언어 > Node.js' 카테고리의 다른 글
[데이터베이스] address already in use ::: (0) 2024.05.22 "데이터베이스 연결 설정: 127.0.0.1 vs. localhost, 어떤 것을 선택해야 할까?" (0) 2024.05.22 [Node.js] 돌아가기만 하면 되는 거 아닌가? (1) 2024.04.20 [Node.js] 'TypeError: Invalid URL' 오류 해결하기 (1) 2024.04.18 [Node.js] Node.js 설치 후 일어날 수 있는 오류 (0) 2024.04.18