자바스크립트는 웹페이지의 단순한 보조 기능을 처리하기 위한 용도로 만들어진 언어이다. 본래는 import와 export를 지원하지 않는다. script로 여러 JS 파일들을 하나의 HTML에서 로드 하면, 모두 하나의 전역 객체를 공유한다. 즉 하나의 파일 내에 있는 것처럼 동작한다. 따라서 전역변수가 중복 될 수 있는 문제가 발생한다. 즉 자바스크립트에서는 표준 모듈 시스템을 제공하지 않았다.
// 모듈화 가 없을 때에는 모두 객체로서 처리
// 각 파일 별로 전역 공간을 지정하는 객체를 설정.
var NAMESPACE = NAMESPACE || {};
NAMESPACE.plus = funvtion(){}
Javascript Everywhere를 목적으로 한 자발적 워킹 그룹(Node.Js 이전)
// 파일을 분리하고 필요한 파일을 주입 받아 활용할 수 있게 한다.
// math.js
module.exports = {
sum: function (a, b) { return a + b; }
};
// sub1.js
const sum = require('./math.js').sum;
module.exports = {
plusTwo: function (a) { return sum(a, 2); }
}
// main.js
const plusTwo = require('./sub1.js').plusTwo;
console.log(plusTwo(10)); // 12
// main.js <- sub1.js <- math.js
장점
단점
script 파일 로딩시 blocking이 발생하는 브라우저 환경에서는 성능저하 발생.
이를 극복하기 위해 script 태그 동적 삽입 방식을 활용하나, 깔끔한 해결책이 될 수는 없다.
var myScript = document.createElement('script');
myScript.setAttribute('src', 'script.js');
myScript.setAttribute('crossorigin', 'anonymous');
myScript.setAttribute('async', '');
myScript.onload = function() {
}
document.getElementById('root').appendChild(myScript);
노드 JS에서는 파일 비동기 접근이 되어 그 순간에 바로 변수에 할당한다. 하지만 브라우저 환경에서는 그렇지 않다. 요청은 하지만 동기적으로 이루어지기에 해당 변수에는 undefined가 담기고 넘어간다. 이후 다운로드가 완료되면, 그때 추가 동작이 없기에 변수는 영원히 undefined이다.
// math.js 배열안에 필요한 의존성이 들어온다.
define([], function () {
function sum (a, b) { return a + b; }
return {
sum: sum
}
});
// sub1.js math는 math.js 에서 return한 sum 객체가 된다.
define(['math'], function (math) {
function plusTwo (a) {
return math.sum(a, 2);
}
return {
plusTwo: plusTwo
}
});
// main.js
require(['sub1'], function (sub) {
console.log(sub.plusTwo(10)); // 12
});