Module

오민영·2021년 7월 16일
0

Javascript

목록 보기
5/6
post-thumbnail

기능 별로 각각 분리된 파일을 Module이라고 부른다.

특수한 지시자(export / import / exports / require)를 적용하면 다른 모듈에서 해당 모듈에 있는 함수를 호출하는 것과 같이 기능 공유가 가능하다.

module은 특수한 키워드나 기능과 함께 사용되기 때문에 <script type="module"> 와 같은 속성을 설정해서 해당 스크립트가 module이라는 걸 브라우저에 명시해야 한다.

<!doctype html>
  <script>
  	import { sample } from './sample.js';
	
	document.body.innerHTML = sample('John');
  </script>

module의 기능

'엄격 모드'로 실행됨

  • 'use strict'
  • 선언되지 않은 변수에 할당하는 등의 코드는 에러를 발생시킨다.
// error 출력
// sample-1
alert(user);
// 모듈은 변수를 공유하지 않기 때문에 `Uncaught ReferenceError: user is not defined`라는 에러가 콘솔 패널에 출력됩니다.

// sample-2
let user = "John";

// index.html
<script type="module" src="sample-1></script>
<script type="module" src="sample-2></script>

모듈 레벨 스코프

  • 모듈만의 스코프가 있어서 모듈 내부에 정의한 변수/함수는 다른 스크립트에 접근할 수 없다. 때문에 내보내는 모듈은 export를 해야하고, 가져오는 모듈은 import 해줘야 한다.
// sample-1
import { user } from './user.js';

alert(user);

// sample-2
export let user = "John";

<script type="module" src="sample-1"></script>

단 한번만 평가됨

  • 하나의 모듈이 여러 곳에서 사용되더라도, 최초 호출시 단 한번만 실행된다.
// alert.js
alert("모듈이 평가되었다");

// 1.js
import './alert.js'; // 모듈이 평가되었다!

// 2.js
import './alert.js'; // 아무일도 일어나지 않음.
// admin.js
export let admin = {}

export function sayHi(){
	alert(`${admin.name}님, 안녕하세요!`)
}

// init.js
import { admin } from './admin.js';

admin.name = "PePe"

// other.js
import {admin, sayHi} from './admin.js';

alert(admin.name); //PePe

sayHi(); // PePe님, 안녕하세요!

import.meta

  • 현재 모듈에 대한 정보를 제공해준다.
  • host 환경에 따라서 제공하는 정보의 내용은 다르지만, 브라우저 환경에서는 스크립트의 url 정보를 얻을 수 있다. HTML 안에 있는 모듈이라면, 현재 실행중인 웹 페이지의 url 정보를 얻을 수 있다.
<script type="module">
  alert(import.meta.url); // script URL (인라인 스크립트가 위치해 있는 html 페이지의 url)
</script>

this = undefined

  • 모듈 최상위 레벨의 this는 undefined이다
    • (Default 'window')

들어가기 전에 기본 정보

import VS require

두 개의 키워드 모두 하나에 파일에서 다른 파일의 코드를 불러온다는 동일한 목적을 가지고 있으나, 문법이 약간 다르다.

exports / require

  • NodeJS에서 사용되고 있는 CommonJS 키워드
// 모듈 내보내기
module.exports = foo;
exports.bar = bar

// 모듈 가져오기
const foo = require('./foo.js');
const bar = require('./bar.js').bar;

export / import

  • ES6에서 새롭게 도입된 키워드
export default foo;
export { bar };

import foo from './foo.js';
import { bar } from './bar.js';

require / exports

CommonJS 방식으로 모듈을 내보내는 경우, 명시적으로 선언하지 않고, 특정 변수나 그 변수의 속성을 내보낼 객체로 세팅해준다.

  1. exports
    - 여러 개의 객체를 내보낼 경우, exports 변수의 속성으로 할당한다.

  2. module.exports
    - 단 하나의 객체를 내보낼 경우, module.exports로 변수 자체를 할당한다.

복수 객체 내보내기 / 불러오기

내보내기
exports 변수의 속성으로 내보낼 함수를 세팅한다.

// currency-functions.js
const exchangeRate = 0.91

function roundTwoDecimals(amount){
  return Math.round(amout * 100) / 100;
}

const canadianToUs = function (canadian){
  return roundTwoDecimals(canadian * exchangeRate);
}

function usTocanadian(us){
  return roundTwoDecimals(us / exchangeRate);
}

exports.canadianToUs = canadianTouUs; // 내보내기 1
exports.usToCanadian = usToCanadian; // 내보내기 2

불러오기
내보낸 여러 개의 객체는 requrie 키워드를 통해 한 번에 불러와 변수에 할당할 수 있으면, 그 변수를 통해서 내보낸 객체에 접근이 가능하다.

const currency = require('./currency-functions.js');

console.log("50 Canadian dollars equals this amount of US dollars:");
console.log(currency.canadianToUs(50));

console.log("30 US dollars equals this amount of Canadian dollars:");
console.log(currency.usToCanadian(30));

단일 객체 내보내기 / 불러오기

내보내기
module.exports 변수에 할당해서 내보낸다.

// currency-class.js
const exchangeRate = 0.91;

// 안 내보냄
function roundTwoDecimals(amount) {
  return Math.round(amount * 100) / 100;
}

// 내보내기
const obj = {};

obj.canadianToUs = function (canadian) {
  return roundTwoDecimals(canadian * exchangeRate);
};
obj.usToCanadian = function (us) {
  return roundTwoDecimals(us / exchangeRate);
};

module.exports = obj;

불러오기
내보내기 하나의 객체는 require 키워드를 통해 변수에 할당할 수 있으며, 그 변수를 통해서 일반 객체에 접근하는 것 처럼 속성에 세팅되어 있는 함수에 접근할 수 있다.

const currency = require("./currency-object");

console.log("50 Canadian dollars equals this amount of US dollars:");
console.log(currency.canadianToUs(50));

console.log("30 US dollars equals this amount of Canadian dollars:");
console.log(currency.usToCanadian(30));

export / import

ES6 모듈 시스템이 최신 스팩이기 때문에 좋은 이점이 몇 가지 있다.

  • import / from / export / default 처럼 모듈 관리 전용 키워드를 사용하기 때문에 가독성이 좋다.
  • 비동기 방식으로 작동하고, 모듈에서 실제로 쓰이는 부분만 불러오기 때문에 성능과 메모리 부분에서 유리하다.
  1. export class User {...}
    - named export(복수객체)로, import { User } from '...' 으로 불러온다.

  2. export default class User {...}
    - default export(단일객체)로, import User from '...' 으로 불러온다.

복수 객체 내보내기 / 불러오기

모듈을 내보내고 불러올 때, import 키워드의 짝궁인 export 키워드를 사용해서 명시적을 선언한다.
이 때, 내보내는 변수나 함수의 이름이 그대로 불러낼 때 사용되기 때문에 Named Export라고 일컫는다.

내보내기
선언과 동시에 내보내거나, 선언 후에 별도로 내보낼 수 있다.

const exchangeRate = 0.91;

// 안 내보냄
function roundTwoDecimals(amount) {
  return Math.round(amount * 100) / 100;
}

// 내보내기 1
export function canadianToUs(canadian) {
  return roundTwoDecimals(canadian * exchangeRate);
}

// 내보내기 2
const usToCanadian = function (us) {
  return roundTwoDecimals(us / exchangeRate);
};
export { usToCanadian };

불러오기
여러 객체를 불러올 때는 ES6의 디스트럭처링 문법을 사용해서, 필요한 객체에만 선택적으로 전역에서 사용하거나 모든 객체에 별명을 붙이고 그 별명을 통해서 접근할 수도 있다.

// Destructuring
import { canadianToUs } from "./currency-functions";

console.log("50 Canadian dollars equals this amount of US dollars:");
console.log(canadianToUs(50));

// Alias
import * as currency from "./currency-functions";

console.log("30 US dollars equals this amount of Canadian dollars:");
console.log(currency.usToCanadian(30));

단일 객체 내보내기 / 불러오기

내보내기
하나의 모듈에서 하나의 객체를 내보내기 때문에, Default Export라고 일컫는다.

이름이 필요없기 때문에 별도로 변수 할당 없이, 바로 객체를 내보내기 할 수 있다. 내보낼 때 어떤 이름도 지정하지 않기 때문에 불러올 때도 아무 이름이나 사용할 수 있다.

const exchangeRate = 0.91;

// 안 내보냄
function roundTwoDecimals(amount) {
  return Math.round(amount * 100) / 100;
}

// 내보내기
export default {
  canadianToUs(canadian) {
    return roundTwoDecimals(canadian * exchangeRate);
  },

  usToCanadian: function (us) {
    return roundTwoDecimals(us / exchangeRate);
  },
};

불러오기
하나의 객체를 불러올 때는 간단하게 import 키워드를 사용해서, 아무 이름이나 원하는 이름을 주고 해당 객체를 통해 속성에 접근하면 된다.

import currency from "./currency-object";

console.log("50 Canadian dollars equals this amount of US dollars:");
console.log(currency.canadianToUs(50));

console.log("30 US dollars equals this amount of Canadian dollars:");
console.log(currency.usToCanadian(30));

Reference

참고
참고
참고

profile
이것저것 정리하는 공간

0개의 댓글