쉽게 따라하는 모바일 웹 개발: jQuery Mobile부터 Node.js까지 예제
grunt 빌드를 통해 생성되는 프로젝트 결과물, 해당 디렉터리만 웹서버에 배포된다.
제이쿼리 모바일은 단일 페이지 애플리케이션 구조를 띠고 있다. 해당 페이지가 될 index.html의 body 부분이 저장돼있다.
현재 Grunt에서 사용 중인 assemble은 핸들바 템플릿을 사용 중이고, 이 핸들바 템플릿은 사용자 정의 헬퍼를 만들어 사용할 수 있다.
helper는 이러한 헬퍼를 저장해놓은 공간이다.
현 프로젝트의 <body>
요소 안의 여러 개의 페이지가 기능별로 총 6개의 페이지로 구성돼 있는데, 이뿐만 아니라 각 페이지별로 공통으로 사용되는
footer, toolbar, 위젝, script 태그, css 링크 등의 파일도 별도로 나눠져 있다.
index.html의 구조가 저장되어 있다. 기본 doctype, html, head, meta 태그가 저장된 파일이 저장되는 폴더라고 보면 된다.
해당 프로젝트를 구성하기 위한 css, img, js 파일이 저장된다. Grunt로 빌드되면 dist 디렉터리에 복사된다.
Grunt를 통해 프로젝트의 빌드를 수행한다. 이를 위해 Grunt의 설정 및 실행에 대한 내용이 저장되어 있는 파일이고 이 파일이 있어야 Grunt가 실행된다.
본 프로젝트는 Grunt와 assemble을 통해 index.html 파일이 생성된다. 이때 data.json에 저장된 데이터를 참조하는데, 청첩장의 특성상 신부/신랑 소개, 결혼식장 위치, 환영 문구, 이미지 경로 등 변경하기 쉽게 해당 정보를 JSON 형태로 선언해 놓았다. 이 JSON 정보를 변경하면 내용이 전혀 다른 청첩장 파일을 생성할 수 있다.
Grunt는 Node.js 기반으로 만들어진 도구이다. Grunt에서 사용 중인 여러 모듈이 npm 기반으로 배포돼 있고, Grunt에서도 이것을 사용한다.
모든 Node.js 기반 프로젝트는 package.json 파일을 포함하고 있다. 해당 파일을 통해 의존성 관리 및 배포 정보를 관리한다.
$ npm install
$ grunt
CategoryInfo: ObjectNotFound: (axios:String) [], CommandNotFoundExce ption
$ npm install -g grunt-cli
$ grunt
$ grunt dev
http://localhost:8080
이라는 내부 웹서버를 실행하며, 해당 URL로 접속하면 프로젝트를 확인할 수 있다.
확장자는 html이 아니고 hbs이다. 그 이유는 assemble에서 템플릿 엔진으로 핸들바를 사용하기 때문. 이 hbs 파일이 assemble과 Grunt 빌드를 통해 HTML로 완성된다.
// layout/default.hbs
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>{{user.groom}} {{user.brider}}의 Wedding Invitation by using jQuery Mobile</title>
{{>css}}
</head>
<body>
<div id="fb-root"></div>
{{>body}}
{{>script}}
</body>
</html>
...
assemble: {
options: {
helpers: [ 'helper/common.js' ]
},
build: {
options: {
layoutdir: 'layout',
layout: 'default.hbs',
partials: 'includes/*.hbs',
data: 'data.json'
},
files: [{
expand: true,
cwd: 'docs',
src: '*.hbs',
dest: 'dist'
}]
}
...
// docs/index.hbs
{{>main}}
{{>album1}}
{{>album2}}
{{>propose}}
{{>location1}}
{{>location2}}
제이쿼리 모바일은 페이지 기반의 단일 페이지 애플리케이션이다. 즉, 6개의 페이지로 이루어진 애플리케이션이다.
...
<h1 class="text-header">
{{user.groom}} <b style="color:red">❤</b> {{user.brider}} 의 결혼식
</h1>
...
{{user.groom}}은 data.json에 저장돼 있는 user 객체의 값을 참조한다.
여기서 중요한 것은 해당 템플릿의 {{user.groom}}을 변경하지 않으면 data.json의 user.groom객체의 키 값도 변경하면 안 된다는 것이다. 대신 user.groom의 value는 언제든지 변경할 수 있다.
// resources/main.js
window.mySwipe = new Swipe( elem, {
startSlide: 0,
speed: 500,
auto: 1000,
continuous: true,
disableScroll: false,
stopPropagation: false,
callback: function(index, elem) {},
transitionEnd: function(index, elem) {}
});
var $slider = $( "#slider" ),
$prev = $( "#prevButton" ),
$next = $( "#nextButton" );
$prev.off( "click" ).on( "click", function(){
mySwipe.prev();
});
$next.off( "click" ).on( "click", function(){
mySwipe.next();
});
// 애플리케이션 키, data.json
"application" : {
"tmapAppKey": "59d44673-37a8-3d41-a7b6-6ca3c6ea061f"
}
// resources/main.js
...
var initLocation = function() {
var map = new Tmap.Map({
div:"map1",
width:'100%',
height:'400px'
});
var markerLayer = new Tmap.Layer.Markers();
map.addLayer( markerLayer );
var lonlat = new Tmap.LonLat( 14127736.0000893, 4511715.2883089 );
//var center = new Tmap.LonLat( 14123343.752289, 4512189.739492 );
map.setCenter( lonlat, 16 );
var size = new Tmap.Size(30,30);
var offset = new Tmap.Pixel(-(size.w/2), -(size.h/2));
var icon = new Tmap.Icon('./resources/img/heart.png', size, offset);
var marker = new Tmap.Marker(lonlat, icon);
markerLayer.addMarker(marker);
};
...
// resources/js/main.js
<div>
<a href="javascript:;" id="kakao-link">
<img class="kakaolink" src="./resources/img/kakao_talk.png"
width="100%" alt="카카오 톡으로 청첩장 보내기" />
</a>
</div>
// 카카오 연동
ar initKakao = function(){
/* kakao톡 링크 */
Kakao.cleanup();
// 사용할 앱의 Javascript 키를 설정해 주세요.
Kakao.init('abeaf346736c57a8ba07ef2dcfcad028');
// 카카오톡 링크 버튼을 생성합니다. 처음 한번만 호출하면 됩니다.
Kakao.Link.createTalkLinkButton({
container: '#kakao-link',
label: '저희의 결혼을 축하해주세요',
image: {
src: 'http://dev.kazikai.net/invitation/dist/resources/img/main.png',
width: '300',
height: '200'
},
webButton: {
text: '청첩장 바로가기',
url: 'http://dev.kazikai.net/invitation/dist/index.html'
// 앱 설정의 웹 플랫폼에 등록한 도메인의 URL이어야 합니다.
}
});
};
...
// 카카오 연동 함수 실행
initKakao();
...