最近のお仕事でも使われていたので参考にしたり、これから個人でフロントエンドの実装するときも楽できるように自分用に作ってみました。
やりたいこと
今回css書くときにstylusを使ってみたかったのが始めた動機でもあるんですが、
- stylusをコンパイル
- tmpディレクトリに作業一時的にコピー(いらんかもw)
- minifiして結合したjsとcss、最適化した画像ファイルをappディレクトリにデプロイ
みたいなことをやろうとしてて、これを更にgruntでwatchして、更新が入る度に実行してやろうという魂胆です。
stylusのコンパイルが結構手間だと思うので、gruntでファイル監視することで開発が楽になりますね。
あと、minifyしたものを更に結合(conbine)しているのは、で呼び出すファイル数をjsとcssで1つに減らすことが出来て良いかなとおもったのでやっています。
簡単キレイなライブラリを色々入れなきゃいけない時は重宝するのではないでしょうか。(今回はjqueryと写真閲覧系ライブラリ2つを使ってみています。)
画像最適化はおまけです。
実践
ソースはこんな感じ
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module.exports = function(grunt) { | |
'use strict'; | |
grunt.loadNpmTasks('grunt-contrib-uglify'); | |
grunt.loadNpmTasks('grunt-contrib-cssmin'); | |
grunt.loadNpmTasks('grunt-contrib-stylus'); | |
grunt.loadNpmTasks('grunt-contrib-watch'); | |
grunt.loadNpmTasks('grunt-contrib-copy'); | |
grunt.loadNpmTasks('grunt-img'); | |
grunt.registerTask('default', ['stylus', 'copy', 'uglify', 'cssmin', 'img']); | |
grunt.registerTask('reload', ['copy', 'uglify', 'cssmin']); | |
grunt.registerTask('dev', ['watch']); | |
grunt.initConfig({ | |
pkg: grunt.file.readJSON('package.json'), | |
copy: { | |
img: { | |
files: [{ | |
expand: true, | |
src: '**/*', | |
dest: './tmp/img', | |
cwd: './src/img' | |
}] | |
}, | |
js: { | |
files: [{ | |
expand: true, | |
src: '**/*', | |
dest: './tmp/js', | |
cwd: './src/js' | |
}] | |
}, | |
css: { | |
files: [{ | |
expand: true, | |
src: '**/*.css', | |
dest: './tmp/css', | |
cwd: './src/css' | |
}] | |
} | |
}, | |
uglify: { | |
dist: { | |
options: { | |
mangle: true, | |
preserveComments: 'some' | |
}, | |
files: [ | |
{ | |
'./app/js/hoge.js': [ | |
'./tmp/js/lib/jquery-2.0.3.js', | |
'./tmp/js/lib/jquery.flexslider.js', | |
'./tmp/js/lib/klass.min.js', | |
'./tmp/js/lib/code.photoswipe-3.0.5.js', | |
'./tmp/js/main.js' | |
] | |
} | |
] | |
} | |
}, | |
cssmin: { | |
minify: { | |
expand: true, | |
cwd: './tmp/css', | |
src: '**/*.css', | |
dest: './tmp/css', | |
ext: '.min.css' | |
}, | |
conbine: { | |
files: { | |
'./app/css/hoge.css': [ | |
'./tmp/css/flexslider.min.css', | |
'./tmp/css/photoswipe.min.css', | |
'./tmp/css/main.min.css' | |
] | |
} | |
} | |
}, | |
img: { | |
dist: { | |
src: ['./tmp/**/*'], | |
dest: './app/img' | |
} | |
}, | |
stylus: { | |
compile: { | |
src: './src/css/main.styl', | |
dest: './src/css/main.css', | |
options: { | |
compress: false | |
} | |
} | |
}, | |
watch: { | |
stylus: { | |
files: [ | |
'./src/css/**/*.styl' | |
], | |
tasks: ['stylus'] | |
}, | |
reload: { | |
files: [ | |
'./src/**/*.html', | |
'./src/css/**/*.css', | |
'./src/js/**/*.js' | |
], | |
tasks: ['reload'] | |
}, | |
reloadImg: { | |
files: [ | |
'./src/img/**/*' | |
], | |
tasks: ['copy:img', 'img'] | |
} | |
} | |
}); | |
}; |
今回使っているgruntのnpm tasksは
- grunt-contrib-watch → ファイル更新監視
- grunt-contrib-stylus → stylusのコンパイル
- grunt-contrib-copy → ファイルコピー
- grunt-contrib-uglify → jsのminify
- grunt-contrib-cssmin → cssのminify
- grunt-img → 画像最適化
ですね。
grunt-contribだけで全部入りらしいんですが、軽量な状態にしてあったほうが良いかなと思ってこうしてます。
1. grunt-contrib-watch : ファイルの更新監視
watch: { stylus: { files: [ './src/css/**/*.styl' ], tasks: ['stylus'] }, reload: { files: [ './src/**/*.html', './src/css/**/*.css', './src/js/**/*.js' ], tasks: ['reload'] }, reloadImg: { files: [ './src/img/**/*' ], tasks: ['copy:img', 'img'] } }
watchの中にstylusファイルの監視とその他html, css, jsファイルの監視、grunt-imgが遅いので別途分けた画像ファイルの監視がそれぞれ置いてあります。
この設定がある状態で、/srcディレクトリ以下の各ファイルどれかを編集すると、tasksの中身が実行されます。
2. grunt-contrib-stylus : stylusのコンパイル
stylus: { compile: { src: './src/css/main.styl', dest: './src/css/main.css', options: { compress: false } } },
watch:stylusから呼ばれているタスクです。
自分で編集する.stylファイルをmain.stylだけにして、main.cssという名前で出力される用になります。
optionでcompressした状態のcssが出せるようになってたので使ってみたのですが、後ほど他cssと一緒にcssminするのでここでやるのはやめておきました。
ここでwatchをみると、このタスクで生成されたmain.cssに変更が加えられるのでreloadのタスクが走ります。便利ですねぇ。
3. grunt-contrib-copy : ファイルコピー
copy: { img: { files: [{ expand: true, src: '**/*', dest: './tmp/img', cwd: './src/img' }] }, js: { files: [{ expand: true, src: '**/*', dest: './tmp/js', cwd: './src/js' }] }, css: { files: [{ expand: true, src: '**/*.css', dest: './tmp/css', cwd: './src/css' }] } },
copyの中で使われています。
試しに使ってみただけなので使い方間違ってる感じがしますが、作業用・準備用・デプロイ用と分けてGruntfileを書いてみただけです。
4. grunt-contrib-uglify : jsのminify
uglify: { dist: { options: { mangle: true, preserveComments: 'some' }, files: [ { './app/js/hoge.js': [ './tmp/js/lib/jquery-2.0.3.js', './tmp/js/lib/jquery.flexslider.js', './tmp/js/lib/klass.min.js', './tmp/js/lib/code.photoswipe-3.0.5.js', './tmp/js/main.js' ] } ] } },
ここでは圧縮から結合まで一気にやっています。
結合されたファイルが、どこからがどのファイルなのか試すために、コメントを残すオプションなどが付いています。
便利ですねぇ。。
5. grunt-contrib-cssmin : cssのminify
cssmin: { minify: { expand: true, cwd: './tmp/css', src: '**/*.css', dest: './tmp/css', ext: '.min.css' }, conbine: { files: { './app/css/hoge.css': [ './tmp/css/flexslider.min.css', './tmp/css/photoswipe.min.css', './tmp/css/main.min.css' ] } } },
uglifyのcss版です。
各種ライブラリで必要なcssが圧縮、結合されています。
圧縮したファイル名を".min.css"としたりできるのでやってみました。便利。
6. grunt-img : 画像の最適化
img: { dist: { src: ['./tmp/**/*'], dest: './app/img' } },
やってみたかっただけです。
gruntはこんなことまで出来るんですねぇ。凄いっす。
使い方
上の方に
grunt.registerTask('default', ['stylus', 'copy', 'uglify', 'cssmin', 'img']); grunt.registerTask('reload', ['copy', 'uglify', 'cssmin']); grunt.registerTask('dev', ['watch']);
が用意されています。
defaultがただgruntと実行した時の全部入りタスク。
reloadはwatch:reloadから呼ばれているタスク。
dev(名前変えるほどのこと無かったな。。)はwatchが始まるだけのタスクです。今後なんかクライアントサイドのtestとかjsHint足すかも。
まぁこんなもんか。
まとめ
stylusの自動コンパイルがしたかっただけなのに壮大なGruntfileになってしまった。
実際使ってみると、uglifyが結構無茶してたりするのでちょっぴり遅い。
最終的にデプロイするときは問題無いと思うんだけど、開発中はちょっと大げさなので、src内で完結する様な構成も今後は考えたいですね。
特にminifyしてるからjsのデバッグが大変そう。
deployタスクみたいなlocalと本番で別にタスクを用意したりしなきゃなぁと思いますた。
0 件のコメント:
コメントを投稿