Node.js
npm
grunt
grunt.js

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使った方が良いと思う。(自分以外の人もそれなりにわかるなら別だけど)