Posted at

GruntからMakeへ、Makeからnpm-scriptsへ

More than 3 years have passed since last update.


経緯


npm-scripts


package.json

{

"private": true,
"scripts": {
"command": "echo Hello!"
}
}


Terminal

$ npm run # or npm run-script

Available scripts in the package:
command
echo Hello!
$ npm run command

> @ command /path/to/dir
> echo Hello!

Hello!


npm install後にbower installをする


package.json

{

"private": true,
"scripts": {
"postinstall": "bower install"
},
"dependencies": {
"bower": "^1.3.12"
}
}


jadeでjadeをコンパイルする


npm-script

jade -o ./public ./sources



node-sassでsass, scssをコンパイルする


npm-script

node-sass --output-style compressed -o ./public -r ./sources



bowerでインストールしたライブラリをconcatする


Grepfile

jquery.min.js

vue.min.js


npm-script

find ./bower_components -type f | grep -f Grepfile | xargs awk '{ print }' > ./libs.js


xargs awk '{ print }'xargs catにすると

//# sourceMappingURL=jquery.min.map/**

* Vue.js v0.11.0

になって残念な感じになる。


grunt-contrib-concatのseparator, banner, footerっぽいことをして複数のスクリプトを即時関数で囲む


npm-script

find ./sources -type f -name '*.js ' -exec awk -f concat.awk {} + > index.min.js



1.js

/**

* 1.js
*/

console.log(1);


concat.awk

BEGIN {

print "(function() {"
}

{
print
}

END {
print "}());"
}



index.min.js

(function() {

/**
* 1.js
*/

console.log(1);
/**
* 2.js
*/

console.log(2);
}());

ついでに圧縮する。


npm-script

find ./sources -type f -name '*.js' -exec awk -f concat.awk {} + | uglifyjs -cm > index.min.js



index.min.js

!function(){console.log(1),console.log(2)}();



grunt-contrib-concatのseparator, banner, footerっぽいことをしてJSONを連結する


npm-script

awk -f join.awk 1.json 2.json 3.json > common.json



1.json

{

"name":"data1"
}


join.awk

BEGIN {

RS=""
ORS=""

print "{\"items\":["
}

{
if (NR == 1) {
print
} else {
print "," $0
}
}

END {
print "]}"
}



common.json

{"items":[{

"name": "data1"
},{
"name": "data2"
},{
"name": "data3"
}]}

余計なスペースとかを削除したい。


npm-script

node -pe 'JSON.stringify(process.argv.splice(1).map(function(json) { return require(json); }));' ./1.json ./2.json ./3.json | awk -f join.awk > common.json


うーん。横に長い。


npm-script

find . -type f -name '[123].json' | xargs node -pe 'JSON.stringify(process.argv.splice(1).map(function(a) { return require(a); }));' | awk -f join.awk > common.json


うーむ。横に長い。


common.json

{"items":[{"name":"data1"},{"name":"data2"},{"name":"data3"}]}


余計なスペースとかが削除された。


scssとjsをwatchして保存したらビルドしたい

fswatchが必要なので入れておく。

fswatch以外だと

とか。


package.json

{

"private": true,
"scripts": {
"watch": "npm run watch-css & npm run watch-js",
"watch-css": "node-sass -w -o ./public -r ./sources",
"watch-js": "fswatch -E -e '\\.(jade|scss)$' -i '\\.js$' -r ./sources | xargs -I{} -n 1 npm run build-js"
"build-js": "find . -type f -name '*.js' -exec awk '{ print }' + > ./index.min.js"
}
}


Terminal

$ brew install fswatch

$ npm run watch


ローカルで動くLiveReload付きのサーバが欲しい

サーバだけはGruntを使う。


Gruntfile.coffee

module.exports = (grunt) ->

grunt.initConfig

connect:
server:
options:
base: 'public'
livereload: true

esteWatch:
livereload:
enabled: true

grunt.loadNpmTasks 'grunt-contrib-connect'
grunt.loadNpmTasks 'grunt-este-watch'

grunt.registerTask 'default', ['connect', 'esteWatch']

return



package.json

{

"private": true,
"scripts": {
"watch": "grunt & npm run watch-css & npm run watch-file",
"watch-css": "node-sass -w -o ./public -r ./sources",
"watch-file": "fswatch -r ./public | xargs -I{} -n 1 sh -c 'curl -fs -o /dev/null http://localhost:35729/changed?files=$(basename {})'"
},
"devDependencies": {
"grunt": "^0.4.5",
"grunt-contrib-connect": "^0.9.0",
"grunt-este-watch": "^0.1.18",
"node-sass": "^1.2.3"
}
}

うーむ。横に長い。


Terminal

$ npm i

$ npm run watch


npm-scriptsが横に長くてつらい

代表は言っている――ここで死ぬ運命ではないとbin以下にシェルを用意して実行させよと


package.json

{

"private": true,
"scripts": {
"build-js": "./bin/build-js.sh"
}
}


Terminal

$ mkdir -p bin

$ cat <<'EOB' > bin/build-js.sh
> #!/bin/bash
>
> find . -type f -name '*.js' -exec awk '{ print }' + > ./index.min.js
> EOB
$ chmod +x bin/build-js.sh
$ npm run build-js


npm-scriptsというよりかはgruntを使わないでfindとかawkでがんばるスクリプト集みたいになった。

自分一人だけの時なら複雑なスクリプトを書いてもいいかもしれないけど、協調が必要なときは普通にGrunt使った方が良いと思う。(自分以外の人もそれなりにわかるなら別だけど)