Edited at

jadeとstylusとcoffeeのgruntを作ってみた

More than 5 years have passed since last update.


はじめに

タイトルの通りですが、jadeとstylusとcoffeeを監視、コンパイルして、圧縮してビルドするGruntfileを作りました。その他にも色々機能がありますので紹介します。


ファイル構成

Gruntfile.coffee

package.json
src/
jade/sample.jade
stylus/sample.styl
coffee/sample.coffee
images/sample.jpg


Getting Started

package.jsonを任意の場所に置いて、npm installします。

必要なnode_modulesがインストールされます。

grunt-contribで足りないものも含まれています。


package.json

{

"name": "grunt-jade-stylus-coffee",
"version": "0.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": "",
"author": "",
"license": "BSD",
"devDependencies": {
"grunt-contrib-concat": "~0.3.0",
"grunt-contrib-copy": "~0.4.1",
"grunt-contrib-compass": "~0.6.0",
"grunt-contrib-clean": "~0.5.0",
"grunt-contrib-sass": "~0.5.1",
"grunt-contrib-htmlmin": "~0.1.3",
"grunt-contrib-csslint": "~0.1.2",
"grunt-contrib-cssmin": "~0.6.2",
"grunt-contrib-jst": "~0.5.1",
"grunt-contrib-coffee": "~0.7.0",
"grunt-contrib-qunit": "~0.3.0",
"grunt-contrib-connect": "~0.5.0",
"grunt-contrib-requirejs": "~0.4.1",
"grunt-contrib-jshint": "~0.6.5",
"grunt-contrib-jasmine": "~0.5.2",
"grunt-contrib-uglify": "~0.2.7",
"grunt-contrib-handlebars": "~0.5.12",
"grunt": "~0.4.2",
"grunt-contrib-compress": "~0.5.3",
"grunt-contrib-watch": "~0.5.3",
"grunt-contrib-stylus": "~0.8.0",
"grunt-contrib-jade": "~0.8.0",
"grunt-contrib-imagemin": "~0.3.0",
"grunt-contrib-less": "~0.7.0",
"grunt-contrib-nodeunit": "~0.2.2",
"grunt-contrib-yuidoc": "~0.5.0",
"grunt-contrib": "~0.8.0",
"matchdep": "~0.3.0",
"grunt-coffeelint": "0.0.7",
"grunt-simple-mocha": "~0.4.0",
"grunt-autoprefixer": "~0.4.1",
"grunt-styleguide": "~0.2.12"
}
}

npm install


Gruntfile.coffee

module.exports = (grunt) ->

# load all grunt tasks
(require 'matchdep').filterDev('grunt-*').forEach(grunt.loadNpmTasks)

_ = grunt.util._
path = require 'path'

grunt.initConfig
pkg: grunt.file.readJSON('package.json')
# Metadata.
banner: '/*! <%= pkg.title || pkg.name %> - v<%= pkg.version %> - ' + '<%= grunt.template.today(\'yyyy-mm-dd\') %>\n' + '<%= pkg.homepage ? \'* \' + pkg.homepage + \'\\n\' : \'\' %>' + '* Copyright (c) <%= grunt.template.today(\'yyyy\') %> <%= pkg.author.name %>;' + ' Licensed <%= _.pluck(pkg.licenses, \'type\').join(\', \') %> */\n'

dir:
src: 'src'
jade: 'jade'
styl: 'stylus'
coffee: 'coffee'
images: 'images'
js: 'js'
css: 'css'
img: 'images'
vendors: 'vendors'
dist: 'dist'
build: 'build'
docs: 'docs'
test: 'test'

jade:
dist:
options:
pretty: true, #htmlをインデント表記させる
expand: true
cwd: '<%= dir.src %>/<%= dir.jade %>'
src: '**/*.jade'
dest: '<%= dir.dist %>/'
ext: '.html'

stylus:
dist:
options:
compress: false
expand: true
cwd: '<%= dir.src %>/<%= dir.styl %>/'
src: '**/*.styl'
dest: '<%= dir.dist %>/<%= dir.css %>/'
ext: '.css'

coffee:
dist:
expand: true
cwd: '<%= dir.src %>/<%= dir.coffee %>'
src: '**/*.coffee'
dest: '<%= dir.dist %>/<%= dir.js %>'
ext: '.js'

htmlmin:
build:
options:
removeComments: true
collapseWhitespace: true
expand: true
cwd: '<%= dir.dist %>'
src: '**/*.html'
dest: '<%= dir.build %>'
ext: '.html'

cssmin:
build:
expand: true
cwd: '<%= dir.dist %>/<%= dir.css %>'
src: '**/*.css'
dest: '<%= dir.build %>/<%= dir.css %>'
ext: '.css'

uglify:
options:
banner: '<%= banner %>'
sourceMap: (path) ->
path + '.map'
build:
expand : true
src: '<%= dir.build %>/**/*.js'

# 画像の圧縮
imagemin:
options:
optimizationLevel: 7
pngquant: false
dist:
expand: true
cwd: '<%= dir.dist %>/<%= dir.images %>'
src: '**/*.{jpg,jpeg,gif}'
dest: '<%= dir.dist %>/<%= dir.img %>'

# coffeeの文法チェック
coffeelint:
app: '**/<%= dir.coffee %>/*.coffee'

# CSSのprefiexを補完
autoprefixer:
options:
browsers: ['last 2 version', 'ie 8', 'ie 7', 'ie 6']
dist:
expand: true
cwd: '<%= dir.dist %>/<%= dir.css %>'
src: '**/*.css'
dest: '<%= dir.dist %>/<%= dir.css %>/'
ext: '.css'

simplemocha:
dist:
src: '<%= dir.test %>/<%= dir.coffee %>/*.coffee'
options:
globals: ['should']
timeout: 3000
ignoreLeaks: false
grep: '*-test'
ui: 'bdd'
reporter: 'tap'

watch:
jade:
files: '<%= dir.src %>/**/*.jade',
tasks: 'jade:dist'
stylus:
files: '<%= dir.src %>/**/*.styl'
tasks: ['stylus:dist', 'autoprefixer:dist', 'styleguide:dist']
coffee:
files: '<%= dir.src %>/**/*.coffee'
tasks: 'coffee:dist'
images:
files: ['<%= dir.src %>/**/*.{gif,jpeg,jpg,png,svg,webp}']
tasks: ['clean:images', 'copy', 'imagemin']
vendors:
files: ['<%= dir.src %>/<%= dir.vendors %>/']
tasks: ['copy:vendors']
livereload:
options:
livereload: '<%= connect.options.livereload %>'
files: [
'<%= dir.dist %>/*.html',
'<%= dir.dist %>/**/*.css',
'<%= dir.dist %>/**/*.js',
'<%= dir.dist %>/**/*.{gif,jpeg,jpg,png,svg,webp}'
]

connect:
options:
port: 9000
livereload: 35729
hostname: 'localhost'
livereload:
options:
open: true
base: ['<%= dir.dist %>']

copy:
img:
expand: true
dot: true
cwd: '<%= dir.src %>/<%= dir.images %>'
dest: '<%= dir.dist %>/<%= dir.img %>'
src: [
'**/*.{gif,jpeg,jpg,png,svg,webp}',
]
vendors:
expand: true
dot: true
cwd: '<%= dir.src %>/<%= dir.vendors %>'
dest: '<%= dir.dist %>/<%= dir.vendors %>'
src: ['**']
build:
expand: true
dot: false
cwd: '<%= dir.dist %>/'
dest: '<%= dir.build %>/'
src: ['**']

yuidoc:
dist:
name: '<%= pkg.name %>'
description: '<%= pkg.description %>'
version: '<%= pkg.version %>'
options:
paths: '<%= dir.src %>/<%= dir.coffee %>/'
outdir: '<%= dir.docs %>/<%= dir.js %>'
syntaxtype: 'coffee'
extension: '.coffee'

styleguide:
dist:
files:
#'<%= dir.docs %>/<%= dir.css %>': '<%= dir.src %>/<%= dir.styl %>/**/*.styl'
'<%= dir.docs %>/<%= dir.css %>': '<%= dir.dist %>/<%= dir.css %>/**/*.css'
#'<%= dir.docs %>/<%= dir.css %>': '<%= dir.src %>/<%= dir.styl %>/**/*.sass'

clean:
dist:
src: [
'<%= dir.dist %>/**/*.html',
'<%= dir.dist %>/<%= dir.js %>/**/*.js',
'<%= dir.dist %>/<%= dir.css %>/**/*.css',
'<%= dir.build %>',
'<%= dir.docs %>'
]
docs:
src: '<%= dir.docs %>'
images:
src: ['<%= dir.dist %>/<%= dir.img %>']

grunt.registerTask 'default', [
'clean',
'coffeelint',
'simplemocha',
'yuidoc'
'jade:dist',
'stylus:dist',
'autoprefixer',
'styleguide',
'coffee:dist',
'copy:img',
'copy:vendors',
'imagemin'
]
grunt.registerTask 'w', [
'default',
'connect',
'watch',
'jshint',
]
grunt.registerTask 'compile', [
'clean',
'coffee:dist',
'jade:dist',
'stylus:dist'
]
grunt.registerTask 'build', [
'default',
'copy:build'
'htmlmin:build',
'cssmin:build',
'uglify'
]
grunt.registerTask 'c', ['compile']
grunt.registerTask 'docs', ['clean:docs', 'yuidoc', 'styleguide']



使い方

デフォルトのコマンドで、jade,stylus,coffeeがコンパイルされ、distディレクトリの中に配置されます。

grunt

Gruntfile.coffee

package.json
dist/
sample.html
js/
sample.js
css/
sample.css
img/
sample.jpg
src/
jade/sample.jade
stylus/sample.styl
coffee/sample.coffee
images/sample.jpg

grunt wで監視します。ブラウザが立ち上がり、jade,stylus,coffee,imagesディレクトリの中身に変更があれば自動でリロードします。

grunt w

grunt buildでリリースビルドします。buildディレクトリの中に配置され、各ファイルはminifyされます。画像も圧縮されます。

grunt build


coffeelint

coffee-scriptの文法チェックです。デフォルトと監視時にチェックが入ります。


simplemocha

simplemochaで簡単なJSテストをします。


autoprefixer

CSSでベンダープレフィックスを自動でつけてくれる機能です。

selector {

transition: transform 1s;
}

と書けば、grunt後に、

selector {

-webkit-transition: -webkit-transform 1s;
transition: transform 1s;
}

と書きだされます。


imagemin

画像のファイル容量を圧縮します。設定は、optimizationLevelでデフォルトは7です。

細かい設定は、下記のURLから。

grunt-contrib-imagemin


uglify

JSファイルの難読化、圧縮をします。ビルド時にSourceMapというファイルが出ます。

Introduction to JavaScript Source Maps