모듈을 내보내거나 가져와서 사용할 때 자바스크립트에는 전통적, 현대적 방법 두가지가 존재한다.
오늘은 이들 각각의 export 부분에 대해서만 알아보도록 하겠다. 이유는 딱히 없고, 내가 헷갈려서....
ES6의 import / export 방식에서의 export. 하나의 파일에서 하나의 모듈만 내보내는 export default 방식와 여러개의 객체를 각각 내보내는 export 방법이 있다.
In practice, there are mainly two kinds of modules.
say.js
.user.js
exports only class User
.말인 즉슨 여러개의 함수나 변수를 패키징해서 내보내는 모듈이 있거나, 클래스와 같은 하나의 entity를 내보내는 모듈이 있다는 말이다.
Mostly the second approach is preferred, so that every 'thing' resides in its own module.
Modules provide a special export default
syntax to make the "one thing per module" way look better.
다시말하면 export default
는 모듈 하나에 하나의 기능만을 정의하는 것을 돕는 깔끔한 하나의 문법 이라고 볼 수 있을 것 같다.
export default
를 이용해서 익스포트 한 객체는 import할 때 curly braces를 씌우지 않고도 (아래 그림과 같이) 가져올 수 있다.
// 📁 user.js
export default class User { // just add "default"
constructor(name) {
this.name = name;
}
}
// 📁 main.js
import User from './user.js'; // not {User}, just User
new User('John');
보통 둘 중 하나의 방법(default를 쓰거나 / 안쓰거나)으로만 export하는 것이 맞다.
default 객체를 통한다면 이름 없는 객체를 내보낼 수도 있다.
export default function () {}
// 또는
export default class {
constructor () {}
}
// 또는
export default ['Jan', 'Feb'];
이름을 지어서 익스포트(반출)하는 것. named export 라 하는 듯 하다.
Named exports are explicit. They exactly name what they import, so we have that information from them; that's a good thing.
Named exports force us to use exactly the right name to import.
default를 사용해서 내보낼때와는 달리, import로 가져올 때 '정확히 그 이름으로만' 가능하다.
// User.js
export class User () {
...
};
// Main.js
import {User} from './user.js';
// import {MyUser} won't work, the name must be {User}
// 말하자면 export된 이름(여기에서는 User)으로만 import 해 올 수 있다.
While for a deafult export, we always choose the name when importing:
// User.js
export default class User () {
...
};
// Main.js
import User from './users.js'; // 가능하다
import MyUser from './user.js'; // 이것도 가능하다
암튼.
모듈에서 '하나만을' export할 때는 default 키워드를 사용할 수 있다.
default키워드와 함께 export한 모듈은 {}없이 임의의 이름으로 import한다.
// app.mjs
import square from './lib.mjs';
console.log(square(3)); // 9
module.exports
와 exports
를 구분해보자!
과정 없이 결과만 보자면..참고자료
자세하게는 뭐가 다른지 알고싶다면 아래 자료를 읽어보자. (아주 간결하고 명확하다)
module.exports vs exports - stack overflow
exports, module.exports
Both of them are referencees to the same object at the beginning. But only module.exports will be returned!
Whatever you do just keep in mind that module.exports
and NOT exports
will be returned from your module when you're requiring that module from somewhere else.
그니까 한마디로 module.exports와 exports는 똑같은 객체를 가리키지만 export되는 것은 module.exports 이다.
그러니까 이는 객체다. 따라서 만약
module.exports = function something () {
console.log('I got something..');
}
처럼 이에 함수를 할당한다면..
// user
var something = require('./somthing.js');
something();
과 같이도 사용할 수 있겠다.
exports
는 그저 외부에서 참조할 수 있는 module.exports
의 주소값을 가지고 있는 변수이기 때문에, 만일 exports에 이와 같은 함수를 할당한다면 module.exports
를 참조하는 바깥에서는 아무것도 참조 할 수 없고 그저 빈 객체만을 가져오게 된다.
위의 모든것들을 연습한 코드 샌드박스