모듈
JavaScript는 파일마다 독립적인 스코프를 갖지 않고 전역 객체를 공유함
require
module.exports
module
exports
객체를 갖고 있음// a.js
const print = () => {
console.log('hello');
}
module.exports = {
print
};
// b.js
const func = require('./a.js');
func.print();
module.exports
와 exports
둘 다 사용 가능함module.exports
는 빈 객체를 참조함exports
는 module.exports
를 참조함require
는 항상 module.exports
를 반환함exports.print = print;
module.exports = { print };
exports
를 사용하는 이유exports
는 항상 module.exports
를 잠조하므로, exports
를 사용하면 module.exports
를 수정하지 않고 객체의 멤버를 만들거나 수정할 수 있음exports
에 어떤 값을 할당하더라도 require
는 module.exports
를 반환하기 때문에 잠재적인 버그를 피할 수 있음define()
, require()
<!DOCTYPE html>
<html lang="en">
<head>
<title>Document</title>
</head>
<body>
<script data-main="index.js" src="require.js"></script>
</body>
</html>
<script>
태그의 src
속성에 할당된 require.js 파일을 받음<script>
태그의 data-main
속성에 할당된 index.js가 실행됨require.config({
baseUrl: '/',
paths: {
a: 'a',
b: 'b',
}
});
require(['a'], (a) => {
a.printA();
});
define(() => {
return {
printA: () => console.log('a');
}
})
AMD와 CommonJS 모듈 구현 방식을 통합하기기 위해 만든 모듈 패턴
AMD, CommonJS, Browser 방식의 모듈을 지원
2개의 인자를 전달받는 함수를 실행함
root
에 넘길 값이 undefined
면 this
로, 아니면 window
로 설정함// UMD 소스 코드
(function (root, factory) {
if (typeof define === 'function' && define.amd) {
// AMD. Register as an anonymous module.
define([], factory);
} else if (typeof module === 'object' && module.exports) {
// Node. Does not work with strict CommonJS, but
// only CommonJS-like environments that support module.exports,
// like Node.
module.exports = factory();
} else {
// Browser globals (root is window)
root.returnExports = factory();
}
}(typeof self !== 'undefined' ? self : this, function () {
// Just return a value to define the module export.
// This example returns an object, but the module
// can return a function as the exported value.
return {};
}));
import
export
@babel/plugin-transform-modules-commonjs
를 통해 변환시켜서 사용함// module.A.js
const A = () => {};
export default A;
//moduleB.js
export const B = () => {};
//index.js
import A from 'moduleA';
import { B } from 'moduleB';
export
를 사용할 때, named export와 default export를 사용할 수 있음{}
로 묶어서 불어와야 함as
로 별칭을 주어서 다른 이름으로 사용 가능함*
와일드카드를 사용하여 한번에 불러오거나 내보낼 수 있음// foo.mjs
var x = 'foo';
var y = 1;
console.log(x); // foo
console.log(window.x); // undefined
// bar.mjs
var x = 'bar';
console.log(x); // bar
console.log(window.x); // undefined
console.log(y); // ReferenceError: x is not defined
// 변수
export const pi = Math.PI;
// 함수
export function square(x) {
return x * x;
}
// 클래스
export class Person {
constructor(name) {
this.name = name;
}
}
const pi = Math.PI;
function square(x) {
return x * x;
}
class Person {
constructor(name) {
this.name = name;
}
}
export { pi, square, Person };
import { pi, square, Person } from './lib.mjs';
console.log(pi); // 3.141592653589793
console.log(square(10)); // 100
console.log(new Person('Lee')); // Person { name: 'Lee' }
import * as lib from './lib.mjs';
console.log(lib.pi); // 3.141592653589793
console.log(lib.square(10)); // 100
console.log(new lib.Person('Lee')); // Person { name: 'Lee' }
import { pi as PI, square as sq, Person as P } from './lib.mjs';
console.log(PI); // 3.141592653589793
console.log(sq(2)); // 4
console.log(new P('Kim')); // Person { name: 'Kim' }
// lib.mjs
export default function (x) {
return x * x;
}
// lib.mjs
export default () => {};
// => OK
export default const foo = () => {};
// => SyntaxError: Unexpected token 'const'
// app.mjs
import square from './lib.mjs';
console.log(square(3)); // 9