Total: Today: Yesterday:
연구소/이것저것 | 2016. 4. 18. 22:01 | Posted by 자수씨


최근에 나오는 라이브러리를 보면 ```"use strict"``` 라는 문구가 자주 보입니다.


strict 미국·영국 [strɪkt]

1. (규칙 등이) 엄격한

2. (사람이 남에 대해) 엄격한

3. (사람이 자신의 종교・신념 등에 대해) 엄격한


- 네이버 어학사전


사전에서 볼 수 있듯이 무언가 엄격하게 사용한다는 의미로 생각이 되는데, 간단하게 알아보려 합니다.



#h3 strict 모드의 정의


strict 모드로 설정하는 방법은 간단합니다. 코드 앞쪽에 ```"use strict"``` 를 추가하는 것 입니다.

### js


"use strict";

x = 3.14;       // This will cause an error (x is not defined)

위의 예제를 실행하면 콘솔 창에 아래와 같은 오류가 찍히게 됩니다.


Uncaught ReferenceError: x is not defined


정의가 되지 않은 x 로 인해 정상적으로 동작을 하지 않습니다.


### js


"use strict";

myFunction();


function myFunction() {

    y = 3.14;   // This will also cause an error (y is not defined)

}

위의 예제도 y 가 정의되지 않아 정상적으로 실행되지 않습니다.




### js


x = 3.14;       // This will not cause an error. 

myFunction();


function myFunction() {

   "use strict";

    y = 3.14;   // This will cause an error (y is not defined)

}

위의 예제는 x 가 사용되기 전에는 ```"use strict"``` 가 선언되지 않았으므로 y 에 대해서만 오류가 발생합니다.



#h3 왜 strict 모드를 사용하는가?


"보안" 자바스크립트를 작성하는 쉬운 방법이기 때문입니다. 다른 이유는 "올바르지 않은 문법" 을 사전에 검출할 수 있습니다.


strict 모드는 쓰기금지 프로퍼티의 정의, getter 전용 프로터피, 존재 하지 않는 프로퍼티, 존재하지 않는 변수, 존재하지 않는 객체에 대해 에러를 발생시킵니다.



#h3 strict 모드에서 허용되지 않는 문법


1. 정의되지 않은 변수의 사용

### js


"use strict";

x = 3.14;                // This will cause an error (x is not defined)

### js


"use strict";

x = {p1:10, p2:20};      // This will cause an error (x is not defined)


2. 변수나 객체의 삭제

### js


"use strict";

var x = 3.14;

delete x;                // This will cause an error


3. 함수 파라미터에 중복된 이름

### js


"use strict";

function x(p1, p1) {};   // This will cause an error


4. 8진수

### js


"use strict";

var x = 010;             // This will cause an error


5. 이스케이프 문자

### js


"use strict";

var x = \010;            // This will cause an error


6. 읽기전용 프로퍼티에 값 설정

### js


"use strict";

var obj = {};

Object.defineProperty(obj, "x", {value:0, writable:false});


obj.x = 3.14;            // This will cause an error


7. 조회 전용 프로퍼티에 값 설정

### js


"use strict";

var obj = {get x() {return 0} };


obj.x = 3.14;            // This will cause an error


8. ```eval```, ```arguments``` 문자열에 대한 변수로의 사용

### js


"use strict";

var eval = 3.14;         // This will cause an error

var arguments = 3.14;    // This will cause an error


9. ```with``` 사용

### js


"use strict";

with (Math){x = cos(2)}; // This will cause an error


10. ```eval()``` 에 정의된 변수 사용

### js


"use strict";

eval ("var x = 2");

alert (x);               // This will cause an error



#h3 References

http://www.w3schools.com/js/js_strict.asp

연구소/이것저것 | 2016. 4. 18. 15:12 | Posted by 자수씨

이전 포스팅에서는 너무 무지한 상태에서 쓰다보니 다시 봐도 이해가 안되는 듯 하여 쉬운 예제를 통해 정리해보겠습니다.


기존에 promise 패턴이 아닌 callback 방식의 경우에는 아래와 같이 코딩을 하였습니다.

### js


$.ajax({

  url: "/ServerResource.txt",

  success: successFunction,

  error: errorFunction

});


대부분 함수의 파라미터 객체에 function 을 설정하여 결과에 대한 처리를 했습니다. 이러한 경우 callback 이 중첩되어 소스의 가독성도 떨어질 뿐더러 관리가 안되는 단점이 있었습니다.



jQuery 1.5 버전 이후부터는 아래와 같이 ```done()```, ```fail()```, ```always()``` 를 이용하여 결과에 대한 처리를 지정합니다.

### js


var promise = $.ajax({

  url: "/ServerResource.txt"

});

  

promise.done(successFunction);

promise.fail(errorFunction);

promise.always(alwaysFunction);


```jQuery.ajax()``` 는 ```jQuery XMLhttpRequest(jqXHR)``` 을 반환하기 때문에 아래와 같은 방식으로도 구현이 가능합니다.

### js


$.ajax( "example.php" )    

    .done(function() { alert("success"); })    

    .fail(function() { alert("error"); })    

    .always(function() { alert("complete"); }); 


체인 방식이 아니더라도 jqXHR 객체에 직접 지정도 가능합니다.

### js


var jqxhr = $.ajax( "example.php" )    

    .done(function() { alert("success"); })    

    .fail(function() { alert("error"); })    

    .always(function() { alert("complete"); }); 

     

    // perform some work here ... 

     

    // Set another completion function for the request above

    jqxhr.always(function() { alert("another complete"); });



jQuery 1.8 버전 이후부터는 ```then()``` 함수를 사용하여 Promise 패턴을 적용할 수 있습니다.

```then()``` 의 첫번째 인자는 성공에 대한 액션, 두번째 인자에는 실패에 대한 액션을 지정할 수 있습니다.

### js


$.ajax({url: "/ServerResource.txt"}).then([successFunction1, successFunction2, successFunction3], 

                                          [errorFunction1, errorFunction2]);

 

//same as

 

var jqxhr = $.ajax({

  url: "/ServerResource.txt"

});

  

jqxhr.done(successFunction1);

jqxhr.done(successFunction2);

jqxhr.done(successFunction3);

jqxhr.fail(errorFunction1);

jqxhr.fail(errorFunction2);

### js


var promise = $.ajax({

  url: "/ServerResource.txt"

});

  

promise.then(successFunction, errorFunction);

### js


var promise = $.ajax({

  url: "/ServerResource.txt"

});

 

promise.then(successFunction); //no handler for the fail() event




Deferred 객체를 직접 만들어서 사용할 수 있는데, 그 방법은 아래와 같습니다.


### js


var timer;

$('#result').html('waiting…');

  

var promise = process();

promise.done(function() {

  $('#result').html('done.');

});

promise.progress(function() {

  $('#result').html($('#result').html() + '.');

});

 

function process() {

  var deferred = $.Deferred();

 

  timer = setInterval(function() {

    deferred.notify();

  }, 1000);

   

  setTimeout(function() {

     clearInterval(timer);

     deferred.resolve();

  }, 10000);

   

  return deferred.promise();

}




Promise 에 등록된 callback 들을 Deferred 가 각 상황에 맞게 호출해주는 방식입니다.


```then()``` 함수를 이용하면 아래와 같이 구현할 수 있습니다.

### js


var timer;

 

(function process() {

  $('#result').html('waiting…');

  var deferred = $.Deferred();

     

  timer = setInterval(function() {

    deferred.notify();

  }, 1000);

   

  setTimeout(function() {

     clearInterval(timer);

     deferred.resolve();

  }, 10000);

   

  return deferred.promise();

})().then(function() { $('#result').html('done.'); },

          null,

          function() { $('#result').html($('#result').html() + '.'); });



#h3 References

http://www.htmlgoodies.com/beyond/javascript/making-promises-with-jquery-deferred.html

https://api.jquery.com/category/deferred-object/




연구소/이것저것 | 2016. 4. 18. 14:05 | Posted by 자수씨

20대에는 신기술에 관심이 많아서 이것저것 많이 해보고 실무에 적용도 했었는데, 30대가 되고나니 업무도 많아지고 귀찮음 때문에 신기술에 대해 관심이 점점 떨어져갔습니다.


최근에 다시 신기술에 대해 공부하다보니 너무 많은 것들이 쏟아져 나와있었습니다. 그 중 하나가 promise 패턴인데, 항상 callback 가 진리라 생각하고 불편한 상황에서도 계속 쓰고만 있었습니다.



promise 패턴은 스펙 구현체들을 로드하여 사용할 수 있는데, 최근 가장 많이 쓴는 jQuery 에서도 promise 패턴을 활용할 수 있습니다.


jQuery 에서는 ```jQuery.when(deferreds)``` 로 제공이 되며 API 에 있는 예제를 하나씩 확인해보겠습니다.



아래 예제는 ```jQuery.when()``` 의 파라미터인 ```deferred``` 가 정상적으로 처리되면 ```deferred.then``` 에서 콜백과 같은 처리를 합니다. 기존의 방식과는 달리 콜백이 중첩되지 않는 구조입니다.


### js


$.when( $.ajax( "test.aspx" ) ).then(function( data, textStatus, jqXHR ) {

  alert( jqXHR.status ); // Alerts 200

});



```jQuery.when()``` 의 파라미터가 Deferred 나 Promise 가 아닐 경우에는 done 콜백이 즉시 실행됩니다.

### js


$.when( { testing: 123 } ).done(function( x ) {

  alert( x.testing ); // Alerts "123"

});


파라미터가 없는 경우에도 즉시 실행됩니다.

### js


$.when().then(function( x ) {

  alert( "I fired immediately" );

});




아래는 ```jQuery.Deferred()``` 를 이용한 예제인데, 아직 잘 이해가 되지 않는 부분이 있습니다. Deferred 객체에 대해 학습 후에 다시 정리해야겠습니다.

### js


var d1 = $.Deferred();

var d2 = $.Deferred();

 

$.when( d1, d2 ).done(function ( v1, v2 ) {

    console.log( v1 ); // "Fish"

    console.log( v2 ); // "Pizza"

});

 

d1.resolve( "Fish" );

d2.resolve( "Pizza" );


### js


var d1 = $.Deferred();

var d2 = $.Deferred();

var d3 = $.Deferred();

 

$.when( d1, d2, d3 ).done(function ( v1, v2, v3 ) {

    console.log( v1 ); // v1 is undefined

    console.log( v2 ); // v2 is "abc"

    console.log( v3 ); // v3 is an array [ 1, 2, 3, 4, 5 ]

});

 

d1.resolve();

d2.resolve( "abc" );

d3.resolve( 1, 2, 3, 4, 5 );




#h3 References

https://api.jquery.com/jquery.when/

https://api.jquery.com/category/deferred-object/

연구소/AngularJS | 2016. 4. 18. 00:24 | Posted by 자수씨

새로운 라이브러리나 프레임워크를 공부할 때는 manning 사의 in Action 시리즈를 자주보게 되는데, 이번에도 AngularJS 공부하기 위해 "AngularJS in Action" 을 살펴보고 있는 중입니다.


쭉 살펴보는 도중 외부 서비스를 사용하는 부분이 있었는데, auth0 와 firebase 입니다.



#h3 auth0


이름에서 볼 수 있듯이 auth0 는 인증과 관련된 서비스를 제공해줍니다. 


홈페이지: https://auth0.com




You can easily and quickly connect your apps, choose identity providers, add users, set up rules, customize your login page and access analytics from your Auth0 dashboard. It really is identity made simple for developers.


https://auth0.com/how-it-works - Overview


위의 내용을 간략하게 보면 내가 만든 애플리케이션에서 접속, 인증 프로바이더 선택, 유저 추가 등을 쉽고 빠르게 적용할 수 있게 도와주는 서비스입니다. 애플리케이션에 가장 기본이 되는 사용자 관련 처리에 대해서 고민거리를 줄여줄 수 있는 서비스라 생각됩니다.


최대 액티브 유저 기준 7,000 명까지는 무료이므로 간단한 시스템 만들 때는 활용하는 것도 좋아보입니다.




#h3 Firebase


이름과 아이콘을 봤을 때는 저장소를 제공해주는 서비스로 생각되었습니다.


홈페이지: https://www.firebase.com





Firebase can power your app's backend, including data storage, user authentication, static hosting, and more. Focus on creating extraordinary user experiences. We'll take care of the rest.

- firebase overview


Firebase 는 데이터 저장소, 사용자 인증, 호스팅 등 백엔드 서비스를 주로 제공합니다. 무료 사용자도 1GB 의 저장소를 제공하기 때문에 auth0 과 마찬가지로 장난감 만들 때 요긴하게 사용할 수 있을 것 같습니다.





나름 10여년 개발하면서 장난감을 만들곤 했었는데, 그 때마다 반복적인 작업 & 설정에 귀찮음을 느끼고 그만둔 것들이 많았습니다. 이런 서비스를 활용한다면 손쉽게 장난감을 만들 수 있을 것이라는 알 수 없는 자신감이 넘쳐 흐름을 느낍니다.




'연구소 > AngularJS' 카테고리의 다른 글

AngularJS 서비스 상속에 대한 고찰  (0) 2016.04.20
AngularJS 기본 개발 환경 구성하기  (0) 2016.04.14

연구소/node.js | 2016. 4. 15. 18:47 | Posted by 자수씨

회사에서 게임 개발/운영 업무를 하다보니 신규 컨텐츠 제작 시 반복적인 신규 리소스 배포작업을 하고 있었습니다.


node.js 공부도 할겸 배포 스크립트 만들어봤습니다.



#h3 배포하기


목표로 했었던 배포 환경을 포스팅용으로 구성해보았습니다.


  • source: 복사할 소스 이미지들이 있는 디렉토리
  • destination/project: 프로젝트(코딩)에 리소스 디렉토리
  • destination/share: 공유 디렉토리


PS E:\temp\sources\resources> tree /a /f

E:.

+---destination

|   +---project

|   |   +---A

|   |   +---B

|   |   \---C

|   \---share

|       +---1

|       +---2

|       \---3

\---source

        02.png

        03.png

        04.png



```Gruntfile.js```
### js

'use strict';

module.exports = function(grunt) {
var readline = require('readline');
var path = require('path');
var sourceDir = 'E:/temp/sources/resources/source';
var shareDestDir = {
root: 'E:/temp/sources/resources/destination/share',
bg: '1',
logo: '2',
icon: '3'
};
var projectDestDir = {
root: 'E:/temp/sources/resources/destination/project',
bg: 'A',
logo: 'B',
icon: 'C'
};
var resourceId = -1;

// Project configuration.
grunt.initConfig({
deploy: {
main: {
files: [
{cwd: sourceDir, src: ['02.png'], dest: [shareDestDir, projectDestDir], type: 'bg'},
{cwd: sourceDir, src: ['03.png'], dest: [shareDestDir, projectDestDir], type: 'logo'},
{cwd: sourceDir, src: ['04.png'], dest: [shareDestDir, projectDestDir], type: 'icon'},
]
}
}
});

grunt.registerTask('question', function() {
var done = this.async();
var rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
rl.question('Input resource ID: ', function(answer) {
rl.close();
resourceId = answer;
grunt.log.writeln('입력받은 아이디: ' + resourceId);
done();
});
});

grunt.registerMultiTask('deploy', function() {

var options = this.options({
encoding: grunt.file.defaultEncoding,
timestamp: false,
mode: false
});

var copyOptions = {
encoding: options.encoding,
process: options.process,
noProcess: options.noProcess
};

this.files.forEach(function(filePair) {
var type = filePair.type;
filePair.src.forEach(function(src) {
var srcPath = path.join(filePair.cwd, src);
var destFileName = type + '_' + resourceId + '.png';
filePair.dest.forEach(function(dest) {
if (dest[type]) {
var destDirName = path.join(dest.root, dest[type]);
var destPath = path.join(destDirName, destFileName);
grunt.file.copy(srcPath, destPath, copyOptions);
grunt.log.writeln('Copy to ' + destPath);
}
});
});
});
});
grunt.registerTask('default', [
'question', 'deploy'
]);
};


기존에 ```copy``` 태스크를 ```deploy``` 로 변경하였으며, 하드코딩으로 파일 복사가 아닌 ```grunt.initConfig({...})``` 에 설정을 읽어들여 파일을 복사하도록 수정하였습니다.



빌드 스크립트 실행결과는 다음과 같습니다.


PS E:\temp\sources\grunt> grunt

Running "question" task

Input resource ID: 0001

입력받은 아이디: 0001


Running "deploy:main" (deploy) task

Copy to E:\temp\sources\resources\destination\share\1\bg_0001.png

Copy to E:\temp\sources\resources\destination\project\A\bg_0001.png

Copy to E:\temp\sources\resources\destination\share\2\logo_0001.png

Copy to E:\temp\sources\resources\destination\project\B\logo_0001.png

Copy to E:\temp\sources\resources\destination\share\3\icon_0001.png

Copy to E:\temp\sources\resources\destination\project\C\icon_0001.png


Done, without errors.



파일들이 복사된 경로를 트리형태로 보면 아래와 같습니다.


PS E:\temp\sources\resources> tree /a /f

E:.

+---destination

|   +---project

|   |   +---A

|   |   |       bg_0001.png

|   |   |

|   |   +---B

|   |   |       logo_0001.png

|   |   |

|   |   \---C

|   |           icon_0001.png

|   |

|   \---share

|       +---1

|       |       bg_0001.png

|       |

|       +---2

|       |       logo_0001.png

|       |

|       \---3

|               icon_0001.png

|

\---source

        02.png

        03.png

        04.png



지금까지 21번이나 복사하는 작업을 반복했는데, 왜 이런걸 만들 생각을 그동안 못했는지 눙물이 납니다 ㅠㅠ




연구소/node.js | 2016. 4. 15. 17:44 | Posted by 자수씨

회사에서 게임 개발/운영 업무를 하다보니 신규 컨텐츠 제작 시 반복적인 신규 리소스 배포작업을 하고 있었습니다.


node.js 공부도 할겸 배포 스크립트 만들어봤습니다.



#h3 파일 복사하기


파일 복사 테스트를 위해 하드코딩으로 이미지 파일을 입력받은 아이디로 리네임된 파일을 복사 테스트를 해보았습니다.


```Gruntfile.js```

### js


'use strict';


module.exports = function(grunt) {

var readline = require('readline');

var resourceId = -1;


// Project configuration.

grunt.initConfig({

copy: {

main: {

}

}

});


grunt.registerTask('question', function() {

var done = this.async();

var rl = readline.createInterface({

input: process.stdin,

output: process.stdout

});

rl.question('Input resource ID: ', function(answer) {

rl.close();

resourceId = answer;

grunt.log.writeln('입력받은 아이디: ' + resourceId);

done();

});

});


grunt.registerMultiTask('copy', function() {


var options = this.options({

encoding: grunt.file.defaultEncoding,

timestamp: false,

mode: false

});


var copyOptions = {

encoding: options.encoding,

process: options.process,

noProcess: options.noProcess

};

var srcPath = 'grunt.png';

var destPath = resourceId + '.png';


grunt.file.copy(srcPath, destPath, copyOptions);

});

grunt.registerTask('default', [

'question', 'copy'

]);

};


파일 복사 작업을 진행하는 ```copy``` 라는 멀티 태스크를 만들고 디폴트 태스크에 추가하였습니다.


입력받은 아이디를 사용해야하기 때문에 ```question``` 태스크 다음에 실행되도록 순서를 지정하였습니다.


실행을 하면 다음과 같이 복사작업이 완료됩니다.


PS E:\temp\sources\grunt> grunt

Running "question" task

Input resource ID: UWO_22

입력받은 아이디: UWO_22


Running "copy:main" (copy) task


Done, without errors.



멀티태스크로 만들 경우 ```grunt.initConfig({...})``` 에 설정 값이 없으면 태스크를 인식하지 못하는 듯 합니다. 아직 아무런 값이 없지만 ```grunt.initConfig({...})``` 에 ```copy``` 태스크 설정을 합니다.



파일 복사 테스트도 끝났으니 이제 마지막 배포 작업만이 남았습니다.




연구소/node.js | 2016. 4. 15. 17:06 | Posted by 자수씨

회사에서 게임 개발/운영 업무를 하다보니 신규 컨텐츠 제작 시 반복적인 신규 리소스 배포작업을 하고 있었습니다.


node.js 공부도 할겸 배포 스크립트 만들어봤습니다.



#h3 아이디 입력받기


"아이디" 는 신규 컨텐츠 마다 별도로 지정이 되기 때문에 스크립트 실행 시 입력받도록 만들고자 합니다.


해당 작업을 위해서는 ```readline``` 라이브러리가 필요합니다. ```readline``` 의 question 함수를 이용하여 입력을 받는 부분을 구현해보았습니다.


```Gruntfile.js```

### js


'use strict';


module.exports = function(grunt) {

var readline = require('readline');

var resourceId = -1;


// Project configuration.

grunt.initConfig({

});


grunt.registerTask('question', function() {

var done = this.async();

var rl = readline.createInterface({

input: process.stdin,

output: process.stdout

});

rl.question('Input resource ID: ', function(answer) {

rl.close();

resourceId = answer;

grunt.log.writeln('입력받은 아이디: ' + resourceId);

done();

});

});

grunt.registerTask('default', [

'question'

]);

};


```question``` 이라는 태스크를 만들고 기본 태스크에 ```question``` 을 등록한 상태이기 때문에 스크립트를 실행하면 아래와 같이 나오게 됩니다.


PS E:\temp\sources\grunt> grunt

Running "question" task

Input resource ID: 12

입력받은 아이디: 12


Done, without errors.



입력받은 아이디는 재사용해야하기 때문에 grunt 전역에서 사용할 수 있도록 선언하고 입력받은 값으로 설정합니다.



아이디 입력받기도 끝!!


연구소/node.js | 2016. 4. 15. 16:14 | Posted by 자수씨

회사에서 게임 개발/운영 업무를 하다보니 신규 컨텐츠 제작 시 반복적인 신규 리소스 배포작업을 하고 있었습니다.


node.js 공부도 할겸 배포 스크립트 만들어봤습니다.



개요

신규 컨텐츠의 디자인이 나오면 해당 파일을 개발 시에 사용하는 이름으로 변경하고 프로젝트 인원들이 함께 볼 수 있는 "공유폴더" 와 개발 워크스페이스에 "리소스폴더" 에 복사를 합니다.




"공유폴더" 와 "리소스폴더" 는 하위 폴더 구조도 상이하여 작업을 할 때마다 개별폴더에 하나씩 복사해야했기에 반복/귀찮은 작업이었습니다.


신규 리소스는 개발에 사용 시에 "아이디" 에 따라 네이밍을 하였기 때문에 배포 작업 시에 변경되는 사항은 "아이디" 밖에 없었습니다.



따라서, 다음과 같이 배포 스크립트를 만드려고 합니다.


  • "아이디" 는 스크립트 실행 시 입력을 받는다.

  • 각 파일들은 "아이디" 를 조합하여 리네임한다.

  • 각 파일들은 각 배포 경로에 복사한다.



사전작업

일단 node.js 와 grunt 실행이 가능하도록 환경을 구성하였습니다.


그 후 가장 기본적인 grunt 스크립트를 만들었습니다.


```package.json```

### JSON


{

  "name": "slotresource-deploy",

  "version": "0.0.1",

  "devDependencies": {

    "grunt": "~0.4.5"

  }

}


```Gruntfile.js```

### js


'use strict';


module.exports = function(grunt) {


    // Project configuration.

    grunt.initConfig({

    });


};


같은 디렉토리에 ```package.json``` 과 ```Gruntfile.js``` 를 생성하고 npm 로 초기화합니다.


npm install


위의 명령어를 실행하면 npm 에서 자동으로 필요한 모듈을 내려받게 됩니다.


slotresource-deploy@0.0.1 E:\temp\sources\grunt

`-- grunt@0.4.5

  +-- async@0.1.22

  +-- coffee-script@1.3.3

  +-- colors@0.6.2

  +-- dateformat@1.0.2-1.2.3

  +-- eventemitter2@0.4.14

  +-- exit@0.1.2

  +-- findup-sync@0.1.3

   ...



이 상태에서 ```grunt``` 를 실행하면 아무것도 없기 때문에 에러가 납니다.


사전작업은 여기까지가 끝!!




연구소/AngularJS | 2016. 4. 14. 18:06 | Posted by 자수씨

node.js 와 npm 이 설치된 상태에서 시작합니다.



기본 개발환경 위해 필요한 툴을 설치합니다.


  • yo (Yeoman): 최신 웹 애플리케이션의 뼈대를 잡아주는 툴 - http://yeoman.io/
  • bower: 웹 사이트의 프레임워크, 라이브러리 등을 관리하는 툴 - http://bower.io/
  • grunt-cli: 자바스크립트 태스크 러너 - http://gruntjs.com/
  • generator-angular: 요맨 AngularJS 제너레이터
  • generator-karma: 요맨 AngularJS 테스트 러너 제너레이터

npm install -g yo bower grunt-cli


npm install -g generator-angular generator-karma



요맨을 이용하여 기본 골격을 갖춘 AngularJS 샘플 프로젝트를 생성합니다.


yo angular sample_project


요맨 옵션은 Sass 사용 안함 외에는 기본 구성을 사용했습니다.





생성된 프로젝트가 정상적인지 실행해봅니다.


grunt serve






아래와 같이 페이지가 나오면 정상적으로 설정이 된 상태입니다.





간혹 "grunt serve" 로 서버를 띄우는 중에 오류가 발생하면 아래의 작업을 수행합니다.


npm install


bower install



개발환경이 갖춰졌으므로 테스트 코딩을 하러...



'연구소 > AngularJS' 카테고리의 다른 글

AngularJS 서비스 상속에 대한 고찰  (0) 2016.04.20
auth0 & firebase  (0) 2016.04.18

연구소/Sass | 2016. 4. 12. 16:16 | Posted by 자수씨

Nesting

HTML 은 중첩구조와 계층을 가지고 있는데, CSS 는 그렇지 않다.

Sass 는 HTML 과 같은 계층구조로 CSS 셀렉터를 구성할 수 있다. 심하게 중첩된 규칙은 필요이상의 CSS 가 만들어지기 때문에 유지보수를 어렵게 하고 나쁜 사례가 됨을 고려해야 한다.

아래는 일반적인 스타일의 사이트 네비게이션 예제이다.

### SCSS

nav {
  ul {
    margin: 0;
    padding: 0;
    list-style: none;
  }

  li { display: inline-block; }

  a {
    display: block;
    padding: 6px 12px;
    text-decoration: none;
  }
}

```ul```, ```li``` ```a``` 셀렉터는 ```nav``` 셀럭터 내부에 중첩되어 있다. 이러한 구조는 CSS 를 체계화 하는데 좋은 방법이며 좀 더 읽기 쉽게 만든다. 생성된 CSS 는 아래와 같다.

### CSS

nav ul {
  margin: 0;
  padding: 0;
  list-style: none;
}

nav li {
  display: inline-block;
}

nav a {
  display: block;
  padding: 6px 12px;
  text-decoration: none;
}

References

- http://sass-lang.com/guide


'연구소 > Sass' 카테고리의 다른 글

Sass Basics - Preprocessing, Variables  (0) 2016.04.11
Sass 란 무엇인가?  (0) 2016.04.11