CentOSにnvmを導入して、npm+lessc環境を構築する

2013年12月23日 15時26分

201312231526HCSC00.png

はじめに

当サイトでも使用しているBootstrap 3は、多くのウエブ開発者からの支持を得ています。Bootstapは、元々lessというCSS拡張メタ言語で書かれており、lessで書かれたソースコードをコンパイルすることで、CSSを生成しています。
今回は、CSSの記述やBootstrapのカスタマイズに無くてはならないless環境の構築方法について解説します。

前提条件

作業の前提条件は、下記のとおりです。

ソフトウエアバージョン
OSWindows 7 Ultimate 32bit
CygwinSetup Version 2.831
VirtualBox4.3.6 r91406
Vagrant1.4.1

構築するサーバのスペックは、下記のとおりです。

ソフトウエアバージョン
CentOS6.5 i386
nvm0.0.3
Node.js0.10.24
less1.5.1
grunt-cli0.1.13

LESS環境の構築

CentOS 6.5-i386-minimalのBoxを起動し、LESSが利用可能なBoxを作成します。

  1. manパッケージのインストール

    minimal構成のCentOSには、manがインストールされていませんので、予めインストールしておきます。

    $ sudo yum -y install man
    
  2. nvmのインストール

    Node.jsは、バージョンアップも頻繁に行われているため、rbenvと同様に複数のnode.jsを切り替えて使用できるnvm(Node.js Version Manager)をgithubからインストールします。

    $ git clone git://github.com/creationix/nvm.git ~/.nvm
    $ source ~/.nvm/nvm.sh
    
    $ git clone git://github.com/creationix/nvm.git ~/.nvm
    Initialized empty Git repository in /home/vagrant/.nvm/.git/
    remote: Counting objects: 1412, done.
    remote: Compressing objects: 100% (710/710), done.
    remote: Total 1412 (delta 706), reused 1376 (delta 685)
    Receiving objects: 100% (1412/1412), 255.45 KiB | 214 KiB/s, done.
    Resolving deltas: 100% (706/706), done.
    
    201312231526HCSC01.png
  3. Node.jsのインストール

    nvmを使用して、Node.jsをインストールします。インストールすると、npm(Node Package Manager)も一緒にインストールされます。

    $ nvm install v0.10.24
    
    $ nvm install v0.10.24
    ######################################################################## 100.0%
    Now using node v0.10.24
    
    201312231526HCSC02.png
  4. .bashrcの編集

    Node.jsのインストールが終了したら、~/.bashrcを編集します。

    $ vi ~/.bashrc
    
    if [ -f ~/.nvm/nvm.sh ]; then
      source ~/.nvm/nvm.sh
      nvm use v0.10.24
    fi
    
    $ source ~/.bashrc
    $ npm -v && node -v
    
    201312231526HCSC03.png
  5. lessのインストール

    lessのインストールに必要なパッケージが全てインストールできましたので、npmを使ってlessをインストールします。

    $ npm install -g less
    
    npm http GET https://registry.npmjs.org/less
    npm http 200 https://registry.npmjs.org/less
    npm http GET https://registry.npmjs.org/less/-/less-1.7.0.tgz
    npm http 200 https://registry.npmjs.org/less/-/less-1.7.0.tgz
    npm http GET https://registry.npmjs.org/mkdirp
    npm http GET https://registry.npmjs.org/request
    npm http GET https://registry.npmjs.org/clean-css
    npm http GET https://registry.npmjs.org/source-map
    npm http GET https://registry.npmjs.org/mime
    npm http 200 https://registry.npmjs.org/source-map
    npm http GET https://registry.npmjs.org/source-map/-/source-map-0.1.33.tgz
    npm http 200 https://registry.npmjs.org/mkdirp
    npm http GET https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.5.tgz
    npm http 200 https://registry.npmjs.org/clean-css
    npm http GET https://registry.npmjs.org/clean-css/-/clean-css-2.1.8.tgz
    npm http 200 https://registry.npmjs.org/request
    npm http GET https://registry.npmjs.org/request/-/request-2.34.0.tgz
    npm http 200 https://registry.npmjs.org/source-map/-/source-map-0.1.33.tgz
    npm http 200 https://registry.npmjs.org/mime
    npm http GET https://registry.npmjs.org/mime/-/mime-1.2.11.tgz
    npm http 200 https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.5.tgz
    npm http 200 https://registry.npmjs.org/clean-css/-/clean-css-2.1.8.tgz
    npm http 200 https://registry.npmjs.org/request/-/request-2.34.0.tgz
    npm http 200 https://registry.npmjs.org/mime/-/mime-1.2.11.tgz
    npm http GET https://registry.npmjs.org/forever-agent
    npm http GET https://registry.npmjs.org/qs
    npm http GET https://registry.npmjs.org/json-stringify-safe
    npm http GET https://registry.npmjs.org/node-uuid
    npm http GET https://registry.npmjs.org/tough-cookie
    npm http GET https://registry.npmjs.org/form-data
    npm http GET https://registry.npmjs.org/tunnel-agent
    npm http GET https://registry.npmjs.org/http-signature
    npm http GET https://registry.npmjs.org/oauth-sign
    npm http GET https://registry.npmjs.org/hawk
    npm http GET https://registry.npmjs.org/aws-sign2
    npm http GET https://registry.npmjs.org/commander
    npm http GET https://registry.npmjs.org/amdefine
    npm http 200 https://registry.npmjs.org/json-stringify-safe
    npm http 200 https://registry.npmjs.org/forever-agent
    npm http GET https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.0.tgz
    npm http 200 https://registry.npmjs.org/qs
    npm http GET https://registry.npmjs.org/forever-agent/-/forever-agent-0.5.2.tgz
    npm http GET https://registry.npmjs.org/qs/-/qs-0.6.6.tgz
    npm http 200 https://registry.npmjs.org/node-uuid
    npm http 200 https://registry.npmjs.org/tunnel-agent
    npm http 200 https://registry.npmjs.org/form-data
    npm http 200 https://registry.npmjs.org/http-signature
    npm http 200 https://registry.npmjs.org/oauth-sign
    npm http 200 https://registry.npmjs.org/aws-sign2
    npm http 200 https://registry.npmjs.org/amdefine
    npm http 200 https://registry.npmjs.org/commander
    npm http 200 https://registry.npmjs.org/hawk
    npm http GET https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.1.tgz
    npm http GET https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.3.0.tgz
    npm http GET https://registry.npmjs.org/form-data/-/form-data-0.1.2.tgz
    npm http GET https://registry.npmjs.org/http-signature/-/http-signature-0.10.0.tgz
    npm http GET https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.3.0.tgz
    npm http GET https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.5.0.tgz
    npm http GET https://registry.npmjs.org/amdefine/-/amdefine-0.1.0.tgz
    npm http GET https://registry.npmjs.org/commander/-/commander-2.1.0.tgz
    npm http GET https://registry.npmjs.org/hawk/-/hawk-1.0.0.tgz
    npm http 200 https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.0.tgz
    npm http 200 https://registry.npmjs.org/tough-cookie
    npm http 200 https://registry.npmjs.org/forever-agent/-/forever-agent-0.5.2.tgz
    npm http 200 https://registry.npmjs.org/form-data/-/form-data-0.1.2.tgz
    npm http 200 https://registry.npmjs.org/qs/-/qs-0.6.6.tgz
    npm http 200 https://registry.npmjs.org/http-signature/-/http-signature-0.10.0.tgz
    npm http 200 https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.3.0.tgz
    npm http 200 https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.5.0.tgz
    npm http GET https://registry.npmjs.org/tough-cookie/-/tough-cookie-0.12.1.tgz
    npm http 200 https://registry.npmjs.org/amdefine/-/amdefine-0.1.0.tgz
    npm http 200 https://registry.npmjs.org/commander/-/commander-2.1.0.tgz
    npm http 200 https://registry.npmjs.org/hawk/-/hawk-1.0.0.tgz
    npm http 200 https://registry.npmjs.org/tough-cookie/-/tough-cookie-0.12.1.tgz
    npm http 200 https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.1.tgz
    npm http 200 https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.3.0.tgz
    npm http GET https://registry.npmjs.org/combined-stream
    npm http GET https://registry.npmjs.org/async
    npm http GET https://registry.npmjs.org/ctype/0.5.2
    npm http GET https://registry.npmjs.org/assert-plus/0.1.2
    npm http GET https://registry.npmjs.org/asn1/0.1.11
    npm http GET https://registry.npmjs.org/punycode
    npm http GET https://registry.npmjs.org/hoek
    npm http GET https://registry.npmjs.org/boom
    npm http GET https://registry.npmjs.org/cryptiles
    npm http GET https://registry.npmjs.org/sntp
    npm http 200 https://registry.npmjs.org/combined-stream
    npm http 200 https://registry.npmjs.org/assert-plus/0.1.2
    npm http 200 https://registry.npmjs.org/async
    npm http 200 https://registry.npmjs.org/ctype/0.5.2
    npm http GET https://registry.npmjs.org/combined-stream/-/combined-stream-0.0.4.tgz
    npm http GET https://registry.npmjs.org/assert-plus/-/assert-plus-0.1.2.tgz
    npm http GET https://registry.npmjs.org/async/-/async-0.2.10.tgz
    npm http 200 https://registry.npmjs.org/punycode
    npm http 200 https://registry.npmjs.org/cryptiles
    npm http 200 https://registry.npmjs.org/hoek
    npm http 200 https://registry.npmjs.org/boom
    npm http 200 https://registry.npmjs.org/sntp
    npm http GET https://registry.npmjs.org/ctype/-/ctype-0.5.2.tgz
    npm http 200 https://registry.npmjs.org/asn1/0.1.11
    npm http GET https://registry.npmjs.org/punycode/-/punycode-1.2.4.tgz
    npm http GET https://registry.npmjs.org/cryptiles/-/cryptiles-0.2.2.tgz
    npm http GET https://registry.npmjs.org/hoek/-/hoek-0.9.1.tgz
    npm http GET https://registry.npmjs.org/boom/-/boom-0.4.2.tgz
    npm http GET https://registry.npmjs.org/sntp/-/sntp-0.2.4.tgz
    npm http GET https://registry.npmjs.org/asn1/-/asn1-0.1.11.tgz
    npm http 200 https://registry.npmjs.org/combined-stream/-/combined-stream-0.0.4.tgz
    npm http 200 https://registry.npmjs.org/cryptiles/-/cryptiles-0.2.2.tgz
    npm http 200 https://registry.npmjs.org/assert-plus/-/assert-plus-0.1.2.tgz
    npm http 200 https://registry.npmjs.org/async/-/async-0.2.10.tgz
    npm http 200 https://registry.npmjs.org/hoek/-/hoek-0.9.1.tgz
    npm http 200 https://registry.npmjs.org/boom/-/boom-0.4.2.tgz
    npm http 200 https://registry.npmjs.org/sntp/-/sntp-0.2.4.tgz
    npm http 200 https://registry.npmjs.org/asn1/-/asn1-0.1.11.tgz
    npm http GET https://registry.npmjs.org/delayed-stream/0.0.5
    npm http 200 https://registry.npmjs.org/ctype/-/ctype-0.5.2.tgz
    npm http 200 https://registry.npmjs.org/punycode/-/punycode-1.2.4.tgz
    npm http 200 https://registry.npmjs.org/delayed-stream/0.0.5
    npm http GET https://registry.npmjs.org/delayed-stream/-/delayed-stream-0.0.5.tgz
    npm http 200 https://registry.npmjs.org/delayed-stream/-/delayed-stream-0.0.5.tgz
    /home/vagrant/.nvm/v0.10.24/bin/lessc -> /home/vagrant/.nvm/v0.10.24/lib/node_modules/less/bin/lessc
    less@1.7.0 /home/vagrant/.nvm/v0.10.24/lib/node_modules/less
    ├── mime@1.2.11
    ├── mkdirp@0.3.5
    ├── clean-css@2.1.8 (commander@2.1.0)
    ├── source-map@0.1.33 (amdefine@0.1.0)
    └── request@2.34.0 (json-stringify-safe@5.0.0, forever-agent@0.5.2, aws-sign2@0.5.0, qs@0.6.6, tunnel-agent@0.3.0, oauth-sign@0.3.0, node-uuid@1.4.1, hawk@1.0.0, tough-cookie@0.12.1, http-signature@0.10.0, form-data@0.1.2)
    
    201312231526HCSC04.png
    201312231526HCSC05.png

    グローバル環境にインストールされたパッケージを表示します。

    $ npm ls -g
    
    /home/vagrant/.nvm/v0.10.24/lib
    ├─┬ less@1.7.0
    │ ├─┬ clean-css@2.1.8
    │ │ └── commander@2.1.0
    │ ├── mime@1.2.11
    │ ├── mkdirp@0.3.5
    │ ├─┬ request@2.34.0
    │ │ ├── aws-sign2@0.5.0
    │ │ ├── forever-agent@0.5.2
    │ │ ├─┬ form-data@0.1.2
    │ │ │ ├── async@0.2.10
    │ │ │ └─┬ combined-stream@0.0.4
    │ │ │   └── delayed-stream@0.0.5
    │ │ ├─┬ hawk@1.0.0
    │ │ │ ├── boom@0.4.2
    │ │ │ ├── cryptiles@0.2.2
    │ │ │ ├── hoek@0.9.1
    │ │ │ └── sntp@0.2.4
    │ │ ├─┬ http-signature@0.10.0
    │ │ │ ├── asn1@0.1.11
    │ │ │ ├── assert-plus@0.1.2
    │ │ │ └── ctype@0.5.2
    │ │ ├── json-stringify-safe@5.0.0
    │ │ ├── node-uuid@1.4.1
    │ │ ├── oauth-sign@0.3.0
    │ │ ├── qs@0.6.6
    │ │ ├─┬ tough-cookie@0.12.1
    │ │ │ └── punycode@1.2.4
    │ │ └── tunnel-agent@0.3.0
    │ └─┬ source-map@0.1.33
    │   └── amdefine@0.1.0
    └─┬ npm@1.3.21
      ├── abbrev@1.0.4
      ├── ansi@0.2.1
      ├── ansicolors@0.3.2
      ├── ansistyles@0.1.3
      ├── archy@0.0.2
      ├── block-stream@0.0.7
      ├── child-process-close@0.1.1
      ├── chmodr@0.1.0
      ├── chownr@0.0.1
      ├── cmd-shim@1.1.1
      ├── editor@0.0.5
      ├── fstream@0.1.25
      ├─┬ fstream-npm@0.1.6
      │ └── fstream-ignore@0.0.7
      ├── github-url-from-git@1.1.1
      ├── github-url-from-username-repo@0.0.2
      ├── glob@3.2.7
      ├── graceful-fs@2.0.1
      ├── inherits@2.0.1
      ├── ini@1.1.0
      ├─┬ init-package-json@0.0.14
      │ └── promzard@0.2.0
      ├── lockfile@0.4.2
      ├── lru-cache@2.5.0
      ├─┬ minimatch@0.2.14
      │ └── sigmund@1.0.0
      ├── mkdirp@0.3.5
      ├── node-gyp@0.12.1
      ├── nopt@2.1.2
      ├─┬ npm-registry-client@0.3.2
      │ └── couch-login@0.1.19
      ├── npm-user-validate@0.0.3
      ├─┬ npmconf@0.1.9
      │ └─┬ config-chain@1.1.8
      │   └── proto-list@1.2.2
      ├── npmlog@0.0.6
      ├── once@1.3.0
      ├── opener@1.3.0
      ├── osenv@0.0.3
      ├── path-is-inside@1.0.0
      ├─┬ read@1.0.5
      │ └── mute-stream@0.0.4
      ├── read-installed@0.2.5
      ├─┬ read-package-json@1.1.4
      │ └── normalize-package-data@0.2.7
      ├─┬ request@2.30.0
      │ ├── aws-sign2@0.5.0
      │ ├── forever-agent@0.5.0
      │ ├─┬ form-data@0.1.2
      │ │ ├── async@0.2.9
      │ │ └─┬ combined-stream@0.0.4
      │ │   └── delayed-stream@0.0.5
      │ ├─┬ hawk@1.0.0
      │ │ ├── boom@0.4.2
      │ │ ├── cryptiles@0.2.2
      │ │ ├── hoek@0.9.1
      │ │ └── sntp@0.2.4
      │ ├─┬ http-signature@0.10.0
      │ │ ├── asn1@0.1.11
      │ │ ├── assert-plus@0.1.2
      │ │ └── ctype@0.5.2
      │ ├── json-stringify-safe@5.0.0
      │ ├── mime@1.2.11
      │ ├── node-uuid@1.4.1
      │ ├── oauth-sign@0.3.0
      │ ├── qs@0.6.6
      │ ├─┬ tough-cookie@0.9.15
      │ │ └── punycode@1.2.3
      │ └── tunnel-agent@0.3.0
      ├── retry@0.6.0
      ├── rimraf@2.2.5
      ├── semver@2.2.1
      ├─┬ sha@1.2.3
      │ └── readable-stream@1.0.17
      ├── slide@1.1.5
      ├── tar@0.1.19
      ├── text-table@0.2.0
      ├── uid-number@0.0.3
      └── which@1.0.5
    
    201312231526HCSC06.png
    201312231526HCSC07.png
  6. コンパイル確認

    lessをインストールすると、lessファイルをCSSにコンパイルするlessc(Less Compiler)がインストールされますので、lessファイルを作成してコンパイル確認します。

    $ mkdir -p ~/less && cd ~/less
    $ vi sample.less
    
    @base: #f938ab;
    
    .box-shadow(@style, @c) when (iscolor(@c)) {
      -webkit-box-shadow: @style @c;
      -moz-box-shadow:    @style @c;
      box-shadow:         @style @c;
    }
    .box-shadow(@style, @alpha: 50%) when (isnumber(@alpha)) {
      .box-shadow(@style, rgba(0, 0, 0, @alpha));
    }
    .box {
      color: saturate(@base, 5%);
      border-color: lighten(@base, 30%);
      div { .box-shadow(0 0 5px, 30%) }
    }
    

    CSSにコンパイルします。

    $ lessc sample.less
    
    .box {
      color: #fe33ac;
      border-color: #fdcdea;
    }
    .box div {
      -webkit-box-shadow: 0 0 5px rgba(0, 0, 0, 0.3);
      -moz-box-shadow: 0 0 5px rgba(0, 0, 0, 0.3);
      box-shadow: 0 0 5px rgba(0, 0, 0, 0.3);
    }
    
    201312231526HCSC08.png

    -xオプションを付けると、圧縮された状態でコンパイルできます。

    $ lessc -x sample.less
    
    .box{color:#fe33ac;border-color:#fdcdea}.box div{-webkit-box-shadow:0 0 5px rgba(0,0,0,0.3);-moz-box-shadow:0 0 5px rgba(0,0,0,0.3);box-shadow:0 0 5px rgba(0,0,0,0.3)}
    
    201312231526HCSC09.png

    第二引数にファイル名を指定すると、指定されたファイルにコンパイル結果を出力します。

    $ lessc sample.less sample.css
    $ cat sample.css
    
    201312231526HCSC10.png

CSSコンパイルの自動化

ここまでの作業で、LESS→CSSコンパイルのための環境は構築できましたが、LESSファイルを更新する度に、毎回コンパイルするのはやはり面倒ですので、gruntを使用してLESS→CSSコンパイルを自動化します。

  1. grunt-cliのインストール

    Gruntは、JavaScriptで書かれた定義ファイル(Gruntfile.js)に定義されたタスクを実行するタスク監視ツールです。例えば、Gruntfile.jsにLESS→CSSコンパイルをタスクとして定義しておくと、LESSファイルが更新されると同時に、CSSにコンパイルされます。

    $ npm install -g grunt-cli
    
    npm http GET https://registry.npmjs.org/grunt-cli
    npm http 200 https://registry.npmjs.org/grunt-cli
    npm http GET https://registry.npmjs.org/grunt-cli/-/grunt-cli-0.1.13.tgz
    npm http 200 https://registry.npmjs.org/grunt-cli/-/grunt-cli-0.1.13.tgz
    npm http GET https://registry.npmjs.org/resolve
    npm http GET https://registry.npmjs.org/nopt
    npm http GET https://registry.npmjs.org/findup-sync
    npm http 200 https://registry.npmjs.org/resolve
    npm http GET https://registry.npmjs.org/resolve/-/resolve-0.3.1.tgz
    npm http 200 https://registry.npmjs.org/findup-sync
    npm http 200 https://registry.npmjs.org/nopt
    npm http GET https://registry.npmjs.org/findup-sync/-/findup-sync-0.1.3.tgz
    npm http GET https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz
    npm http 200 https://registry.npmjs.org/resolve/-/resolve-0.3.1.tgz
    npm http 200 https://registry.npmjs.org/findup-sync/-/findup-sync-0.1.3.tgz
    npm http 200 https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz
    npm http GET https://registry.npmjs.org/abbrev
    npm http GET https://registry.npmjs.org/lodash
    npm http GET https://registry.npmjs.org/glob
    npm http 200 https://registry.npmjs.org/glob
    npm http GET https://registry.npmjs.org/glob/-/glob-3.2.9.tgz
    npm http 200 https://registry.npmjs.org/abbrev
    npm http 200 https://registry.npmjs.org/lodash
    npm http GET https://registry.npmjs.org/abbrev/-/abbrev-1.0.5.tgz
    npm http GET https://registry.npmjs.org/lodash/-/lodash-2.4.1.tgz
    npm http 200 https://registry.npmjs.org/glob/-/glob-3.2.9.tgz
    npm http 200 https://registry.npmjs.org/abbrev/-/abbrev-1.0.5.tgz
    npm http 200 https://registry.npmjs.org/lodash/-/lodash-2.4.1.tgz
    npm http GET https://registry.npmjs.org/minimatch
    npm http GET https://registry.npmjs.org/inherits
    npm http 200 https://registry.npmjs.org/inherits
    npm http 200 https://registry.npmjs.org/minimatch
    npm http GET https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz
    npm http GET https://registry.npmjs.org/minimatch/-/minimatch-0.2.14.tgz
    npm http 200 https://registry.npmjs.org/minimatch/-/minimatch-0.2.14.tgz
    npm http 200 https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz
    npm http GET https://registry.npmjs.org/lru-cache
    npm http GET https://registry.npmjs.org/sigmund
    npm http 200 https://registry.npmjs.org/sigmund
    npm http GET https://registry.npmjs.org/sigmund/-/sigmund-1.0.0.tgz
    npm http 200 https://registry.npmjs.org/lru-cache
    npm http GET https://registry.npmjs.org/lru-cache/-/lru-cache-2.5.0.tgz
    npm http 200 https://registry.npmjs.org/sigmund/-/sigmund-1.0.0.tgz
    npm http 200 https://registry.npmjs.org/lru-cache/-/lru-cache-2.5.0.tgz
    /home/vagrant/.nvm/v0.10.24/bin/grunt -> /home/vagrant/.nvm/v0.10.24/lib/node_modules/grunt-cli/bin/grunt
    grunt-cli@0.1.13 /home/vagrant/.nvm/v0.10.24/lib/node_modules/grunt-cli
    ├── resolve@0.3.1
    ├── nopt@1.0.10 (abbrev@1.0.5)
    └── findup-sync@0.1.3 (lodash@2.4.1, glob@3.2.9)
    
    201312231526HCSC11.png
    201312231526HCSC12.png
  2. 初期化

    監視したいフォルダ(通常、プロジェクトごとのフォルダ)を作成し、initコマンドを実行して、package.jsonファイルを作成します。

    $ mkdir -p ~/sample && cd ~/sample
    $ npm init
    
    This utility will walk you through creating a package.json file.
    It only covers the most common items, and tries to guess sane defaults.
    
    See `npm help json` for definitive documentation on these fields
    and exactly what they do.
    
    Use `npm install <pkg> --save` afterwards to install a package and
    save it as a dependency in the package.json file.
    
    Press ^C at any time to quit.
    name: (sample)
    version: (0.0.0)
    description: sample
    entry point: (index.js)
    test command:
    git repository:
    keywords:
    author: puniochan
    license: (ISC)
    About to write to /home/vagrant/sample/package.json:
    
    {
      "name": "sample",
      "version": "0.0.0",
      "description": "sample",
      "main": "index.js",
      "scripts": {
        "test": "echo \"Error: no test specified\" && exit 1"
      },
      "author": "puniochan",
      "license": "ISC"
    }
    
    
    Is this ok? (yes)
    

    ハイライトで表示された13,18行目以外は、デフォルトでも構いません。なお、package.jsonはいつでも修正できますので、全てデフォルトのまま作成し、後で修正しても構いません。

    201312231526HCSC13.png
    201312231526HCSC14.png
  3. Gruntのインストール

    --save-devオプションを付けて、Gruntコアパッケージをインストールします。
    オプションを指定すると、インストールされたパッケージをpackage.jsonに追加できますので、必ず指定しましょう。

    $ npm install grunt --save-dev
    
    npm WARN package.json sample@0.0.0 No repository field.
    npm WARN package.json sample@0.0.0 No README data
    npm http GET https://registry.npmjs.org/grunt
    npm http 200 https://registry.npmjs.org/grunt
    npm http GET https://registry.npmjs.org/grunt/-/grunt-0.4.5.tgz
    npm http 200 https://registry.npmjs.org/grunt/-/grunt-0.4.5.tgz
    npm http GET https://registry.npmjs.org/colors
    npm http GET https://registry.npmjs.org/dateformat/1.0.2-1.2.3
    npm http GET https://registry.npmjs.org/eventemitter2
    npm http GET https://registry.npmjs.org/hooker
    npm http GET https://registry.npmjs.org/iconv-lite
    npm http GET https://registry.npmjs.org/rimraf
    npm http GET https://registry.npmjs.org/underscore.string
    npm http GET https://registry.npmjs.org/which
    npm http GET https://registry.npmjs.org/js-yaml
    npm http GET https://registry.npmjs.org/exit
    npm http GET https://registry.npmjs.org/getobject
    npm http GET https://registry.npmjs.org/grunt-legacy-util
    npm http GET https://registry.npmjs.org/grunt-legacy-log
    npm http GET https://registry.npmjs.org/coffee-script
    npm http GET https://registry.npmjs.org/findup-sync
    npm http GET https://registry.npmjs.org/minimatch
    npm http GET https://registry.npmjs.org/glob
    npm http GET https://registry.npmjs.org/nopt
    npm http GET https://registry.npmjs.org/lodash
    npm http GET https://registry.npmjs.org/async
    npm http 200 https://registry.npmjs.org/hooker
    npm http GET https://registry.npmjs.org/hooker/-/hooker-0.2.3.tgz
    npm http 200 https://registry.npmjs.org/colors
    npm http 200 https://registry.npmjs.org/eventemitter2
    npm http GET https://registry.npmjs.org/colors/-/colors-0.6.2.tgz
    npm http GET https://registry.npmjs.org/eventemitter2/-/eventemitter2-0.4.13.tgz
    npm http 200 https://registry.npmjs.org/dateformat/1.0.2-1.2.3
    npm http 200 https://registry.npmjs.org/which
    npm http 200 https://registry.npmjs.org/underscore.string
    npm http 200 https://registry.npmjs.org/js-yaml
    npm http 200 https://registry.npmjs.org/rimraf
    npm http 200 https://registry.npmjs.org/exit
    npm http 200 https://registry.npmjs.org/getobject
    npm http 200 https://registry.npmjs.org/grunt-legacy-util
    npm http 200 https://registry.npmjs.org/grunt-legacy-log
    npm http 304 https://registry.npmjs.org/minimatch
    npm http 304 https://registry.npmjs.org/glob
    npm http 200 https://registry.npmjs.org/coffee-script
    npm http 304 https://registry.npmjs.org/findup-sync
    npm http 304 https://registry.npmjs.org/nopt
    npm http 304 https://registry.npmjs.org/lodash
    npm http 304 https://registry.npmjs.org/async
    npm http GET https://registry.npmjs.org/glob/-/glob-3.1.21.tgz
    npm http GET https://registry.npmjs.org/lodash/-/lodash-0.9.2.tgz
    npm http GET https://registry.npmjs.org/async/-/async-0.1.22.tgz
    npm http GET https://registry.npmjs.org/which/-/which-1.0.5.tgz
    npm http GET https://registry.npmjs.org/underscore.string/-/underscore.string-2.2.1.tgz
    npm http GET https://registry.npmjs.org/js-yaml/-/js-yaml-2.0.5.tgz
    npm http GET https://registry.npmjs.org/rimraf/-/rimraf-2.2.8.tgz
    npm http GET https://registry.npmjs.org/exit/-/exit-0.1.2.tgz
    npm http GET https://registry.npmjs.org/getobject/-/getobject-0.1.0.tgz
    npm http GET https://registry.npmjs.org/grunt-legacy-util/-/grunt-legacy-util-0.2.0.tgz
    npm http GET https://registry.npmjs.org/grunt-legacy-log/-/grunt-legacy-log-0.1.1.tgz
    npm http GET https://registry.npmjs.org/coffee-script/-/coffee-script-1.3.3.tgz
    npm http 200 https://registry.npmjs.org/iconv-lite
    npm http GET https://registry.npmjs.org/dateformat/-/dateformat-1.0.2-1.2.3.tgz
    npm http 200 https://registry.npmjs.org/hooker/-/hooker-0.2.3.tgz
    npm http 200 https://registry.npmjs.org/async/-/async-0.1.22.tgz
    npm http GET https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.2.11.tgz
    npm http 200 https://registry.npmjs.org/which/-/which-1.0.5.tgz
    npm http 200 https://registry.npmjs.org/underscore.string/-/underscore.string-2.2.1.tgz
    npm http 200 https://registry.npmjs.org/colors/-/colors-0.6.2.tgz
    npm http 200 https://registry.npmjs.org/eventemitter2/-/eventemitter2-0.4.13.tgz
    npm http 200 https://registry.npmjs.org/js-yaml/-/js-yaml-2.0.5.tgz
    npm http 200 https://registry.npmjs.org/rimraf/-/rimraf-2.2.8.tgz
    npm http 200 https://registry.npmjs.org/exit/-/exit-0.1.2.tgz
    npm http 200 https://registry.npmjs.org/getobject/-/getobject-0.1.0.tgz
    npm http 200 https://registry.npmjs.org/grunt-legacy-util/-/grunt-legacy-util-0.2.0.tgz
    npm http 200 https://registry.npmjs.org/grunt-legacy-log/-/grunt-legacy-log-0.1.1.tgz
    npm http 200 https://registry.npmjs.org/coffee-script/-/coffee-script-1.3.3.tgz
    npm http 200 https://registry.npmjs.org/dateformat/-/dateformat-1.0.2-1.2.3.tgz
    npm http 200 https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.2.11.tgz
    npm http 200 https://registry.npmjs.org/glob/-/glob-3.1.21.tgz
    npm http 200 https://registry.npmjs.org/lodash/-/lodash-0.9.2.tgz
    npm http GET https://registry.npmjs.org/abbrev
    npm http GET https://registry.npmjs.org/underscore.string/-/underscore.string-2.3.3.tgz
    npm http GET https://registry.npmjs.org/lru-cache
    npm http GET https://registry.npmjs.org/sigmund
    npm http GET https://registry.npmjs.org/graceful-fs
    npm http 304 https://registry.npmjs.org/abbrev
    npm http GET https://registry.npmjs.org/inherits
    npm http 200 https://registry.npmjs.org/underscore.string/-/underscore.string-2.3.3.tgz
    npm http GET https://registry.npmjs.org/inherits
    npm http GET https://registry.npmjs.org/argparse
    npm http GET https://registry.npmjs.org/esprima
    npm http 304 https://registry.npmjs.org/sigmund
    npm http 304 https://registry.npmjs.org/lru-cache
    npm http 200 https://registry.npmjs.org/esprima
    npm http GET https://registry.npmjs.org/esprima/-/esprima-1.0.4.tgz
    npm http 200 https://registry.npmjs.org/argparse
    npm http GET https://registry.npmjs.org/argparse/-/argparse-0.1.15.tgz
    npm http 200 https://registry.npmjs.org/esprima/-/esprima-1.0.4.tgz
    npm http 200 https://registry.npmjs.org/graceful-fs
    npm http GET https://registry.npmjs.org/graceful-fs/-/graceful-fs-1.2.3.tgz
    npm http 304 https://registry.npmjs.org/inherits
    npm http 304 https://registry.npmjs.org/inherits
    npm http GET https://registry.npmjs.org/inherits/-/inherits-1.0.0.tgz
    npm http 200 https://registry.npmjs.org/argparse/-/argparse-0.1.15.tgz
    npm http GET https://registry.npmjs.org/underscore
    npm http GET https://registry.npmjs.org/underscore.string
    npm http 200 https://registry.npmjs.org/graceful-fs/-/graceful-fs-1.2.3.tgz
    npm http 200 https://registry.npmjs.org/inherits/-/inherits-1.0.0.tgz
    npm http 304 https://registry.npmjs.org/underscore.string
    npm http 200 https://registry.npmjs.org/underscore
    npm http GET https://registry.npmjs.org/underscore/-/underscore-1.4.4.tgz
    npm http 200 https://registry.npmjs.org/underscore/-/underscore-1.4.4.tgz
    grunt@0.4.5 node_modules/grunt
    ├── which@1.0.5
    ├── dateformat@1.0.2-1.2.3
    ├── eventemitter2@0.4.13
    ├── getobject@0.1.0
    ├── rimraf@2.2.8
    ├── colors@0.6.2
    ├── hooker@0.2.3
    ├── async@0.1.22
    ├── grunt-legacy-util@0.2.0
    ├── exit@0.1.2
    ├── nopt@1.0.10 (abbrev@1.0.5)
    ├── lodash@0.9.2
    ├── coffee-script@1.3.3
    ├── underscore.string@2.2.1
    ├── minimatch@0.2.14 (sigmund@1.0.0, lru-cache@2.5.0)
    ├── iconv-lite@0.2.11
    ├── findup-sync@0.1.3 (glob@3.2.9, lodash@2.4.1)
    ├── grunt-legacy-log@0.1.1 (underscore.string@2.3.3, lodash@2.4.1)
    ├── glob@3.1.21 (inherits@1.0.0, graceful-fs@1.2.3)
    └── js-yaml@2.0.5 (esprima@1.0.4, argparse@0.1.15)
    
    201312231526HCSC15.png
    201312231526HCSC16.png
  4. Gruntプラグインのインストール

    Gruntに追加するプラグインをインストールします。
    追加するプラグインは、下記のとおりです。

    プラグイン機能
    grunt-contrib-uglifyJavaSctiptを圧縮します。
    grunt-contrib-watch指定されたタスクを監視します。
    grunt-contrib-lessLESSファイルをコンパイルします。
    npm install grunt-contrib-uglify grunt-contrib-watch grunt-contrib-less --save-dev
    
    npm WARN package.json sample@0.0.0 No repository field.
    npm WARN package.json sample@0.0.0 No README data
    npm http GET https://registry.npmjs.org/grunt-contrib-uglify
    npm http GET https://registry.npmjs.org/grunt-contrib-watch
    npm http GET https://registry.npmjs.org/grunt-contrib-less
    npm http 200 https://registry.npmjs.org/grunt-contrib-watch
    npm http GET https://registry.npmjs.org/grunt-contrib-watch/-/grunt-contrib-watch-0.6.1.tgz
    npm http 200 https://registry.npmjs.org/grunt-contrib-uglify
    npm http GET https://registry.npmjs.org/grunt-contrib-uglify/-/grunt-contrib-uglify-0.4.0.tgz
    npm http 200 https://registry.npmjs.org/grunt-contrib-less
    npm http GET https://registry.npmjs.org/grunt-contrib-less/-/grunt-contrib-less-0.11.0.tgz
    npm http 200 https://registry.npmjs.org/grunt-contrib-watch/-/grunt-contrib-watch-0.6.1.tgz
    npm http 200 https://registry.npmjs.org/grunt-contrib-uglify/-/grunt-contrib-uglify-0.4.0.tgz
    npm http 200 https://registry.npmjs.org/grunt-contrib-less/-/grunt-contrib-less-0.11.0.tgz
    npm http GET https://registry.npmjs.org/chalk
    npm http GET https://registry.npmjs.org/maxmin
    npm http GET https://registry.npmjs.org/less
    npm http GET https://registry.npmjs.org/lodash
    npm http GET https://registry.npmjs.org/async
    npm http GET https://registry.npmjs.org/uglify-js
    npm http GET https://registry.npmjs.org/gaze
    npm http GET https://registry.npmjs.org/tiny-lr-fork/0.0.5
    npm http GET https://registry.npmjs.org/async
    npm http GET https://registry.npmjs.org/lodash
    npm http 200 https://registry.npmjs.org/chalk
    npm http GET https://registry.npmjs.org/chalk/-/chalk-0.4.0.tgz
    npm http 304 https://registry.npmjs.org/lodash
    npm http 200 https://registry.npmjs.org/maxmin
    npm http 304 https://registry.npmjs.org/less
    npm http GET https://registry.npmjs.org/maxmin/-/maxmin-0.1.0.tgz
    npm http 200 https://registry.npmjs.org/gaze
    npm http 304 https://registry.npmjs.org/lodash
    npm http GET https://registry.npmjs.org/gaze/-/gaze-0.5.1.tgz
    npm http 304 https://registry.npmjs.org/async
    npm http 200 https://registry.npmjs.org/tiny-lr-fork/0.0.5
    npm http 200 https://registry.npmjs.org/uglify-js
    npm http GET https://registry.npmjs.org/uglify-js/-/uglify-js-2.4.13.tgz
    npm http GET https://registry.npmjs.org/tiny-lr-fork/-/tiny-lr-fork-0.0.5.tgz
    npm http 304 https://registry.npmjs.org/async
    npm http 200 https://registry.npmjs.org/chalk/-/chalk-0.4.0.tgz
    npm http 200 https://registry.npmjs.org/maxmin/-/maxmin-0.1.0.tgz
    npm http GET https://registry.npmjs.org/gzip-size
    npm http GET https://registry.npmjs.org/pretty-bytes
    npm http 200 https://registry.npmjs.org/gaze/-/gaze-0.5.1.tgz
    npm http GET https://registry.npmjs.org/has-color
    npm http 200 https://registry.npmjs.org/uglify-js/-/uglify-js-2.4.13.tgz
    npm http GET https://registry.npmjs.org/ansi-styles
    npm http GET https://registry.npmjs.org/strip-ansi
    npm http 200 https://registry.npmjs.org/tiny-lr-fork/-/tiny-lr-fork-0.0.5.tgz
    npm http 200 https://registry.npmjs.org/gzip-size
    npm http GET https://registry.npmjs.org/gzip-size/-/gzip-size-0.1.1.tgz
    npm http 200 https://registry.npmjs.org/pretty-bytes
    npm http GET https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-0.1.1.tgz
    npm http 200 https://registry.npmjs.org/has-color
    npm http GET https://registry.npmjs.org/has-color/-/has-color-0.1.7.tgz
    npm http 200 https://registry.npmjs.org/ansi-styles
    npm http GET https://registry.npmjs.org/globule
    npm http GET https://registry.npmjs.org/ansi-styles/-/ansi-styles-1.0.0.tgz
    npm http 200 https://registry.npmjs.org/gzip-size/-/gzip-size-0.1.1.tgz
    npm http 200 https://registry.npmjs.org/strip-ansi
    npm http GET https://registry.npmjs.org/strip-ansi/-/strip-ansi-0.1.1.tgz
    npm http 200 https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-0.1.1.tgz
    npm http 200 https://registry.npmjs.org/has-color/-/has-color-0.1.7.tgz
    npm http GET https://registry.npmjs.org/noptify
    npm http GET https://registry.npmjs.org/faye-websocket
    npm http GET https://registry.npmjs.org/debug
    npm http 200 https://registry.npmjs.org/ansi-styles/-/ansi-styles-1.0.0.tgz
    npm http 200 https://registry.npmjs.org/globule
    npm http GET https://registry.npmjs.org/qs
    npm http 200 https://registry.npmjs.org/strip-ansi/-/strip-ansi-0.1.1.tgz
    npm http GET https://registry.npmjs.org/globule/-/globule-0.1.0.tgz
    npm http 200 https://registry.npmjs.org/debug
    npm http GET https://registry.npmjs.org/concat-stream
    npm http GET https://registry.npmjs.org/zlib-browserify
    npm http 200 https://registry.npmjs.org/noptify
    npm http 200 https://registry.npmjs.org/faye-websocket
    npm http GET https://registry.npmjs.org/debug/-/debug-0.7.4.tgz
    npm http 304 https://registry.npmjs.org/qs
    npm http GET https://registry.npmjs.org/noptify/-/noptify-0.0.3.tgz
    npm http GET https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.4.4.tgz
    npm http 200 https://registry.npmjs.org/globule/-/globule-0.1.0.tgz
    npm http GET https://registry.npmjs.org/qs/-/qs-0.5.6.tgz
    npm http 200 https://registry.npmjs.org/zlib-browserify
    npm http 200 https://registry.npmjs.org/concat-stream
    npm http GET https://registry.npmjs.org/zlib-browserify/-/zlib-browserify-0.0.3.tgz
    npm http GET https://registry.npmjs.org/concat-stream/-/concat-stream-1.4.5.tgz
    npm http 200 https://registry.npmjs.org/debug/-/debug-0.7.4.tgz
    npm http 200 https://registry.npmjs.org/concat-stream/-/concat-stream-1.4.5.tgz
    npm http 200 https://registry.npmjs.org/noptify/-/noptify-0.0.3.tgz
    npm http 200 https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.4.4.tgz
    npm http 200 https://registry.npmjs.org/qs/-/qs-0.5.6.tgz
    npm http GET https://registry.npmjs.org/lodash
    npm http GET https://registry.npmjs.org/glob
    npm http GET https://registry.npmjs.org/minimatch
    npm http 200 https://registry.npmjs.org/zlib-browserify/-/zlib-browserify-0.0.3.tgz
    npm http GET https://registry.npmjs.org/tape
    npm http GET https://registry.npmjs.org/typedarray
    npm http GET https://registry.npmjs.org/readable-stream
    npm http GET https://registry.npmjs.org/inherits
    npm http GET https://registry.npmjs.org/gzip-size
    npm http GET https://registry.npmjs.org/pretty-bytes
    npm http 304 https://registry.npmjs.org/lodash
    npm http GET https://registry.npmjs.org/has-color
    npm http GET https://registry.npmjs.org/ansi-styles
    npm http GET https://registry.npmjs.org/strip-ansi
    npm http GET https://registry.npmjs.org/lodash/-/lodash-1.0.1.tgz
    npm http 304 https://registry.npmjs.org/minimatch
    npm http 304 https://registry.npmjs.org/glob
    npm http 200 https://registry.npmjs.org/readable-stream
    npm http GET https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.13-1.tgz
    npm http 304 https://registry.npmjs.org/inherits
    npm http 304 https://registry.npmjs.org/gzip-size
    npm http 304 https://registry.npmjs.org/has-color
    npm http 304 https://registry.npmjs.org/ansi-styles
    npm http 304 https://registry.npmjs.org/strip-ansi
    npm http 304 https://registry.npmjs.org/pretty-bytes
    npm http GET https://registry.npmjs.org/concat-stream
    npm http GET https://registry.npmjs.org/zlib-browserify
    npm http 200 https://registry.npmjs.org/tape
    npm http GET https://registry.npmjs.org/tape/-/tape-0.2.2.tgz
    npm http 200 https://registry.npmjs.org/lodash/-/lodash-1.0.1.tgz
    npm http 200 https://registry.npmjs.org/typedarray
    npm http GET https://registry.npmjs.org/typedarray/-/typedarray-0.0.5.tgz
    npm http 200 https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.13-1.tgz
    npm http GET https://registry.npmjs.org/optimist
    npm http GET https://registry.npmjs.org/uglify-to-browserify
    npm http 304 https://registry.npmjs.org/concat-stream
    npm http GET https://registry.npmjs.org/async
    npm http GET https://registry.npmjs.org/source-map
    npm http 200 https://registry.npmjs.org/tape/-/tape-0.2.2.tgz
    npm http 304 https://registry.npmjs.org/zlib-browserify
    npm http 200 https://registry.npmjs.org/typedarray/-/typedarray-0.0.5.tgz
    npm http 200 https://registry.npmjs.org/optimist
    npm http GET https://registry.npmjs.org/optimist/-/optimist-0.3.7.tgz
    npm http GET https://registry.npmjs.org/inherits
    npm http 200 https://registry.npmjs.org/uglify-to-browserify
    npm http GET https://registry.npmjs.org/nopt
    npm http GET https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz
    npm http 304 https://registry.npmjs.org/source-map
    npm http 304 https://registry.npmjs.org/async
    npm http 200 https://registry.npmjs.org/optimist/-/optimist-0.3.7.tgz
    npm http GET https://registry.npmjs.org/core-util-is
    npm http GET https://registry.npmjs.org/isarray/0.0.1
    npm http GET https://registry.npmjs.org/string_decoder
    npm http 304 https://registry.npmjs.org/inherits
    npm http 304 https://registry.npmjs.org/nopt
    npm http GET https://registry.npmjs.org/nopt/-/nopt-2.0.0.tgz
    npm http 200 https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz
    npm http 200 https://registry.npmjs.org/core-util-is
    npm http GET https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.1.tgz
    npm http 200 https://registry.npmjs.org/isarray/0.0.1
    npm http GET https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz
    npm http GET https://registry.npmjs.org/jsonify
    npm http GET https://registry.npmjs.org/deep-equal
    npm http GET https://registry.npmjs.org/defined
    npm http 200 https://registry.npmjs.org/nopt/-/nopt-2.0.0.tgz
    npm http 200 https://registry.npmjs.org/string_decoder
    npm http 200 https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.1.tgz
    npm http GET https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.25-1.tgz
    npm http 200 https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz
    npm http GET https://registry.npmjs.org/wordwrap
    npm http GET https://registry.npmjs.org/amdefine
    npm http 200 https://registry.npmjs.org/jsonify
    npm http 200 https://registry.npmjs.org/deep-equal
    npm http GET https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz
    npm http GET https://registry.npmjs.org/deep-equal/-/deep-equal-0.0.0.tgz
    npm http 200 https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.25-1.tgz
    npm http 200 https://registry.npmjs.org/defined
    npm http GET https://registry.npmjs.org/defined/-/defined-0.0.0.tgz
    npm http 200 https://registry.npmjs.org/wordwrap
    npm http GET https://registry.npmjs.org/abbrev
    npm http 304 https://registry.npmjs.org/amdefine
    npm http GET https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz
    npm http 200 https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz
    npm http 200 https://registry.npmjs.org/deep-equal/-/deep-equal-0.0.0.tgz
    npm http 200 https://registry.npmjs.org/defined/-/defined-0.0.0.tgz
    npm http GET https://registry.npmjs.org/lru-cache
    npm http GET https://registry.npmjs.org/sigmund
    npm http 304 https://registry.npmjs.org/abbrev
    npm http GET https://registry.npmjs.org/graceful-fs
    npm http GET https://registry.npmjs.org/inherits
    npm http 200 https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz
    npm http 304 https://registry.npmjs.org/lru-cache
    npm http 304 https://registry.npmjs.org/sigmund
    npm http 304 https://registry.npmjs.org/graceful-fs
    npm http GET https://registry.npmjs.org/mime
    npm http GET https://registry.npmjs.org/request
    npm http GET https://registry.npmjs.org/mkdirp
    npm http GET https://registry.npmjs.org/clean-css
    npm http GET https://registry.npmjs.org/source-map
    npm http 304 https://registry.npmjs.org/inherits
    npm http 304 https://registry.npmjs.org/source-map
    npm http 304 https://registry.npmjs.org/mime
    npm http 304 https://registry.npmjs.org/request
    npm http 304 https://registry.npmjs.org/mkdirp
    npm http 304 https://registry.npmjs.org/clean-css
    npm http GET https://registry.npmjs.org/qs
    npm http GET https://registry.npmjs.org/json-stringify-safe
    npm http GET https://registry.npmjs.org/node-uuid
    npm http GET https://registry.npmjs.org/forever-agent
    npm http GET https://registry.npmjs.org/tough-cookie
    npm http GET https://registry.npmjs.org/form-data
    npm http GET https://registry.npmjs.org/tunnel-agent
    npm http GET https://registry.npmjs.org/http-signature
    npm http GET https://registry.npmjs.org/oauth-sign
    npm http GET https://registry.npmjs.org/hawk
    npm http GET https://registry.npmjs.org/aws-sign2
    npm http GET https://registry.npmjs.org/commander
    npm http GET https://registry.npmjs.org/amdefine
    npm http 304 https://registry.npmjs.org/forever-agent
    npm http 304 https://registry.npmjs.org/qs
    npm http 304 https://registry.npmjs.org/json-stringify-safe
    npm http 304 https://registry.npmjs.org/node-uuid
    npm http 304 https://registry.npmjs.org/tunnel-agent
    npm http 304 https://registry.npmjs.org/form-data
    npm http 304 https://registry.npmjs.org/oauth-sign
    npm http 304 https://registry.npmjs.org/http-signature
    npm http 304 https://registry.npmjs.org/hawk
    npm http 304 https://registry.npmjs.org/commander
    npm http 304 https://registry.npmjs.org/amdefine
    npm http 304 https://registry.npmjs.org/aws-sign2
    npm http 304 https://registry.npmjs.org/tough-cookie
    npm http GET https://registry.npmjs.org/combined-stream
    npm http GET https://registry.npmjs.org/assert-plus/0.1.2
    npm http GET https://registry.npmjs.org/asn1/0.1.11
    npm http GET https://registry.npmjs.org/ctype/0.5.2
    npm http GET https://registry.npmjs.org/punycode
    npm http GET https://registry.npmjs.org/hoek
    npm http GET https://registry.npmjs.org/boom
    npm http GET https://registry.npmjs.org/cryptiles
    npm http GET https://registry.npmjs.org/sntp
    npm http 304 https://registry.npmjs.org/combined-stream
    npm http 304 https://registry.npmjs.org/assert-plus/0.1.2
    npm http 304 https://registry.npmjs.org/ctype/0.5.2
    npm http 304 https://registry.npmjs.org/asn1/0.1.11
    npm http GET https://registry.npmjs.org/delayed-stream/0.0.5
    npm http 304 https://registry.npmjs.org/hoek
    npm http 304 https://registry.npmjs.org/cryptiles
    npm http 304 https://registry.npmjs.org/sntp
    npm http 304 https://registry.npmjs.org/boom
    npm http 304 https://registry.npmjs.org/delayed-stream/0.0.5
    npm http 304 https://registry.npmjs.org/punycode
    grunt-contrib-uglify@0.4.0 node_modules/grunt-contrib-uglify
    ├── chalk@0.4.0 (has-color@0.1.7, ansi-styles@1.0.0, strip-ansi@0.1.1)
    ├── maxmin@0.1.0 (pretty-bytes@0.1.1, gzip-size@0.1.1)
    └── uglify-js@2.4.13 (uglify-to-browserify@1.0.2, async@0.2.10, source-map@0.1.33, optimist@0.3.7)
    
    grunt-contrib-watch@0.6.1 node_modules/grunt-contrib-watch
    ├── async@0.2.10
    ├── lodash@2.4.1
    ├── tiny-lr-fork@0.0.5 (debug@0.7.4, faye-websocket@0.4.4, qs@0.5.6, noptify@0.0.3)
    └── gaze@0.5.1 (globule@0.1.0)
    
    grunt-contrib-less@0.11.0 node_modules/grunt-contrib-less
    ├── async@0.2.10
    ├── chalk@0.4.0 (has-color@0.1.7, ansi-styles@1.0.0, strip-ansi@0.1.1)
    ├── lodash@2.4.1
    ├── maxmin@0.1.0 (pretty-bytes@0.1.1, gzip-size@0.1.1)
    └── less@1.7.0 (mime@1.2.11, mkdirp@0.3.5, source-map@0.1.33, clean-css@2.1.8, request@2.34.0)
    
    201312231526HCSC17.png
    201312231526HCSC18.png
  5. Gruntfile.jsの作成

    自動化に必要なパッケージが全てインストールできましたので、Gruntfile.jsを作成してLESS→CSSコンパイルのためのタスクを定義します。

    $ vi Gruntfile.js
    
    module.exports = function(grunt) {
    
      grunt.initConfig({
        pkg: grunt.file.readJSON("package.json"),
        less: {
          dist: {
            options: {
                yuicompress: true
            },
            files: [{
                expand: true,
                cwd: "less",
                src: ["*.less"],
                dest: "css",
                ext: ".css"
            }]
          }
        },
        watch: {
          less: {
            files: [
              "less/*.less"
            ],
            tasks: [
              "less"
            ]
          }
        }
      });
    
      grunt.registerTask("default", ["less"]);
      grunt.loadNpmTasks("grunt-contrib-watch");
      grunt.loadNpmTasks("grunt-contrib-less");
    };
    

    12行目~15行目では、lessフォルダ下のLESSファイルをソースファイルに、cssフォルダを出力フォルダに指定しています。
    19行目~28行目では、lessフォルダ下のLESSファイルを監視する対象として指定しています。
    31行目~33行目では、実行するプラグインをロードしています。

  6. 監視実行

    カレントディレクリに、lessおよび、cssフォルダを作成し、監視を実行します。

    $ mkdir -p less css
    $ grunt watch &
    

    プロセスがバックグラウンドで実行され、Watchタスクが実行されている旨のメッセージが表示されます。

    [1] 5276
    [vagrant@localhost sample]$ Running "watch" task
    Waiting...
    
    201312231526HCSC19.png
  7. LESSファイル追加

    lessフォルダに先に作成したlessファイルをコピーすると、cssフォルダにCSSファイルが作成できます。

    $ cp -p ~/less/sample.less less
    
    201312231526HCSC20.png

以上で、CSSコンパイルの自動化ができました。なお、手順2の初期化以降の作業は、プロジェクトごとに毎回行う必要がありますので、注意して下さい。