JavaScriptを使った開発で必要となるconcat, minify, lint, test といったタスクを動かすのに使うツール、最近はgruntをよく見かけるのでオレオレmakefileから移行してみた。
既存のmakefileは以下の通り。makefile + makeターゲットから呼び出される各種タスクに対応した処理を行なうプログラムという構成。make minifyと打てば圧縮版のファイルを生成、make testと打てばテストが実行される寸法だ、圧縮にはuglify.js, lintにはjshint、全てnodeモジュールを使っているのでそのまま移行できるはず。concatにはmuというテンプレートエンジンを使っていた。
grunt testでテストが実行されるし、grunt watchしてコードを編集すれば勝手にlint, concat, testしてくれるので移行はOK。 古参JSerであればRailsにアセットパイプラインが導入される前から、それ相当の機能を持つ秘伝のタレ的なMakefileやRakefileを使ってきたとは思うが、gruntはプラグインという形でタスクを共有できるので新規プロジェクトで使ってみるメリットは十分ある。少なくともCakefileよりはイケている。ライブラリでは無くWebアプリケーションの開発であればgruntを利用したyeomanの方が良さげ。
既存のmakefileは以下の通り。makefile + makeターゲットから呼び出される各種タスクに対応した処理を行なうプログラムという構成。make minifyと打てば圧縮版のファイルを生成、make testと打てばテストが実行される寸法だ、圧縮にはuglify.js, lintにはjshint、全てnodeモジュールを使っているのでそのまま移行できるはず。concatにはmuというテンプレートエンジンを使っていた。
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
SRC_DIR = src | |
.PHONY: test | |
FILES = ${SRC_DIR}/api.js ${SRC_DIR}/trap.js ${SRC_DIR}/typechecker.js ${SRC_DIR}/all.js | |
CONCAT_FILE = struct.js | |
MINIFY_FILE = struct.min.js | |
default_target: all | |
TARGET = clean concat minify | |
all: $(TARGET) | |
setup_build_environment: | |
npm install | |
clean: | |
-rm -f ${CONCAT_FILE} | |
-rm -f ${MINIFY_FILE} | |
concat: clean ${FILES} | |
@echo "** Start concat source files" | |
node build/concat.js > ${CONCAT_FILE} | |
check: concat | |
@echo "** Start check source files by jshint" | |
node build/check.js < ${CONCAT_FILE} | |
minify: check | |
@echo "** Start minify concat file" | |
./node_modules/uglify-js/bin/uglifyjs --unsafe < ${CONCAT_FILE} > ${MINIFY_FILE} | |
@echo "Created ${MINIFY_FILE}" | |
test: | |
@echo "** Start tests" | |
node --harmony ./node_modules/jasmine-node/bin/jasmine-node test | |
makefileからの移行
まず、gruntの制御に必要なgrunt.jsファイルは grunt init:gruntfile して生成する。concat, lint, minify がビルトインタスクとして既に存在しているのがわかる。それらの箇所を修正して対象ファイルを指定する。gruntからシェルコマンドの実行
最初に困ったのが、gruntから npm test を実行したいが、シェルのコマンドを実行する方法がデフォルトでは存在しない事。そこで grunt-exec というgruntプラグインを発見したので利用した。最終的に次のgrunt.jsになった。
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) { | |
grunt.initConfig({ | |
pkg: '<json:package.json>', | |
meta: { | |
name: 'Struct.js' | |
}, | |
exec: { | |
run_nodejs_test: { | |
command: 'npm test', | |
stdout: true | |
} | |
}, | |
lint: { | |
files: ['grunt.js', 'src/**/*.js'] | |
}, | |
concat: { | |
dist: { | |
src: [ | |
'<file_template:src/header.txt>', | |
'<file_strip_banner:src/prepare.js>', | |
'<file_strip_banner:src/typecheck.js>', | |
'<file_strip_banner:src/handlermaker.js>', | |
'<file_strip_banner:src/api.js>' | |
], | |
dest: 'struct.js' | |
} | |
}, | |
min: { | |
dist: { | |
src: [ | |
'<config:concat.dist.dest>' | |
], | |
dest: 'struct.min.js' | |
} | |
}, | |
watch: { | |
files: '<config:lint.files>', | |
tasks: 'lint qunit' | |
}, | |
jshint: { | |
options: { | |
curly: true, | |
eqeqeq: true, | |
immed: true, | |
latedef: true, | |
newcap: true, | |
noarg: true, | |
sub: true, | |
undef: true, | |
boss: true, | |
eqnull: true, | |
browser: true | |
}, | |
globals: { | |
'global': true, | |
'module': true, | |
'console': true, | |
'Proxy': true | |
} | |
}, | |
uglify: {} | |
}); | |
// Default task. | |
grunt.registerTask('test', 'exec'); | |
grunt.registerTask('default', 'lint concat test min'); | |
// Plugins | |
grunt.loadNpmTasks('grunt-exec'); | |
}; |