Require.js

Require.js란

requirejs는 자바스크립트 코드들을 모듈화 관리가 가능한 프레임워크 이며, AMD(Asynchronous Module Definition) 모듈 로딩 표준을 따르기에 기본적으로 모든 모듈을 비동기적으로 처리한다. 또한 자바스크립트 모듈의 의존관계등의 관리도 쉽게 할수 있게 도와준다.

모듈 정의와 사용

모듈을 정의하는 기본 형태는 다음과 같다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
-js/foo.js
// 모듈 정의의 기본 형태
define([ // 의존 모듈들을 나열한다. 모듈이 한 개라도 배열로 넘겨야 한다.
'js/util',
'js/Ajax',
'js/Event'
], function (util, Ajax, Event) { // 의존 모듈들은 순서대로 매개변수에 담긴다.
// 의존 모듈들이 모두 로딩 완료되면 이 함수를 실행한다.
// 초기화 영역
var i = 0;

function increase() {
i++;
}

function get() {
return i;
}

// 외부에 노출할 함수들만 반환한다.
return {
increase: increase,
get: get
};
});

-js/main.js
require([
'js/foo'
], function (foo) {
console.log(foo.get()); // 0
foo.increase();
console.log(foo.get()); // 1
});

모듈의 이름을 명시적으로 설정할 수도 있지만 이름 없는 모듈로 정의하는 것을 권장한다. 이름 없는 모듈은 호출될 때 모듈의 위치에 따라 이름을 결정한다. 개발할 때 파일의 이름이나 위치는 자주 변경되므로 유연한 상태로 둘 필요가 있다.

설정 옵션

require.js는 여러 설정 옵션들을 제공한다. 대표적인 옵션은 다음과 같다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<script>
// RequireJS 설정 객체
// require.js가 로딩되면 이 객체를 자동으로 읽어 들여 반영한다.
var require = {
baseUrl: '/js/app',
paths: {
'lib': '../lib' // "/js/lib" 과 동일하다. baseUrl 기준
},
shim: {
'modernizr': { // Modernizr 라이브러리
exports: 'Modernizr'
}
},
urlArgs : 'ts=' + (new Date()).getTime()
};
</script>
<script src="/js/lib/require.js"></script>
<script>
// code...
</script>

var require = {}; 설정은 require.js 파일의 로딩 전에 사용하는 방법 이다.
require.js 파일을 로딩한 후에는 require.config() 함수를 사용하여 설정할 수 있다.

모듈 위치

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/* /index.html */
<script>
var require = {
baseUrl: '/js/app'
};
</script>
<script src="/js/lib/require.js"></script>
<script>
require([
'common/relative', // (1) 위치: "/js/app/common/relative.js"
'dotjs.js', // (2) 위치: "/dotjs.js"
'/js/lib/absolute.js', // (3) 위치: "/js/lib/absolute.js"
'http://another.com/foo.js' // (4) 위치: "http://another.com/foo.js"
], function (relative, dotjs, absolute, foo) {
// code...
});
</script>

(1)의 경우가 일반적인 사용이며, (2), (3), (4)는 특별한 경우가 아니면 사용할 일이 없지만 알아 둘 필요는 있다.
(2)의 경우 baseUrl이 설정을 무시하고 현재 페이지의 경로를 사용한 결과이다. (3), (4)는 절대 경로로 이름을 지정한 경우이며 꼭 이름의 뒤에 ‘.js’를 붙여야 한다.

모듈이 아닌 외부 라이브러리 사용

AMD를 지원하지 않는 외부의 좋은 라이브러리를 사용하려면 paths와 shim 설정 옵션을 사용한다. 외부 라이브러리를 모듈처럼 사용할 수 있게 한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
-config.js
requirejs.config({
// 모듈의 기본 위치를 지정한다.
baseUrl: 'vendor',

// 모듈의 단축 경로 지정 또는 이름에 대한 별칭(Alias)을 지정할 수 있다.
// ".js"는 자동 추가
paths: {
app: '../app',
// 배열로 선언시 첫번째 파일 로드 실패 시 두번째 파일을 로드한다.
jquery: [
'https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min',
'jquery/dist/jquery.min'
],
underscore: [
'https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min',
'underscore/underscore-min'
],
text: [
'https://cdnjs.cloudflare.com/ajax/libs/require-text/2.0.12/text.min',
'text/text'
],
backbone: [
'https://cdnjs.cloudflare.com/ajax/libs/backbone.js/1.3.3/backbone-min',
'backbone/backbone-min'
],
bootstrap: [
'https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-alpha.6/js/bootstrap.min',
'bootstrap/dist/js/bootstrap.min'
]
},

// 타임스탬프
// 모듈 위치 URL뒤에 덧붙여질 쿼리를 설정한다.
// 개발 환경에서는 브라우저 캐시를 회피하기 위해 사용할 수 있고,
// 실제 서비스 환경이라면 bust값을 배포한 시간으로 설정하여 새로 캐시하게 할 수 있다.
//urlArgs: 'bust=' + (new Date()).getTime(),

// 타이머 지연(타이머 관련 에러시 대처)
//waitSeconds: 200,

// AMD를 지원하지 않는 외부 라이브러리를 모듈로 사용할 수 있게 한다. ex) modernizr
// jQuery의 경우 paths 설정만으로 사용 가능한 이유는 jQuery가 사실 AMD를 지원하기 때문이다.
// jQuery 소스의 마지막 부분을 살펴보면 define으로 모듈을 반환하는 코드를 볼 수 있다.
shim: {
/*jquery: {
exports: '$'
},
underscore: {
exports: '_'
},
text: {
deps: ['underscore'],
exports: 'text'
},
backbone: {
deps: ['jquery', 'underscore'],
exports: 'Backbone'
},*/
bootstrap: {
deps: ['jquery']
}
}
});

// Load the main app module to start the app
requirejs(['app/main']); // 여기서 app은 상단의 paths.app 의 프로퍼티 값의 경로를 뜻한다.
1
2
3
4
5
6
7
8
9
10
11
-app/main.js
require([
'jquery',
'underscore',
'backbone',
'text!/backbone/header.html',
'text!/backbone/home.html',
'text!/backbone/footer.html'
], function($, _, Backbone, headerTempl, homeTempl, footerTempl) {
// code...
});

참조

공유하기