Skip to content

Instantly share code, notes, and snippets.

@kiyeon
Last active March 10, 2018 00:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kiyeon/b9b11e17e1fbc8d0036a4437d64a54f3 to your computer and use it in GitHub Desktop.
Save kiyeon/b9b11e17e1fbc8d0036a4437d64a54f3 to your computer and use it in GitHub Desktop.
간단한 모듈 의존성 로더 매니져(클로저, 모듈 샘플 코드)
// Supporting AMD and CommonJS, and Plaintype.
(function(root, factory) {
if(typeof define !== 'undefined' && define.amd) {
// AMD loader type declaration.
define(['jquery', 'moment'], function(jquery, moment) {
factory(window, document, jquery, moment);
});
} else if(typeof module === 'object') {
var jsdom = require('jsdom').jsdom;
var _document = jsdom('<html></html>', {});
var _window = _document.defaultView;
var _jquery = require('jquery')(_window);
var _moment = require('moment');
module.exports = factory(_window, _document, _jquery, _moment);
} else {
root.pignoseCalendar = factory(window, document, jQuery, moment);
}
} (this, function (window, document, jquery, moment) {
// definition of the library.
});
MyModules.define("bar", [], function() {
function hello(who) {
return "Let me introduce: " + who;
}
return {
hello: hello
};
});
MyModules.define("foo", ["bar"], function(bar) {
var hungry = "hippo";
function awesome() {
console.log(bar.hello(hungry).toUpperCase());
}
return {
awesome: awesome
};
});
// 전역 오염을 피하기위해 get대신 require를 사용하도록 한다.
//var bar = MyModules.get("bar");
//var foo = MyModules.get("foo");
//console.log(bar.hello("hippo")); // Let me introduce: hippo
//foo.awesome(); // LET ME INTRODUCE: HIPPO
MyModules.require(["bar"], function(bar) {
console.log(bar.hello("hippo"));
});
MyModules.require(["foo"], function(foo) {
foo.awesome();
});
var MyModules = (function ModuleManager() {
var modules = {};
return {
define: function(name, deps, impl) {
if (arguments.length === 3) {
for (var i=0; i<deps.length; i++) { deps[i] = modules[deps[i]]; }
modules[name] = impl.apply(impl, deps);
} else {
modules[name] = deps();
}
},
require: function(deps, impl) {
if (arguments.length === 2) {
for (var i=0; i<deps.length; i++) { deps[i] = modules[deps[i]]; }
impl.apply(impl, deps);
} else {
deps();
}
}
};
}());
@kiyeon
Copy link
Author

kiyeon commented Mar 4, 2018

You Don't Know JS, p252에 클로저란 무엇이며 어떻게 활용할 수 있는지에 대한 예시를 일부 수정했다. MyModules는 싱글톤으로 생성되었고 define과 get을 갖는 간단한 구조의 모듈관리 객체다. 코드가 작성된 순간부터 MyModules의 클로저가 발생한다. 책에서처럼 클로저는 모든 곳에 존재한다. :) 이 코드는 클로저뿐 아니라 Client Side에서의 모듈을 어떻게 사용할 수 있는지에 대한 간단한 예시도 포함되어있다.(모듈관리자를 사용하는 이유는 전역을 오염시키지 않고 모듈화를 하기위해서다) 앱의 규모가 커질 수록 모듈 시스템이 필요한데 js는 ES6부터 지원한다. Server Side는 CommonJS를 사용하지만 Client Side는 선택의 폭과 방법이 다양하다. 마지막에 추가한 amd_commonjs_module_supports.js이곳을 참조했다. 의존성을 낮추기위해 AMD와 CommonJS, VanilaJS를 지원하는 방식의 예시다.

이 모듈 매니저는 굉장히 심플한 구조로되어있다. 하지만 사용하기에는 몇가지 단점이 존재한다.

  • 의존성에 따라 정의 순서를 맞춰줘야 한다. 예를 들어 b에서 a를 사용할경우 a가 먼저 정의되어있어야 한다. 순서가 바뀌면 "undefined"를 만나게 된다.
  • 외부 라이브러리를 등록하려면 해당 라이브러리를 모듈에 등록할 수 있게끔 일부 수정을 해야한다. 예를 들어 define하려면 jQuery나 undersocre 코드를 일부 수정해야 한다.

모듈 포스트

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment