https://ko.javascript.info/modules-intro
모듈은 대개 클래스 하나 혹은 특정한 목적을 가진 복수의 함수로 구성된 라이브러리 하나로 구성된다.
모듈은 단지 파일 하나에 불과하며 스크립트 하나는 모듈 하나이다.
모듈 시스템 종류
위와 같은 모듈 시스템은 오래된 스크립트에서 여전히 존재하지만 사라지는 추세
모듈 시스템은 2015년 표준에 등재되어 이제는 대부분의 주요 브라우저와 Node.js가 모듈 시스템을 지원함
모듈은 특수한 키워드나 기능과 함께 사용되므로 <script type="module">
와 같이 속성을 설정해 해당 스크립트가 모듈이라는걸 브라우저에게 알려줘야 한다.
일반 스크립트와 모듈의 차이? (모든 호스트 환경에 공통으로 적용되는 모듈의 핵심 기능)
<script>
alert(this); // window
</script>
<script type="module">
alert(this); // undefined
</script>
nomodule
<script type="module">
alert("모던 브라우저를 사용하고 계시군요.");
</script>
<script nomodule>
alert("type=module을 해석할 수 있는 브라우저는 nomodule 타입의 스크립트는 넘어갑니다. 따라서 이 alert 문은 실행되지 않습니다.")
alert("오래된 브라우저를 사용하고 있다면 type=module이 붙은 스크립트는 무시됩니다. 대신 이 alert 문이 실행됩니다.");
</script>
브라우저 환경에서 모듈을 단독으로 사용하는 경우는 흔치 않다. 대개 웹팩과 같은 빌드 툴을 사용해 모듈을 번들링하여 프로덕션 서버에 올리는 방식을 사용한다.
빌드 툴의 역할
<script type="module">
에 넣을 주요 모듈(진입점 역할을 하는 모듈) 선택변수, 함수, 클래스 선언 시 맨 앞에 export 붙이면 내보내기 가능
마지막줄에 export { name1, name2 };
로도 내보내기 가능
클래스나 함수를 내보낼 땐 세미콜론을 붙이지 마세요.
클래스나 함수 선언 시, 선언부 앞에 export를 붙인다고 해서 함수 선언 방식이 함수 선언문에서 함수 표현식(function expression) 으로 바뀌지 않습니다. 내보내 지긴 했지만 여전히 함수 선언문입니다.
대부분의 자바스크립트 스타일 가이드는 함수나 클래스 선언 끝에 세미콜론을 붙이지 말라고 권유합니다.
같은 이유로 export class나 export function 끝에 세미콜론을 붙이지 않습니다.
as를 사용해 이름을 바꿔서 모듈을 내보낼 수 있음 가져올 수 있음
export {sayHi as hi, sayBye as bye};
이렇게 default를 붙여서 모듈을 내보내면 중괄호 {} 없이 모듈을 가져올 수 있습니다.
import User from './user.js';
export default
를 사용하면 '해당 모듈엔 개체가 하나만 있다’는 사실을 명확히 나타낼 수 있습니다. (default export가 아닌 경우엔 이름이 없어도 정상 동작하지만 그렇지 않으면 이름이 꼭 필요합니다.)
named export는 내보냈을 때 사용한 이름 그대로 가져오므로 관련 정보를 파악하기 쉽습니다. 그런데 아래와 같이 내보내기 할 때 쓴 이름과 가져오기 할 때 쓸 이름이 동일해야 한다는 제약이 있죠.
named export와는 다르게 default export는 가져오기 할 때 개발자가 원하는 대로 이름을 지정해 줄 수 있습니다.
import {login, logout} from './helpers.js'; export {login, logout};
// 동일
export {login, logout} from './helpers.js';
https://www.typescriptlang.org/docs/handbook/modules.html#umd-modules
import {...} from '경로';
로 가져오기 가능
import * as name from '경로';
로 가져와서 name.?? 로 접근도 가능
웹팩과 같은 모던 빌드 툴은 로딩 속도를 높이기 위해 모듈들을 한데 모으는 번들링과 최적화를 수행한다. 이 과정에서 사용하지 않는 리소스가 삭제되기도한다. 따라서 어떤 걸 가져올 땐 그 대상을 구체적으로 명시하는 게 좋다.
as를 사용해 이름을 바꿔서 모듈을 가져올 수 있음
import {sayHi as hi, sayBye as bye} from './say.js';
( require / exports ) 는 NodeJS에서 사용되고 있는 CommonJS 키워드이고 Ruby 언어 스타일과 비슷하다라고 볼수 있다.
Babel과 같은 ES6 코드를 변환(transpile)해주는 도구를 사용할 수 없는 상황에서는 좋든 싫든 require 키워드를 사용해야 합니다
CommonJS 방식으로 모듈을 내보낼 때는 ES6처럼 명시적으로 선언하는 것이 아니라 특정 변수나 그 변수의 속성으로 내보낼 객체를 세팅해줘야 합니다. 특히, 제일 햇갈리는 부분이 바로 유사해보이는 exports 변수와 module.exports 변수를 상황에 맞게 잘 사용해야 한다는 점입니다. 기본적으로 다음 2가지 규칙만 기억하시면 됩니다.
( import / export ) 는 ES6(ES2015)에서 새롭게 도입된 키워드로서 Java나 Python 언어 방식과 비슷하다.
차이점
/** export **/
export default module;
//혹은
export module;
/** import **/
import module from "module";
//혹은
import {module} from "module";
/** export **/
module.exports = module;
//혹은
exports.module = () => {};
/** import **/
const module = require("module");
//혹은
const {module} = require("module");
javascript에서 모듈화 시켜 나눠져있는 파일의 값을 내보내고 가져올 때 export, import, require 사용
export
: 모듈에서 함수, 객체, 원시값을 내보냄
exports
: 모듈에서 함수, 객체, 원시값을 객체의 형태로 내보냄
exports default
: 분리되어 있는 파일에서 하나의 고정된 값만 내보냄
export는 내보낼 변수 하나하나의 값을 선언하여 내보냄
exports는 exports 객체를 내보내므로 객체의 프로퍼티 형태로 내보냄
exports.xx ?
export default
=> import from '...' O / import { ** } from '...' X
exports.default
// import '@popperjs/core';
// import * as Popper from '@popperjs/core';
import { createPopper } from '@popperjs/core';