npm 호출시 다음과 같은 에러가 발생했다. 

Error: Cannot find module 'npmlog'
    at Function.Module._resolveFilename (module.js:455:15)
    at Function.Module._load (module.js:403:25)
    at Module.require (module.js:483:17)
    at require (internal/module.js:20:19)
    at /usr/local/lib/node_modules/npm/bin/npm-cli.js:19:13
    at Object.<anonymous> (/usr/local/lib/node_modules/npm/bin/npm-cli.js:75:3)
    at Module._compile (module.js:556:32)
    at Object.Module._extensions..js (module.js:565:10)
    at Module.load (module.js:473:32)
    at tryModuleLoad (module.js:432:12)

npm 의 문제가 있으니 이를 수정한 업그레이드가 있을까하고 업그레이드를 시도했으니 npm 6.6.0 가 이미 설치되어 있다고 한다. 

✗ brew upgrade npm
==> Auto-updated Homebrew!
Updated 1 tap (homebrew/core).
==> Updated Formulae
bacula-fd         erlang            galen             irssi             leiningen         liquibase         macosvpn          open-babel        openssl ✔         openssl@1.1       privoxy           repo              zpaq
 
Error: npm 6.6.0 already installed

그래도 동일한 문제가 발생했다. 이와 관련해서 인터넷 검색을 문제를 찾아보니 Cannot find module 'npmlog' following homebrew update & upgrade가 나왔다.

위에 나온 절차에 따라 node 삭제작업을 진행한다.

brew uninstall node
Uninstalling /usr/local/Cellar/node/6.6.0... (3,669 files, 40.9M)
node 6.1.0, 6.3.1 are still installed.
Remove all versions with `brew uninstall --force node`.
➜  honeymon git:(master) ✗ brew uninstall --force node
Uninstalling node... (7,484 files, 78.5M)
➜  honeymon git:(master) ✗ sudo rm -rf /usr/local/lib/node_modules
Password:
➜  honeymon git:(master) ✗ brew install node
==> Downloading https://homebrew.bintray.com/bottles/node-6.6.0.el_capitan.bottle.tar.gz
Already downloaded: /Users/honeymon/Library/Caches/Homebrew/node-6.6.0.el_capitan.bottle.tar.gz
==> Pouring node-6.6.0.el_capitan.bottle.tar.gz
==> Using the sandbox
==> Caveats
Please note by default only English locale support is provided. If you need
full locale support you should either rebuild with full icu:
  `brew reinstall node --with-full-icu`
or add full icu data at runtime following:
  https://github.com/nodejs/node/wiki/Intl#using-and-customizing-the-small-icu-build
 
Bash completion has been installed to:
  /usr/local/etc/bash_completion.d
==> Summary
🍺  /usr/local/Cellar/node/6.6.0: 3,669 files, 40.9M


Gulp

설정 및 설치

  • package.json 생성
{
  "name": "test-front-web",
  "version": "0.0.1.SNAPSHOT",
  "devDependencies": {

  }
}
  • gulp 설치
$ npm install --save-dev gulp 

위의 명령을 실행하고 나면 package.json 파일에 다음과 같이 "gulp": "^3.9.1" 가 추가된 것을 확인할 수 있다.

{
  "name": "test-front-web",
  "version": "0.0.1.SNAPSHOT",
  "devDependencies": {
    "gulp": "^3.9.1"
  }
}

거기에 node_modules 디렉터리가 추가되고 다양한 의존성 라이브러리가 추가되었다.

프로젝트 폴더에 gulpfile.js 를 생성한다. 그리고 그 안에,

// Include gulp
var gulp = require('gulp');

코드를 추가한다.

추가할 수 있는 태스크의 종류는 많지만 그 중에서 몇가지만 소개한다:

  • gulp.task(name, function) - 이름으로 함수를 등록
  • gulp.watch(global, function) - 전역변수의 변경사항이 생겼을 때 호출할 함수 정의
  • gulp.src(global) - 읽어올 위치
  • gulp.dest(folder) - 작성된 파일을 놓을 위치

gulp와 파일 연결하기(Concatenating)

gulp만 설치한다고 끝나는 것은 아니다. gulp 가 동작할 수 있도록 플러그인을 설치하고 gulpfile 에 태스크를 추가해야 한다. gulp-concat 플러그인이 필요하다.

$ npm install --save-dev gulp-concat 

를 실행하고 나면 package.json 에 "gulp-concat": "^2.6.0" 가 추가된다.

이제 gulpfile 에 필요한 테스크를 추가한다.

// Include gulp
var gulp = require('gulp');

// Include plugins
var concat = require('gulp-concat');

//Concatenate JS File: src/js 에 있는 파일들을 main.js 로 연결
gulp.task('scripts', function() {
   return gulp.src('src/js/*.js')
       .pipe(concat('honeymon.js'))
       .pipe(gulp.dest('build/js'));
});

// Default Task
gulp.task('default', ['scripts']);

gulp-concat 플러그인 설정을 포함하고 gulp.task 를 사용하여 기본 테스크에 script 를 추가했다. 이 태스크는 3단계 과정으로 처리가 된다:

  1. gulp.src 에서 정의한 src/js 디렉토리에 있는 확장자 js 를 연결한다.
  2. main.js 로 연결한다.
  3. build/js 디렉토리에 main.js 파일을 밀어 넣는다.

gulp 를 이용한 JS 최소화하기

보통 자바스크립트를 배포할 때 최소화(Minify)하는 과정을 거치는데 gulp 에서는 이를 처리하는 플러그인이 있다. 그리고 나서 파일명 접미사로 .min 를 붙이는 rename 플러그인도 함께 설치한다.

$ npm install --save-dev gulp-unglify gulp-renmae 

이제 gulpfile.js 에 scripts 태스크를 수정한다.

// Include gulp
var gulp = require('gulp');
// Include plugins
var concat = require('gulp-concat');
var uglify = require('gulp-uglify');
var rename = require('gulp-rename');

//Concatenate JS File: src/js 에 있는 파일들을 main.js 로 연결
gulp.task('scripts', function () {
    return gulp.src('src/js/*.js')
        .pipe(concat('honeymon.js'))
        .pipe(rename({suffix: '.min'}))
        .pipe(uglify())
        .pipe(gulp.dest('js'));
});

gulp 를 이용한 css 처리

gulp 를 이용해서 sass 파일을 컴파일하여 css 를 생성하는 태스크를 추가한다.

루비의 공식적인 sass 컴파일러를 설치한다.

$ npm install --save-dev gulp-ruby-sass 

이제 gulpfile.js 에 sass 태스크를 수정한다.

// Include gulp
var gulp = require('gulp');
// Include plugins
var concat = require('gulp-concat');
var uglify = require('gulp-uglify');
var rename = require('gulp-rename');
var sass = require('gulp-ruby-sass');

//Concatenate JS File: src/js 에 있는 파일들을 main.js 로 연결
gulp.task('scripts', function () {
    return gulp.src('src/js/*.js')
        .pipe(concat('honeymon.js'))
        .pipe(rename({suffix: '.min'}))
        .pipe(uglify())
        .pipe(gulp.dest('build/js'));
});

//Compile SASS
gulp.task('sass', function () {
    sass('src/scss/style.scss', {style: 'compressed'})
        .pipe(rename({suffix: '.min'}))
        .pipe(gulp.dest('build/css'));
    sass('src/scss/honeymon/*.scss', {style: 'compressed'})
        .pipe(rename({suffix: '.min'}))
        .pipe(gulp.dest('build/css/honeymon'));
});

// Default Task
gulp.task('default', ['scripts', 'sass']);

프로젝트에 사용하는 이미지 이동

이제 gulp 에서 많은 시간이 걸리는 작업이 남았다. 스크립트나 스타일시트 작업보다 더 오래 걸릴 것이다. gulp-imagemin 와 gulp-cache 를 이용해서 이미지를 최적화하는 작업을 진행한다.

$ npm install --save-dev gulp-imagemin gulp-cache 

gulp-imagemin 와 gulp-cache 에 대한 의존성을 추가하고 image 태스크를 수정하자.

// Include gulp
var gulp = require('gulp');
// Include plugins
var concat = require('gulp-concat');
var uglify = require('gulp-uglify');
var rename = require('gulp-rename');
var sass = require('gulp-ruby-sass');
var imagemin = require('gulp-imagemin');
var cache = require('gulp-cache');

//Concatenate JS File: src/js 에 있는 파일들을 main.js 로 연결
gulp.task('scripts', function () {
    return gulp.src('src/js/*.js')
        .pipe(concat('honeymon.js'))
        .pipe(rename({suffix: '.min'}))
        .pipe(uglify())
        .pipe(gulp.dest('build/js'));
});

//Move image files
gulp.task('images', function() {
    return gulp.src(srcPath + '/img/**/*')
        .pipe(cache(imagemin({ optimizationLevel: 5, progressive: true, interlaced: true })))
        .pipe(gulp.dest(buildPath + 'img'));
});

//Compile SASS
gulp.task('sass', function () {
    sass('src/scss/style.scss', {style: 'compressed'})
        .pipe(rename({suffix: '.min'}))
        .pipe(gulp.dest('build/css'));
    sass('src/scss/honeymon/*.scss', {style: 'compressed'})
        .pipe(rename({suffix: '.min'}))
        .pipe(gulp.dest('build/css/honeymon'));
});

//Build JavaScript, Images, Sass
gulp.task('build', ['scripts', 'images', 'sass']);

// Default Task
gulp.task('default', ['build']);

실제로 많이 걸린다..

➜  test-front-web git:(master) ✗ gulp
[14:27:52] Using gulpfile ~/workspace/honeymon/test-front-web/gulpfile.js
[14:27:52] Starting 'scripts'...
[14:27:52] Starting 'images'...
[14:27:52] Starting 'sass'...
[14:27:52] Finished 'sass' after 19 ms
[14:27:52] Finished 'scripts' after 147 ms
[14:27:54] Finished 'images' after 2.18 s
[14:27:54] Starting 'build'...
[14:27:54] Finished 'build' after 1.61 μs
[14:27:54] Starting 'default'...
[14:27:54] Finished 'default' after 1.5 μs

프로젝트에서 작성한 html 을 이동시키자.

html 을 옮기는 과정에서는 2가지 작업을 해야한다.

  • src html 에서 보고 있는 *.css 와 *.js 의 경로를 변경해야 한다.
  • build 로 이동시키면서 빌드 컴파일러된 *.css 와 *.js 를 보도록 변경해야 한다.

우선은 src 에서 build 로 이동처리를 먼저 하자.

// Include gulp
var gulp = require('gulp');
// Include plugins
var concat = require('gulp-concat');
var uglify = require('gulp-uglify');
var rename = require('gulp-rename');
var sass = require('gulp-ruby-sass');

var buildPath = 'build/'
var srcPath = 'src/'

//Concatenate JS File: src/js 에 있는 파일들을 main.js 로 연결
gulp.task('scripts', function () {
    return gulp.src(srcPath + 'js/*.js')
        .pipe(concat('honeymon.js'))
        .pipe(rename({suffix: '.min'}))
        .pipe(uglify())
        .pipe(gulp.dest(buildPath + 'js'));
});

//Move image files
gulp.task('images', function() {
    gulp.src(srcPath + 'img')
        .pipe(gulp.dest(buildPath + 'img'));
});

//Compile SASS
gulp.task('sass', function () {
    sass(srcPath + 'scss/style.scss', {style: 'compressed'})
        .pipe(rename({suffix: '.min'}))
        .pipe(gulp.dest(buildPath + 'css'));
    sass(srcPath + 'scss/honeymon/*.scss', {style: 'compressed'})
        .pipe(rename({suffix: '.min'}))
        .pipe(gulp.dest(buildPath + 'css/honeymon'));
});

gulp.task('html-copy', function() {
    gulp.src([srcPath + 'index.html', srcPath + 'sample.html'])
        .pipe(gulp.dest(buildPath))

    gulp.src(srcPath + 'tx/*.html')
        .pipe(gulp.dest(buildPath + '/tx'))
});

//Build JavaScript, Images, Sass
gulp.task('build', ['scripts', 'images', 'sass', 'html-copy']);

// Default Task
gulp.task('default', ['build']);

이제 gulp-html-replace 플러그인을 설치하고 html 을 옮기면서 stylesheet 와 script 를 처리해보자.

$ npm install --save-dev gulp-html-replace

이제 html-copy 테스크에 추가한다.

gulp.task('html-copy', function () {
    //SEE: https://www.npmjs.com/package/gulp-html-replace
    gulp.src([srcPath + 'sample.html'])
        .pipe(htmlReplace({
            css: [
                'css/libs/bootstrap.min.css',
                'css/libs/bootstrap-select.min.css',
                'css/libs/font-awesome/css/font-awesome.min.css',
                'css/style.min.css'
            ],
            js: [
                'js/libs/jquery.min.js',
                'js/libs/bootstrap.min.js',
                'js/libs/bootstrap-select.min.js',
                'js/honeymon.min.js'
            ]
        }))
        .pipe(gulp.dest(buildPath));

    gulp.src([srcPath + 'index.html'])
        .pipe(htmlReplace({
            css: [
                'css/libs/bootstrap.min.css',
                'css/libs/font-awesome/css/font-awesome.min.css',
                'css/libs/bootstrap-select.min.css',
                'css/style.min.css',
                'css/honeymon/index.min.css'
            ],
            js: [
                'js/libs/jquery.min.js',
                'js/libs/bootstrap.min.js',
                'js/libs/bootstrap-select.min.js',
                'js/honeymon.min.js'
            ]
        }))
        .pipe(gulp.dest(buildPath));

    gulp.src(srcPath + 'tx-*.html')
        .pipe(htmlReplace({
            css: [
                'css/libs/bootstrap.min.css',
                'css/libs/font-awesome/css/font-awesome.min.css',
                'css/libs/bootstrap-select.min.css',
                'css/style.min.css',
                'css/honeymon/tx.min.css'
            ],
            js: [
                'js/libs/jquery.min.js',
                'js/libs/bootstrap.min.js',
                'js/libs/bootstrap-select.min.js',
                'js/honeymon.min.js'
            ]
        }))
        .pipe(gulp.dest(buildPath));
});

src 디렉토리 감시하기

이제 src 디렉토리 내에 있는 파일들의 변경사항이 생겼을 때 이를 감지해서 build 태스크를 실행하도록 만들자.

watch 태스크를 생성한다.

gulp.task('watch', function() {
    // Watch .js files
    gulp.watch(srcPath + 'js/*.js', ['scripts']);
    // Watch .scss files
    gulp.watch(srcPath + 'scss/*.scss', ['sass']);
    // Watch image files
    gulp.watch(srcPath + 'images/**/*', ['images']);
});

그 후 기본 태스크에 watch 태스크를 추가한다.

// Include gulp
var gulp = require('gulp');
// Include plugins
var concat = require('gulp-concat');
var uglify = require('gulp-uglify');
var rename = require('gulp-rename');
var sass = require('gulp-ruby-sass');
var imagemin = require('gulp-imagemin');
var cache = require('gulp-cache');
var htmlReplace = require('gulp-html-replace');
var cleanCSS = require('gulp-clean-css');

var buildPath = 'build/'
var srcPath = 'src/'

//Concatenate JS File: src/js 에 있는 파일들을 main.js 로 연결
gulp.task('scripts', function () {
    return gulp.src(srcPath + 'js/*.js')
        .pipe(concat('honeymon.js'))
        .pipe(rename({suffix: '.min'}))
        .pipe(uglify())
        .pipe(gulp.dest(buildPath + 'js'));
});

//MOVE libraries
gulp.task('libraries', function () {
    //Copy Javascript
    gulp.src([
        'node_modules/jquery/dist/jquery.min.js',
        'node_modules/bootstrap/dist/js/bootstrap.min.js',
        'node_modules/bootstrap-select/dist/js/bootstrap-select.min.js'])
        .pipe(gulp.dest(buildPath + 'js/libs'));

    //Copy StyleSheet
    gulp.src([
        'node_modules/bootstrap/dist/css/bootstrap.min.css',
        'node_modules/bootstrap-select/dist/css/bootstrap-select.min.css'])
        .pipe(gulp.dest(buildPath + 'css/libs'));

    //Copy font-awesome
    gulp.src(['./node_modules/font-awesome/css/font-awesome.min.css'])
        .pipe(gulp.dest(buildPath + 'css/libs/font-awesome/css'));
    gulp.src(['./node_modules/font-awesome/fonts/*'])
        .pipe(gulp.dest(buildPath + 'css/libs/font-awesome/fonts'));

    //copy bootstrap
});


//Move image files
gulp.task('images', function () {
    return gulp.src(srcPath + '/img/**/*')
        .pipe(cache(imagemin({optimizationLevel: 5, progressive: true, interlaced: true})))
        .pipe(gulp.dest(buildPath + 'img'));
});

//Compile SASS
gulp.task('sass', function () {
    sass(srcPath + 'scss/style.scss', {style: 'compressed'})
        .pipe(rename({suffix: '.min'}))
        .pipe(gulp.dest(buildPath + 'css'));
    sass(srcPath + 'scss/honeymon/*.scss', {style: 'compressed'})
        .pipe(rename({suffix: '.min'}))
        .pipe(gulp.dest(buildPath + 'css/honeymon'));
});

//Replace html js, css
gulp.task('html-copy', function () {
    //SEE: https://www.npmjs.com/package/gulp-html-replace
    gulp.src([srcPath + 'sample.html'])
        .pipe(htmlReplace({
            css: [
                'css/libs/bootstrap.min.css',
                'css/libs/bootstrap-select.min.css',
                'css/libs/font-awesome/css/font-awesome.min.css',
                'css/style.min.css'
            ],
            js: [
                'js/libs/jquery.min.js',
                'js/libs/bootstrap.min.js',
                'js/libs/bootstrap-select.min.js',
                'js/honeymon.min.js'
            ]
        }))
        .pipe(gulp.dest(buildPath));

    gulp.src([srcPath + 'index.html'])
        .pipe(htmlReplace({
            css: [
                'css/libs/bootstrap.min.css',
                'css/libs/font-awesome/css/font-awesome.min.css',
                'css/libs/bootstrap-select.min.css',
                'css/style.min.css',
                'css/honeymon/index.min.css'
            ],
            js: [
                'js/libs/jquery.min.js',
                'js/libs/bootstrap.min.js',
                'js/libs/bootstrap-select.min.js',
                'js/honeymon.min.js'
            ]
        }))
        .pipe(gulp.dest(buildPath));

    gulp.src(srcPath + 'tx-*.html')
        .pipe(htmlReplace({
            css: [
                'css/libs/bootstrap.min.css',
                'css/libs/font-awesome/css/font-awesome.min.css',
                'css/libs/bootstrap-select.min.css',
                'css/style.min.css',
                'css/honeymon/tx.min.css'
            ],
            js: [
                'js/libs/jquery.min.js',
                'js/libs/bootstrap.min.js',
                'js/libs/bootstrap-select.min.js',
                'js/honeymon.min.js'
            ]
        }))
        .pipe(gulp.dest(buildPath));
});

//Watch project
gulp.task('watch', function () {
    // Watch .js files
    gulp.watch(srcPath + 'js/*.js', ['scripts']);

    // Watch .scss files
    gulp.watch([srcPath + '**/*.scss'], ['sass']);
    // gulp.watch(srcPath + 'scss/honeymon/*.scss', ['sass']);

    // Watch image files
    gulp.watch(srcPath + 'img/**/*', ['images']);

    // Watch .html files
    gulp.watch(srcPath + '*.html', ['html-copy']);
});

//Build JavaScript, Images, Sass
gulp.task('build', ['scripts', 'libraries', 'images', 'sass', 'html-copy']);

// Default Task
gulp.task('default', ['build', 'watch']);

이렇게 테스트가 추가되고 나면 src 내에 작은 변화가 생기면 자동적으로 변환이 진행되며 그 결과를 확인할 수 있게 된다.

gulp 동작 실행

gulp 명령어만 실행하면 다음과 같이 build 태스크에 있는 것들이 실행되고 watch 태스크가 실행되면서 디렉토리의 변경사항을 감시하여 변동사항이 생기면 자동으로 빌드가 진행된다.

/usr/local/bin/node /honeymon/node_modules/gulp/bin/gulp.js --color --gulpfile /honeymon//gulpfile.js default
[10:58:15] Using gulpfile ~/workspace/honeymon/test-front-web/gulpfile.js
[10:58:15] Starting 'scripts'...
[10:58:15] Starting 'libraries'...
[10:58:15] Finished 'libraries' after 7.74 ms
[10:58:15] Starting 'images'...
[10:58:15] Starting 'sass'...
[10:58:15] Finished 'sass' after 33 ms
[10:58:15] Starting 'html-copy'...
[10:58:15] Finished 'html-copy' after 14 ms
[10:58:15] Starting 'watch'...
[10:58:15] Finished 'watch' after 56 ms
[10:58:16] Finished 'scripts' after 272 ms
[10:59:31] Starting 'sass'...
[10:59:31] Finished 'sass' after 6.61 ms
[10:59:32] write ./style.css
[11:00:21] Starting 'sass'...
[11:00:21] Finished 'sass' after 5.03 ms
[11:00:22] write ./style.css

참고문헌


'Javascript > Framework & Libs' 카테고리의 다른 글

Error: Cannot find module 'npmlog' 해결  (2) 2016.09.23

Bower, A package manager for the web
Web sites are made of lots of things — frameworks, libraries, assets, utilities, and rainbows. Bower manages all these things for you.
> 최근의 웹사이트는 다양한 것들(프레임워크, 라이브러리, 자원, 유틸리티 그리고 레인보우(!?))로 만들어진다. Bower는 이 모든 것을 관리한다.

Bower는 찾고자 하는 것들을 각지에서 탐색하고, 다운로드하고, 설치하고 붙인다. Bower는 bower.json 매니페스트 파일을 기준으로 패키지들을 추적관리한다.
어떤 패키지를 사용할지는 사용자에게 달려있다.

Bower는 프론트엔드에 최적화되어 있다. Bower는 간단한 의존성구조, 각 패키지별 대표버전만을 요구하며, 페이지로드를 최소한으로 감소시킨다.

1. Bower 설치

Bower는 커맨드라인 유틸리티다. npm*(https://www.npmjs.com/) 이 설치되어 있어야 한다.

$ npm install -g bower

Bower는 Node 그리고 npm  Git을 필요로 한다.

2. 시작

2.1. 패키지 설치

패키지 설치는 bower install 이용한다. Bower가 설치한 패키지는 bower_components/에 설치된다.

$ bower install <package>

패키지는 github, git 엔드포인트, URL 그리고 기타등등이 가능하다. 보다 자세한 내용은 bower install 을 살펴보기 바란다.

# registered package
$ bower install jquery
# GitHub shorthand
$ bower install desandro/masonry
# Git endpoint
$ bower install git://github.com/user/package.git
# URL
$ bower install http://example.com/script.js

2.2. 패키지 검색

Search Bower pacakge와 선호하는 프로젝트의 등록된 패키지명을 검색한다.

2.3. 패키지 저장

패키지 저장은 bower init 을 통해서 bower.json 에 등록한다.

2.4. 패키지 사용

패키지를 사용하는 것은 사용자가 결정한다. Bower와 함께 Grunt, RequireJS, Yeoman, 그리고 다양한 도구들을 함께 사용하거나,
빌드할때 API를 활용하는 것을 권장한다. 또한 설치된 패키지를, 다음의 jquery사용의 경우처럼, 바로 사용할 수도 있다.

<script src="bower_components/jquery/dist/jquery.min.js"></script>

다음은 RequireJS를 이용하여 각 페이지별 자바스크립트 파일/모듈을 적재해보자.

참고


최근에 나는 프론트쪽을 거의 다루지 않았다. 백엔드쪽에서 프론트에 필요한 API만 만들어서 추가하는 쪽으로 활용했었다. 그래서 툴에 별로 관심을 두지 않아서 Aptna를 이용했었다. 그런데, 운영체제를 자주 밀어버리는 편(우분투를 사용하다보니 이게 일상이다)이라 설치가 가벼운 녀석을 찾았다. 그러다가 우연히 Brackets를 발견했다. 데비안 계열의 운영체제까지 지원한다. 오우.

- 공식사이트: http://brackets.io/

- Github: https://github.com/adobe/brackets

Adobe에서 내놓은 웹플랫폼 개발툴IDE Brackets([])를 소개한다.

모양은 이렇다.

모습도 깔끔하다. node를 기반으로 해서 동작하는 녀석으로 보인다.

현재 36번째 릴리즈버전이 출시되었고, 지속적으로 출시가 될 것으로 보인다. 쓸만한 플러그인들도 많이 제공한다. 


한글화도 잘 되어 있다.

JCO에서 발표했던 REST API에 대한 백엔드를 직접 활용하는 예제를 작성하고 있는 중이다.

실시간 미리보기 기능(현재는 크롬chrome 브라우저에 대해서만 지원)도 지원(Ctrl + Alt + P(review))한다. 코드를 수정 후에 저장하면 바로 브라우저에 갱신신호가 가면서 다시 읽는 것으로 보인다. 아마... 크롬 내부의 API겠지?

태그에서 지정한 class에 대한 CSS 파일도 바로호출이 가능하며,

선택된 class에 적용대상을 미리보기로 호출된 브라우저에 표시도 해준다.

사용자 폴더에 설정파일인 brackets.json 을 수정하여 환경을 설정할 수 있다(지만 귀찮다). 나름 중요한 탭형식과 사이즈 조정은 편집기 오른쪽 하단에 입력하여 설정할 수 있다. 기본은 '스페이스, 크기 4'로 설정되어 있는데, 프론트 쪽에서는 '스페이스 크기 2'를 선호하기에 바꿔봤다. 그러면 brackets.json에 설정내용이 추가된다.


ㅡ_-); 이때 이야기했던 28일되면 VM 인스턴스 내릴거에요.

라고 한 이야기가 거짓말이 되었다. 두둥. AngularJS 공부도 할겸해서 예제를 만들고 있다. 코드만 보여줘서는 의미가 많이 약해질 것이라는 개인적인 욕심이 어울어져 이런 일을 벌이게 되었다. 흠… 지금 예제가 돌고 있는 서버에 CI를 설치해둘까 하는 생각이 들었는데… 문득, OpenShift에서 Jenkins 기어만들고 거기서 빌드하도록 만들면 되겠구나…!! 하는 생각이 든다. ㅎㅎ 돈이 굳었다. ㅡ_-);;

OpenShift에 대해서는 아래내용을 참고하세요.

2014/02/28 - [Java/Tools] - 무료로 쓸만한 통합된 개발환경 시스템 OpenShift(By redhat)를 소개합니다.

프로젝트는… ihoneymon@github.com/rocking-the-rest-api-view를 참고하기 바란다. Yeoman을 활용해서 웹애플리케이션을 초기생성했다.

Yeoman으로 AngularJS 프로젝트 구성하기(http://www.hans.or.kr/2014/02/yeoman-angularjs.html)

위의 내용을 이용해서 초기화를 하고 작업 진행중이다.


깃헙github에서 내놓을 Atom editor(https://atom.io/)이 정식 출시되기 전까지는 쓸만한 녀석으로 보인다.

Atom editor 소개(http://blog.outsider.ne.kr/1035)

Atom editor가 정식 출시가 되면(리눅스도 지원한다면) 바로 옮겨가지 않을까? ㅡ_-)?

Agenda

  • AngularJS Feature
  • Getting Started
  • Directives, Filters and Data binding
  • Views, Controllers and Scope
  • Modules, Routes and Factories

AgularJS Feature


Getting Started

  • Single Page Application(SPA)

    View1 -> View2 -> View3 -> View1

  • Challenge with SPAs

    DOM manipulation, History, Module loading, Routing, Caching, Object Modeling, Data binding, Ajax/Promises, View loading

  • AgularJS를 이용하면 하나의 프레임워크로 모든 기능을 사용할 수 있다.
  • AuglarJS is a full-featured SPA Framework.
    • ViewModel, Controllers, Views

Directives, Filters and Data binding

  • Directives

    • HTML new tricks
      <!DOCUTYPE html>
      <html ng-app> // Directive
      <head>
        <title></title>
      </head>
      <body>
        <div class="container">
            //ng-model is Directive
            // {{name}} is data binding expression
            Name: <input type="text" ng-model="name" /> {{name}}
        </div>
        <script src=""></script>
      </body>
      <html>
      
    • 참고 링크

    • ng-repeat: data-ng-app=”” -> data-ng-init=”names=[]” data-ng-

        <li data-ng-repeat="personName in names">{{personName}}</li>
      
  • Using Filters
    <li data-ng-repeat="cust in customers | filter:nameText | orderBy:'name'">{{cust.name}}-{{cust.city}}</li>
    

Views, Controllers and Scope

[View] <— $scope —> [Controller]
$scope is the “glue” (ViewModel)

  • Createing a View and Controller
    {{name}}
    function SimpleController($scope) {
      // $scope Dynamic inject
      $scope.customers=[{name:"", city:""}]
    }
    

Modules, Routes and Factories

  • Module -> Config -> Routes (->View ->Controller ->(*Factory): View <— $scope —> Controller)
  • Modules are Containers
    <html ng-app="moduleName">
    
  • Module

    • Config
      • Routes
    • Filter
    • Directive
    • Factory, Service, Provider, Value
    • Controller
      var demoApp = angular.module('demoApp', []);
      // What's the Array for?
      // Module that demoApp depends on ->[]
      var demoApp = angular.module('demoApp', ['helperModule']);
      
  • Creating a Controller in a module

      var demoApp = angular.module('demoApp', []);    //define a module
    
      demoApp.controller('SimpleController', function($scope) {    // define a controller
          $scope.customers = [
              //...
          ]
      });
    
  • the Role of Routes

    View1(/view1) -> View2(/view2) -> View3(/view3) -> View4(/view4) -> View1

      var demoApp = angular.module('demoApp', []);
    
      demoApp.config(function($routeProvider) {
          $routeProvider
              .when('/', // define Module Routes
                  {
                      contoller: 'SimpleController',
                      templateUrl: 'View1.html'
                  })
              .when('/partial2',
                  {
                      contoller: 'SimpleController',
                      templateUrl: 'View2.html'
                  })
              .otherwise({ redirectTo: '/'});
      });
    
  • Using Factories and Services

    • The Role of Factories
        var demoApp = angular.module('demoApp', [])
            .factory('simpleFactory', function() {
                var factory = {};
                var customers = {...};
                factory.getCustomers = function() {
                    return customers;
                };
                return factory;
            })
            .controller('SimpleController' function($scope, simpleFactory) {
                $scope.customers = simpleFactory.getCustomer();
            });
      
  • jQuery only used for Bootstrap

  • 참고 링크

참고링크


+ Recent posts