JavaScript 모듈화 및 Lazy Loading 으로 쓰이는 기술, AMD에 대해 간단히 알아보자
동적로딩(Dynamic Loading, Lazy Loading)
- HTML 파일 로딩시에 <script> 태그내의 내용이 모두 로딩되기전까지 html 이 파싱되지 않고 기다리고 있어서 페이지의 랜더링이 늦어진다.
- 꼼수로 <body> 태그의 마지막에 <script> 태그를 배치하여 UI 랜더링이후 <script> 내용을 읽는 방법이 있다.
- 동적로딩은 필요할 경우에만 <script> 내용을 동적으로 로딩하는 방법으로, Eclipse 의 plug-in 시스템과 비슷한 맥락의 방법이다.
- 동적로딩은 여러 방법이 있지만 <script> 태그를 동적으로 만들어서 헤더태그의 제일 마지막에 삽입하는 방법이 많이 쓰인다.
- 예제
-
<!-- index.html --!> <html> <head> <title>Test</title> <script src="js/main.js"></script> </head> <body> <button onclick="test()">Lazy Loading</button> </body> </html>
-
// main.js function test() { var scriptElement = document.createElement('script'); scriptElement.type = 'text/javascript'; scriptElement.src = 'js/lazy.js'; scriptElement.onload = function(script) { console.log('script lodaed!'); }; document.getElementsByTagName('head')[0].appendChild(scriptElement); }
-
// lazy.js function lazy() { alert('lazy'); }
- 실행결과
- Lazy Loading 버튼을 클릭하기 전에는 lazy.js 가 로딩되지 않았지만, 버튼을 클릭하면 lazy.js 가 로딩이된다.
History
- JavaScript 모듈화에 대한 명세를 정의하는 표준화 정의 그룹으로 CommonJS 그룹이 있고, 여기서 신설된 AMD 라는 그룹이 새로 생김
- JavaScript 모듈화의 목표
- 모듈화
- 외부에서 쉽게 사용가능
- Lazy Loading
- 필요할때에 로딩 가능
- JavaScript 에 대한 모듈정의
- 스코프(Scope): 모든 모듈은 자신만의 독립적인 실행 영역이 있어야 한다.
- 정의(Definition): 모듈 정의는 exports 객체나 define 함수를 이용
- 사용(Usage): 모듈 사용은 require 함수를 이용
CommonJS(CJS)
- http://www.commonjs.org/
- exports
- 모듈 정의
- require()
- 모듈 사용
- 예제
//--------------------------------------------- // test.js // export 할 모듈 정의 function test(){ this.first = function(){ console.log('first'); } this.last = function(){ console.log('last'); } } // 모듈 export exports.test = test; //--------------------------------------------- // main.js var test = require('./test').test; var module = new test(); module.first(); // 'first' module.last(); // 'last'
AMD
- https://github.com/amdjs/amdjs-api/blob/master/AMD.md
- define()
- 모듈 정의
- CommonJS 의 exports 와 같은 개념
- Signature
-
define( module_id /*optional*/, [dependencies] /*optional*/, definition function /*function for instantiating the module or object*/ );
- module_id
- 모듈 이름
- dependencies
- 모듈이 갖는 의존성 모듈(먼저 로드되어야 하는 모듈)의 배열
- 기술된 모듈은 definition function 의 인자로 순서대로 전달된다.
- 예제
-
//--------------------------------------------- // test.js // 모듈정의 define([ 'js/jquery.js', // 의존성을 가지는 모듈들을 기술 'js/my.js' ], function(jQuery, my) { // 의존성을 가지는 모듈들이 순서대로 매개변수로 담김 // 의존 모듈들이 모두 로딩 완료되면 함수를 실행 function first() { console.log('first'); } function last() { console.log('last'); } return { first: first, last: last }; } );
- require()
- 모듈사용
- 예제
-
//--------------------------------------------- // main.js require([ 'js/test.js' ], function(test) { test.first(); // 'first' test.last(); // 'last' } );
RequiredJS
- RequireJS implements the AMD API
- 지원하는 프레임웍
- Dojo (1.7), MooTools (2.0), Firebug (1.8), jQuery (1.7).
- Requried JS
- define과 require의 차이점은?
- define 은 모듈을 등록하여 export 할 경우 사용
- require 는 기존 모듈을 사용하여 비지니스 로직을 구성할 경우 사용
- require 함수에서는 새로운 모듈구현을 return 할수 없다.
- http://stackoverflow.com/questions/9507606/when-to-use-require-and-when-to-use-define
- define에서 기술된 모듈이 순서가 중요한 경우(의존성 관계)
- define 에 기술된 모듈은 asynchronous 하게 병렬적으로 로딩되는데 AMD 를 지원한다면 자체적으로 관련 모듈에 대한 dependecy 에 대한 모듈이 로딩되고 factroy 함수가 실행된다.
- define 에 기술된 모듈이 AMD 를 지원하지 않고 순서를 갖는 경우, 가령 define dependency 에 jquery ui, jquery 가 순서가 다르게 되있어 로딩순서가 중요한 경우 shim 설정으로 모듈간의 디펜던시를 기술
- Example jquery shim
-
requirejs.config({ "shim": { "jquery.ui": ["jquery"] } });
References
- GitHub AMD Document
- https://github.com/amdjs/amdjs-api/blob/master/AMD.md
- JavaScript 표준을 위한 움직임 CommonJS와 AMD
- http://helloworld.naver.com/helloworld/textyle/12864
- RequireJS - AMD의 이해와 개발
- http://helloworld.naver.com/helloworld/591319
- Writing Modular JavaScript With AMD, CommonJS & ES Harmony
- http://addyosmani.com/writing-modular-js/
- Stackoverflow: Relation between CommonJS, AMD and RequireJS?
- http://stackoverflow.com/questions/16521471/relation-between-commonjs-amd-and-requirejs
- AMD: The Definitive Source
- http://www.sitepen.com/blog/2012/06/25/amd-the-definitive-source/
'Web' 카테고리의 다른 글
[Chrome] Debugging Asynchronous JavaScript (0) | 2015.12.21 |
---|---|
Gravatar (0) | 2015.08.26 |
[WIDLPROC] widl 을 widlprocxml 파일로 변환하기 (0) | 2015.01.15 |
Concurrency Programming of Web (0) | 2014.11.27 |
[Chrome] Your profile could not be opened correctly (0) | 2014.10.24 |