Jade、Stylus、CoffeeScriptで簡単にページを作ってアップロードするgruntタスクを紹介します。作ってある機能は以下の通りです。
- 開発用
- 各種ファイルの変更監視
- サーバ起動
- Jade、Stylus、CoffeeScript
- CSSのvendor prefix拡張
- 素のHTML、CSS、JavaScript、画像への対応
- デプロイ用
- HTML、CSS、JavaScript、画像の圧縮
- FTPでの差分アップロード
普段は、これをベースに機能を削って使っています。
ディレクトリ構成
以下のようなディレクトリ構成で使います。
/
.ftppass(FTP使わないなら不要)
.gitignore(git使わないなら不要だけど、使うときに事故起こさないようにいつも入れてる)
Gruntfile.coffee
package.json
src/ (アップロードしたいファイルを入れる。ディレクトリ構成は自由です!)
index.jade
sample/
index.html
css/
styles.styl
normalize.css
js/
scripts.coffee
jquery.js
dist/ (自動で作られる。圧縮済みのファイルが入る)
各ファイルの中身
package.json
{
"name": "example-site",
"version": "0.0.0",
"description": "build example website.",
"devDependencies": {
"grunt": "*",
"grunt-contrib-watch": "*",
"grunt-contrib-connect": "*",
"grunt-contrib-clean": "*",
"grunt-contrib-copy": "*",
"grunt-contrib-coffee": "*",
"grunt-closurecompiler": "*",
"grunt-contrib-jade": "*",
"grunt-contrib-htmlmin": "*",
"grunt-contrib-stylus": "*",
"grunt-autoprefixer": "*",
"grunt-contrib-cssmin": "*",
"grunt-contrib-imagemin": "*",
"grunt-ftpush": "*"
}
}
Gruntfile.coffee
module.exports = (grunt) ->
pkg = grunt.file.readJSON('package.json')
grunt.initConfig
pkg: pkg
watch:
gruntfile:
files: 'Gruntfile.coffee'
html:
files: 'src/**/*.html'
tasks: 'copy:html'
css:
files: 'src/**/*.css'
tasks: ['copy:css', 'autoprefixer:dist']
js:
files: 'src/**/*.js'
tasks: 'copy:js'
jade:
files: 'src/**/*.jade'
tasks: 'jade:dist'
stylus:
files: 'src/**/*.styl'
tasks: ['stylus:dist', 'autoprefixer:dist']
coffee:
files: 'src/**/*.coffee'
tasks: 'coffee:dist'
options:
livereload: true
connect:
server:
options:
base: '.tmp'
useAvailablePort: true
dist:
options:
keepalive: true
useAvailablePort: true
base: 'dist'
clean:
server: '.tmp'
dist: 'dist'
copy:
image:
expand: true
cwd: 'src'
src: '**/*.{png,jpg,gif}'
dest: '.tmp'
filter: 'isFile'
html:
expand: true
cwd: 'src'
src: '**/*.html'
dest: '.tmp'
filter: 'isFile'
css:
expand: true
cwd: 'src'
src: '**/*.css'
dest: '.tmp'
filter: 'isFile'
js:
expand: true
cwd: 'src'
src: '**/*.js'
dest: '.tmp'
filter: 'isFile'
jade:
options:
client: false
dist:
expand: true
cwd: 'src'
src: '**/*.jade'
dest: '.tmp'
ext: '.html'
stylus:
dist:
expand: true
cwd: 'src'
src: ['**/*.styl', '!**/_*.styl']
dest: '.tmp'
ext: '.css'
autoprefixer:
dist:
expand: true
cwd: '.tmp'
src: '**/*.css'
dest: '.tmp'
ext: '.css'
coffee:
options:
bare: true
dist:
expand: true
cwd: 'src'
src: '**/*.coffee'
dest: '.tmp'
ext: '.js'
htmlmin:
options:
removeComments: true
collapseWhitespace: true
dist:
expand: true
cwd: '.tmp'
src: '**/*.html'
dest: 'dist'
cssmin:
dist:
expand: true
cwd: '.tmp',
src: '**/*.css'
dest: 'dist'
closurecompiler:
options:
compilation_level: 'SIMPLE_OPTIMIZATIONS'
max_processes: 5
dist:
expand: true
cwd: '.tmp',
src: '**/*.js'
dest: 'dist'
imagemin:
options:
optimizationLevel: 7
dist:
expand: true
cwd: '.tmp'
src: '**/*.{png,jpg,gif}'
dest: 'dist'
ftpush:
dist:
auth:
host: 'server.domain.tld' # アップロード先サーバ
port: 21
authKey: pkg.name
src: 'dist'
dest: '/' # アップロード先のディレクトリなので環境によって変わる
exclusions: 'dist/**/{.DS_Store,Thumbs.db}'
simple: false
useList: false
grunt.loadNpmTasks task for task of pkg.devDependencies when /^grunt-/.test(task)
grunt.registerTask 'generate', [
'clean:server'
'copy'
'jade:dist'
'stylus:dist'
'autoprefixer:dist'
'coffee:dist'
]
grunt.registerTask 'compile', [
'clean:dist'
'htmlmin:dist'
'cssmin:dist'
'closurecompiler:dist'
'imagemin:dist'
]
grunt.registerTask 'build', [
'generate'
'compile'
]
grunt.registerTask 'serve', [
'generate'
'connect:server'
'watch'
]
grunt.registerTask 'serve:dist', [
'build'
'connect:dist'
]
grunt.registerTask 'deploy', [
'build'
'ftpush:dist'
]
grunt.registerTask 'default', [
'serve'
]
.ftppass
{
"example-site": {
"username": "USERNAME",
"password": "PASSWORD"
}
}
当たり前ですが、このファイルは.gitignoreの対象にしておきましょう。
.gitignore
/node_modules
/.ftppass
/.tmp
/dist
dist
をレポジトリの管理下に置きたいことはよくあるので、その時は取り除きます。
使い方
grunt # 開発用のサーバが起動します。圧縮しません。
grunt serve:dist # 圧縮した場合のデータが見れるサーバが起動します。
grunt build # 圧縮したデータを生成します。
grunt deploy # 圧縮したデータを生成し、FTPでアップロードします。
もちろん事前にnpm i --save-dev
してからですが。
補足
割とオーソドックスな構成ですが、他に比べたら一般的ではないgrunt-closurecompilerとgrunt-ftpushについて。
grunt-closurecompilerは趣味的なものです。grunt-contrib-uglifyを使う場合は、package.jsonを置き換えて、Gruntfileのタスク名を置き換えれば良いでしょう。closurecompilerを使うgruntはいくつかありますが、これを使っているのは、何も考えずにnpm i --save-dev
するだけで他のセットアップが不要だからです。オススメです。
grunt-ftpushは差分アップロードに対応しているという理由で使っています。他に良いタスクがあれば教えていただきたいです。あと、多分、差分アップロードなので、他のところからFTPでアップロードすると消されたりするのではないかと思います(未検証)。そういう専用のディレクトリに対して適用しないといけない可能性が高いです。
問題点
- デプロイするたびに変更していないものの圧縮、特に画像の圧縮が走るのが無駄