最近0からサイト作るときによく使ってるnpmパッケージ(つかgruntプラグイン)とフォルダ構成。
設定系
- load-grunt-config
- grunt-bower-task
load-grunt-config で各タスクをGruntfile.coffeeから分離して好きなフォルダに配置する。
grunt-bower-task はbowerで引っ張ってくるライブラリを好きなディレクトリに配置する。
メタ言語コンパイル
- grunt-contrib-jade
- grunt-contrib-sass
- grunt-contrib-coffee
説明不要かな。jadeをhtmlに、sassをcssに、coffeeをjsにコンパイル。
チェック
- grunt-contrib-jshint jsはjshintでチェック。
ローカルサーバ・監視系
- grunt-contrib-connect
- grunt-open
- grunt-este-watch
- grunt-notify
grunt-openを使ってるのは僕のデフォルトブラウザがSafariだけど開発はChromeにしたいからで、開くブラウザを指定するために使ってる。
grunt-notify でコンパイルが成功した貸してないかを通知してくれるから地味に便利。
整理整頓
- grunt-contrib-copy
- grunt-contrib-rename
- grunt-contrib-clean
- grunt-contrib-concat
- grunt-contrib-uglify
- grunt-usemin
ここら辺はプロジェクトによりけり。バックエンドのフレームワークの影響で「画像はこっちな!」って指定があったりする場合にコピーとかリネームとか使ってる。
あとは最適化とかの際に concat と uglify と usemin で良い感じに。
フォルダ構成
だいたいこんな感じ。src にソースを入れてドキュメントルートは dist にしてる。あと各種設定ファイルは config に入れて、gruntの各タスク設定ファイルは config/grunt に入る感じ。
ProjectRooot
├ config/
│ ├ grunt/ // 各タスクファイル
│ │ └alias.yaml
│ │ └esteWatch.coffee
│ │ └〜他タスク毎のcoffeeファイル
│ └ .jshintrc
├ dist/ // ドキュメントルート
│ ├index.html
│ ├dir/
│ └assets/
│ ├ libs/ // bowerでインストールするライブラリ
│ ├ img/
│ ├ css/
│ └ js/
├ Gruntfile.coffee
├ node_modules/
│ └各モジュール/
├ package.json
└ src/ // ソースコード
├ sass/
│ ├ style.sass
│ ├ _layout.sass
│ ├ _module.sass
│ ├ _element.sass
│ └ common/
├ coffee/
│ ├ app.coffee
│ ├ extend.coffee
│ └ controller/
├ dir/
└ index.jade
Gruntfile.coffee
load-grunt-config のおかげでむっちゃ長いGruntfile.coffeeを分割できて結構嬉しい。今のGruntfile.coffeeはこんな感じ。
module.exports = (grunt) ->
path = require('path')
# Load grunt tasks automatically
require('load-grunt-config') grunt,
configPath: path.join(process.cwd(), 'config/grunt')
これで各タスクの設定ファイルを ./config/grunt/ に置ける。何でわざわざ ./config/ つけてるかってのは .jshintrc みたいなファイルをどこでも良いからまとめたかったから。
各タスクの設定記述
タスクを alias.yaml に記述して、後はタスク毎のcoffeeファイルを作る
# alias.yaml
default:
- 'connect'
- 'open'
- 'esteWatch'
init:
- 'bower:install'
dist:
- "useminPrepare"
- "concat"
- "uglify"
- "usemin"
- "sass:build"
- "clean"
後は各タスクのcoffeeファイルを書く。例としてgrunt-contrib-connect。
module.exports = (grunt, path) ->
server:
options:
base: 'dist'
port: 3000
livereload: true
## 今後の課題
これで結構良い感じに色々すっきりしてて便利で何とでもなる感じになってきてる。jadeのコンパイル時にパーシャルだった場合のルールとかも決めてできるだけ無駄コンパイルはしないようにもしてるし、残ってる課題は */.jade って感じで全ファイルjadeをコンパイルする時に各ファイルに対応したテキストを記述しているjsonファイルを渡せられるようになれればhtml(マークアップ)とテキストが分離できてよりステキになりそうな気がするんだけどなーと思ってるところ。