블로그 이미지
Peter Note
Web & LLM FullStacker, Application Architecter, KnowHow Dispenser and Bike Rider

Publication

Category

Recent Post

2013. 4. 20. 12:19 HTML5, CSS3/CSS

Sass는 CSS를 재미있게 만들어준다. 개발자에겐 접근하기 쉽겠지만 디자이너에겐 개발에 대한 고민을 하게 만드는 것같다. 하지만 현대적인 웹개발을 위하여 이제는 피할 수 없는 대세(?)인 Sass를 익혀야 한다.



1) 개요

  - 만들어진 배경에 대해서 이해하자 

  


  - 여러 기능들의 본질은 간결하고 반복작업을 없애주는 웹 개발 흐름을(Web Development Workflow) 만들어준다

    + Nested Rules : 들여쓰기 가능 - 상위 개체에 대한 정의를 줄인다 

// CSS

table.hl {

  margin: 2em 0;

}

table.hl td.ln {

  text-align: right;

}


// SCSS (Sassy CSS)

table.hl {

  margin: 2em 0;

  td.ln {

    text-align: right;

  }

}


// SASS

table.hl

  margin: 2em 0

  td.ln

    text-align: right


    + Variables : 변수를 사용하여 반복적인 상수를 줄인다 ($를 사용)

// CSS

.content-navigation {

  border-color: #3bbfce;

  color: #2b9eab;

}


// SCSS

$blue: #3bbfce;

$margin: 16px;


.content-navigation {

  border-color: $blue;

  color:

    darken($blue, 9%);

}


// SASS

$blue: #3bbfce

$margin: 16px


.content-navigation

  border-color: $blue

  color: darken($blue, 9%)


    + Mixins : 반복적인 입력을 함수화하는 것처럼 이용하여 코드를 줄인다 (@mixin @include 이용)

// CSS

#data {

  float: left;

  margin-left: 10px;

}

#data th {

  text-align: center;

  font-weight: bold;

}

#data td, #data th {

  padding: 2px;

}


// SCSS

@mixin table-base {

  th {

    text-align: center;

    font-weight: bold;

  }

  td, th {padding: 2px}

}


@mixin left($dist) {

  float: left;

  margin-left: $dist;

}


#data {

  @include left(10px);

  @include table-base;

}


// SASS

@mixin table-base

  th

    text-align: center

    font-weight: bold

  td, th

    padding: 2px


@mixin left($dist)

  float: left

  margin-left: $dist


#data

  @include left(10px)

  @include table-base


    + Selector Inheritance : 상속 개념으로 기존 코드를 줄인다 (@extend 사용)

// CSS

.error, .badError {

  border: 1px #f00;

  background: #fdd;

}


.error.intrusion,

.badError.intrusion {

  font-size: 1.3em;

  font-weight: bold;

}


.badError {

  border-width: 3px;

}


// SCSS

.error {

  border: 1px #f00;

  background: #fdd;

}

.error.intrusion {

  font-size: 1.3em;

  font-weight: bold;

}


.badError {

  @extend .error;

  border-width: 3px;

}


// SASS

.error

  border: 1px #f00

  background: #fdd


.error.intrusion

  font-size: 1.3em

  font-weight: bold


.badError

  @extend .error

  border-width: 3px


  - Sass는 두가지 문법으로 작성을 할 수 있다 

    + Scss : .scss 이고 {} 와 ; 가 존재, CSS3 의 확장자이다 (Sassy CSS)

    + Sass : .sass 이고 {} 와 ; 가 없고 대신 들여쓰기로 구분을 하여 간결함을 추구한다 (Haml 영향을 받음)

   


  - Sass는 색에 대한 Functions을 제공한다 (참조)

   예) 

   



2) 설치 및 사용법

  - gem install sass

  - 예제 코드 : dowon.scss

#dowon {

  width : 20%;

  height : 120px;

}

  - css 파일 변환하기 : sass --watch dowon.scss:dowon.css


  - Partials & Concatenation : @import 를 사용하고 분할된 파일의 컨벤션은 _partialFile.scss 즉 앞에 _ (underbar)를 붙여서 import 되는 파일을 따로 관리한다 그리고 컴파일을 하게 되면 지정한 하나의 파일 .css로 합쳐진다 


<참조>

  - Sass Tutorial

  - Sass References

  - Sass 온라인 테스트

  - Sass 개요 설명 - 한글

  - Sass 기능 설명 - 한글

posted by Peter Note
2013. 4. 20. 00:46 HTML5, CSS3/CSS

JavaScript에 CoffeeScript가 있다면 CSS에는 Stylus같은 CSS-Preprocessor가 있다고 할까? DRY(Don't Repeat Yourself)를 통하여 반복되는 구문을 없애주고 , {} 의 사용이 필요없다. 그외 다양한 기능이 있으니 자신에게 맞는 것을 선택하여 쓰자. 



1. Stylus 

  - Stylus 만든 분의 소개 동영상


  - 하지만 Stylus말고도 Less, Sass등이 있었으니 이제 결정할 때가 된것 같다



2. Sass

  - Sass 와 Compass에 대해 자세히 알아보자 


  - 이젠 Modern Web Development Workflow에 CoffeeScript + Sass 를 접목하자 



3. Less 

  - 좀 더 간단하게 사용할 수 있다 
  - 사용방법과 문법 소개 



<참조>

  - CSS에 대한 기초

  - Sass & Compass 배우기 35개 리소스 목록

posted by Peter Note
2013. 4. 15. 11:44 Dev Environment/Build System

AngularJS 개발시 반복적인 작업을 제거하고 생산성을 높일 수 있는 통합 도구인 Yeoman의 사용법에 대해 알아보고, 처음 개발을 시작할 때 코드의 틀을 잡아 주는 몇가지 Seed 프로젝트를 통하여 어떤 구조로 애플리케이션을 만들어야 하는지 알아두자



1. 필요 요소 기술

  - UI : Bootstrap from Twitter  간혹 Foundation을 이용

  - Build/Preview : Grunt

  - Test : 기본은 Karma이고, Mocha를 사용하고 싶다면 Karma-Mocha Karma구동을 위한 Mocha adapter 존재

  - Package Management : Bower from Twitter

이들의 통합적으로 사용하기 위한 툴로 yeoman 을 설치하면 된다. 간단한 명령으로 AngularJS 관련 코드를 자동 생성하여 준다



2. Yeoman startup

  

yo - the scaffolding tool from Yeoman

bower - the package management tool  

  + component.json : 의존관계 설정

  + .bowerrc : 컴포넌트 설치 위치정보

grunt - the build tool 

  + Gruntfile.js : ant와 같은 수행 Task 정의

  + package.json : Node.js위에 구동되므로 package.json에 Grunt contributor 라이브러리 정의

karma - grunt test 시에 수행 

  + karma.conf.js : 로컬 테스트 환경

  + karma-e2e.conf.js : Real Browser 테스트 환경 즉, end-to-end (Client<->Server) 테스트 수행. 사용 port 8080


  - Yeoman command for AngularJS

// 설치 : grunt-cli, bower가 같이 설치된다 

npm install -g yo


// Yeoman을 위한 generator 설치 for AngularJS & Karam

// 하기 에러 내역 참조하여 generator-angular의 script-base.js 파일 수정

// Generator는 Yeoman에서 생성하는 boilerplate 나 scaffolding 코드를 만들어주는

// Yeoman의 플러그인이라 생각하면 된다. 이미 만들어지 Generator 목록이 존재한다

// > https://github.com/yeoman (generator-* 목록들)

// > Generator 만들기 참조

npm install -g generator-webapp generator-angular generator-karma


// 명령어 (프로젝트 디렉토리에서 수행)

yo angular 또는 yo angular:app 애플리케이션 생성

yo angular:controller myControllerName 컨트롤러 생성

yo angular:directive myDirectiveName 디렉티브 생성

yo angular:filter myFilterName 필터 생성

yo angular:service myServiceName 서비스 생성


  - yo angular:* 사용시 에러 발생 해결방법

예) yo angular:controller Test 수행시 하기와 같은 에러 발생

~/angularjs/sd_01> yo angular:controller Test


path.js:360

        throw new TypeError('Arguments to path.join must be strings');

              ^

TypeError: Arguments to path.join must be strings

    at path.js:360:15

    at Array.filter (native)

    at Object.exports.join (path.js:358:36)

    at Generator (/usr/local/lib/node_modules/generator-angular/script-base.js:38:29)

    at new Generator (/usr/local/lib/node_modules/generator-angular/controller/index.js:10:14)


==> 해결하기 

1) /usr/local/lib/node_modules/generator-angular/script-base.js 의 38 번째 줄 내용을 하기와 같이 수정함

 37     if (!this.options.coffee &&

 38       //this.expandFiles(path.join(this.appPath, '/scripts/**/*.coffee'), {}).length > 0) {  // 주석처리 

 39       this.expandFiles(path.join(process.cwd(), '/scripts/**/*.coffee'), {}).length > 0) {  // process.cwd() 로 바꿈

 40       this.options.coffee = true;

 41     }


2) 재수행 : 친절하게도 TestCase까지 자동 생성해 준다 

   ~/angularjs/sd_01> yo angular:controller Test

   create app/scripts/controllers/Test.js

   create test/spec/controllers/Test.js


  - Yeoman command for Bower : 의존관계 라이브러리에 대한 관리 담당 

// 명령어

bower search <dep> - search for a dependency in the Bower registry

bower install <dep>..<depN> - install one or more dependencies

bower list - list out the dependencies you have installed for a project

bower update <dep> - update a dependency to the latest version available


// 설치하기 

// .bowerrc 에 설정된 디렉토리로 다운로드된 라이브러리가 설치된다

$ bower install angular-ui

bower cloning git://github.com/angular-ui/angular-ui.git

bower cached git://github.com/angular-ui/angular-ui.git

bower fetching angular-ui

bower checking out angular-ui#v0.4.0

bower copying /Users/nulpulum/.bower/cache/angular-ui/bd4cf7fc7bfe2a2118a7705a22201834

bower installing angular-ui#0.4.0


$ cd app/components/

$ ls

angular angular-scenario es5-shim json3

angular-mocks angular-ui jquery


$ cd ../..

$ cat .bowerrc

{

    "directory": "app/components"

}


  - Yeoman command for Grunt : 프러덕션 빌드, 미리보기, 테스팅 

    + grunt는 task에 대한 여러 target들이 존재하는 구조이다. 

    + 명령을 grunt <task> 로 주면 task밑의 모든 target이 순서대로 수행된다

    + 명령을 grunt <task>:<target> 을 지정하여 특정 target만 수행할 수도 있다

    + task와 관련한 여러가지 Plugins 이 이미 만들어져 있고 직접 만들 수도 있다 (기존 Plugins 목록)

// 명령어

grunt test  - 테스트하기. run the unit tests for an app  

grunt server - 브라우져에서 보기. 변경사항 실시간 반영됨. preview an app you have generated (with Livereload)

grunt - 배포본 빌드하기.  build an optimized, production-ready version of your app  (warning 무시 옵션 --force 사용가능)


// 브라우져 미리보기 in app root folder

grunt server

// warning -jslint 같은- 무시하고 계속 build하기

grunt  --force 



3. 기본 코드 생성

  - Grunt-Express : Grunt와 Express 연동하기

  - Yeoman-Angular-Express : Yeoman을 이용하여 Angular project 생성한 후 Express와 통합하는 예제

  - Angular-Socket.io-Seed : Angular와 Socket.io를 접목 시키고자 할때 사용 (포스팅)



4. Addy Osmani 님이 이야기 하는 Automation Front-end workflow



결론적으로 Yeoman을 사용하여 기반 코드를 생성하고 빌드/테스팅 자동화를 한다. 그리고 필요한 코드들은 Seed 프로젝트를 참조하여 자기것으로 만들면 되겠다



<참조>

  - 원문 : Google, Twitter and AngularJS

  - 보다 많은 AngularJS와 BackboneJS에 대한 기사 in DailyJS

  - Grunt를 위한 express 플러그인 테스트

posted by Peter Note

AngularJS의 테스트툴로 Testacular를 사용하는데 명칭이 Karma로 바뀌었다. WebStorm에 설정하고 사용하는 방법을 알아보자 



1) Karma 설치하기

  - 홈페이지 : http://karma-runner.github.io/0.8/index.html

  - 선조건 : WebStorm 설치 및 Node.js 설치

  - Karma를 global로 설치 : npm install -g karma



2) Yeoman을 통한 Karma 환경설정 

  - 일반적으로 Yeoman을 통하여 스케폴딩 코드를 만들어 사용하는 것이 좋다 : Yeoman 홈페이지

  - yeoman 설치 : npm install -g yo grunt-cli bower

  - angular 프로젝트 만들기 : yo angular 또는 yo angular:app

    

    <자동 생성된 파일 및 디렉토리 구조>


  - 자동 생성된 karma 테스트 환경파일 : karma.conf.js

/ Karma configuration
 
// base path, that will be used to resolve files and exclude
basePath = '';
 
// list of files / patterns to load in the browser
files = [
JASMINE,
JASMINE_ADAPTER,
'app/components/angular/angular.js',
'app/components/angular-mocks/angular-mocks.js',
'app/scripts/*.js',
'app/scripts/**/*.js',
'test/mock/**/*.js',
'test/spec/**/*.js'
];
 
// list of files to exclude
exclude = [];
 
// test results reporter to use
// possible values: dots || progress || growl
reporters = ['progress'];
 
// web server port
port = 8080;
 
// cli runner port
runnerPort = 9100;
 
// enable / disable colors in the output (reporters and logs)
colors = true;
 
// level of logging
// possible values: LOG_DISABLE || LOG_ERROR || LOG_WARN || LOG_INFO || LOG_DEBUG
logLevel = LOG_INFO;
 
// enable / disable watching file and executing tests whenever any file changes
autoWatch = false;
 
// Start these browsers, currently available:
// - Chrome
// - ChromeCanary
// - Firefox
// - Opera
// - Safari (only Mac)
// - PhantomJS
// - IE (only Windows)
browsers = ['Chrome'];
 
// If browser does not capture in given timeout [ms], kill it
captureTimeout = 5000;
 
// Continuous Integration mode
// if true, it capture browsers, run tests and exit
singleRun = false;



3) WebStorm 환경설정

  - Server 설정하기 

    + 웹스톰 상단의 메뉴에서 Edit Configurations... 클릭

    

   + Node.js로 "Karma Server" 생성 : node.js, karma 설치 위치와 프로젝트 위치, 파라미터로 start 입력

      카르마의 테스트 서버 역할을 수행


    + Karma Run 생성 : 파라미터로 run 입력, 테스트를 수행한다 


    + Karma Debug : JavaScript Debug의 Remote로 생성 

       Remote URL 로 "http://localhost:8080/" 입력 



4) 테스트 수행하기 

  - Karma Server 시작하기 

    + Karma Server 선택하고 > 시작 버튼 클릭

    + 하단에 localhost:8080 으로 Listen하는 서버 구동됨 

    + 브라우져가 자동 실행 : 자동 실행안되면 브라우져 띄워서 8080 호출 



  - Karma Run 테스트 하기 

    + 테스트 수행하기 

    + 테스트가 정상 수행되면 SUCCESS가 나온다. 비정상이면 FAILED 메세지


  - Karma Debug

    + 소스 코드에 Break point를 만들고 디버그 수행

    + 테스트 해본 결과 잘 안되는데 향후 다시 한번 체크해 봐야 겠다



5) 테스트 코드 

  - BDD 방식의 테스트 코드를 짠다 

//////////////

// 업무 코드 

'use strict';
 
var app = angular.module('eggheadioApp');
 
app.controller('MainCtrl', function ($scope) {
$scope.awesomeThings = [
'HTML5 Boilerplate',
'AngularJS',
'Karma'
];
}) ;
 
app.factory('Data', function() {
return {message: 'shared data'}
});
 
app.filter('reverse', function(Data) {
return function(text) {
return text.split("").reverse().join("");
}
});


//////////////////////////

// 필터에 대한 테스트 코드 

describe('filter', function() {
beforeEach(module('eggheadioApp'));
 
describe('reverse', function() {
it('should reverse a string', inject(function(reverseFilter){ //reverse라는 Filte 파라미터
expect(reverseFilter('ABCD')).toEqual('DCBA');
}))
})
})



<참조>

  - 원본 : 유튜브 동영상

posted by Peter Note
2013. 4. 11. 17:20 AngularJS/Concept

앵귤러의 모듈에 대해서 알아보자 



1) 개요

  - 모든 애플리케이션에는 main이 있지만 Angular에는 main 이 없다. 애플리케이션이 시작할 때 정의한 모듈을 읽는다

  - 모듈로 쪼개면 애플리케이션 이해가 쉽고 unit-testing이 수월하며 end-to-end testing도 가능하다

  - 필요한 모듈은 언제든지 로딩해서 사용할 수 있다

  - 3rd-party 라이브러리를 모듈로 만들어 사용할 수 있다 

  - Module API

  - 모듈 종류

    + Service Module

    + Directive Module

    + Filter Module 

    + module 들에 의존하는 Application Module : <ng-app="ModuleName"> 으로 시작


  - 모듈을 나누는 가장 큰 이유는 테스팅! 테스팅!

  - 아름다운 코드를 보자 

index.html

  1. <!doctype html>
  2. <html ng-app="xmpl">
  3. <head>
  4. <script src="http://code.angularjs.org/1.0.5/angular.min.js"></script>
  5. <script src="script.js"></script>
  6. </head>
  7. <body>
  8. <div ng-controller="XmplController">
  9. {{ greeting }}!
  10. </div>
  11. </body>
  12. </html>


script.js : service, directive, filter module => use xmpl application module

  1. angular.module('xmpl.service', []).
  2. value('greeter', {
  3. salutation: 'Hello',
  4. localize: function(localization) {
  5. this.salutation = localization.salutation;
  6. },
  7. greet: function(name) {
  8. return this.salutation + ' ' + name + '!';
  9. }
  10. }).
  11. value('user', {
  12. load: function(name) {
  13. this.name = name;
  14. }
  15. });
  16.  
  17. angular.module('xmpl.directive', []);
  18.  
  19. angular.module('xmpl.filter', []);
  20.  
  21. <!-- ng-app="xmpl" 모듈이 다른 부가적인 모듈에 의존관계를 가지고 있다 -->
  22. angular.module('xmpl', ['xmpl.service', 'xmpl.directive', 'xmpl.filter']).
  23. run(function(greeter, user) {
  24. // This is effectively part of the main method initialization code
  25. greeter.localize({
  26. salutation: 'Bonjour'
  27. });
  28. user.load('World');
  29. })
  30.  
  31. // A Controller for your app
  32. var XmplController = function($scope, greeter, user) {
  33. $scope.greeting = greeter.greet(user.name);
  34. }

  


2) 모듈 로딩과 의존관계

  - 모듈은 초기화를 시작하여 애플리케이션에 적용되는 동안 Configuration & Run Block의 집합체이다 

  - Configuration Block

    + providers, constants 만 inject 된다

    + 의존관계있는 모듈을 inject 받는다 

  1. angular.module('myModule', []).
  2. value('a', 123).
  3. factory('a', function() { return 123; }).
  4. directive('directiveName', ...).
  5. filter('filterName', ...);
  6.  
  7. // is same as
  8. // config 펑션에 provider를 통하여 설정한다  
  9. angular.module('myModule', []).
  10. config(function($provide, $compileProvider, $filterProvider) {
  11. $provide.value('a', 123);
  12. $provide.factory('a', function() { return 123; });
  13. $compileProvider.directive('directiveName', ...);
  14. $filterProvider.register('filterName', ...);
  15. });


  - Run Block 

    + instances, constants 만 inject 된다

    + 모듈의 main 메소드 격으로 보면된다  


* Unit Test 다음에 추가



<참조>

  - 원문 : Developer Guide - Module

posted by Peter Note