圧縮/難読化されたJavaScriptファイルのgit diffをみやすくする

# 概要

多くの場合は信じる心でcommitされる圧縮/難読化されたJavaScriptファイルに、差分が意図通り反映されているのか確認しやすくするための設定を追加します。

# 解説

gitには、バイナリファイルなど通常では比較が難しいファイル同士でもdiffをとれるように、テキスト変換のコマンドを設定することができます。圧縮されたJavaScriptファイルにそれを応用することで、難読化が展開された状態でdiffを確認することができます。

# インストールと設定

圧縮/難読化されたファイルを展開するためのコマンドを用意します。ここでは、[js-beautify](https://github.com/beautify-web/js-beautify)をインストールします。

```shell-session
$ npm install -g js-beautify
```

gitの設定に、`minjs`という名前でテキスト変換に`js-beautify`を使うフィルタを追記します。

```ini:.git/config
...
[diff "minjs"]
  textconv = js-beautify
```

gitの属性に、拡張子が`*.min.js`のものは、diff実行時に`minjs`フィルタを使用するよう設定します。

```ini:.git/info/attributes
*.min.js diff=minjs
```

# 出力結果

設定前のdiffでは、このように圧縮/難読化後のファイルは差分を確認する気が失われます。

```diff
diff --git a/idol.js b/idol.js
index bedbede..a17b5ec 100644
--- a/idol.js
+++ b/idol.js
@@ -3,11 +3,17 @@
   var mongoose = require('mongoose');

   var idolSchema = new Schema({
-    name: String
+    name: {
+      first: String,
+      last: String
+    }
   });
   var Idol = mongoose.model('Idol', idolSchema);
   var otome = new Idol({
-    name: 'Otome Arisugawa'
+    name: {
+      first: 'Otome',
+      last: 'Arisugawa'
+    }
   });
   otome.save(function(err) {
     if (err) {
diff --git a/idol.min.js b/idol.min.js
index c1091cb..d9a17b6 100644
--- a/idol.min.js
+++ b/idol.min.js
@@ -1 +1 @@
-!function(){"use strict";var e=require("mongoose"),n=new Schema({name:String}),o=e.model("Idol",n),a=new o({name:"Otome Arisugawa"});a.save(function(e){e&&console.log(e)})}();
+!function(){"use strict";var e=require("mongoose"),n=new Schema({name:{first:String,last:String}}),o=e.model("Idol",n),t=new o({name:{first:"Otome",last:"Arisugawa"}});t.save(function(e){e&&console.log(e)})}();
```

設定後の出力は、以下のようになります。便利。

```diff
diff --git a/idol.js b/idol.js
index bedbede..a17b5ec 100644
--- a/idol.js
+++ b/idol.js
@@ -3,11 +3,17 @@
   var mongoose = require('mongoose');
 
   var idolSchema = new Schema({
-    name: String
+    name: {
+      first: String,
+      last: String
+    }
   });
   var Idol = mongoose.model('Idol', idolSchema);
   var otome = new Idol({
-    name: 'Otome Arisugawa'
+    name: {
+      first: 'Otome',
+      last: 'Arisugawa'
+    }
   });
   otome.save(function(err) {
     if (err) {
diff --git a/idol.min.js b/idol.min.js
index c1091cb..d9a17b6 100644
--- a/idol.min.js
+++ b/idol.min.js
@@ -2,13 +2,19 @@
     "use strict";
     var e = require("mongoose"),
         n = new Schema({
-            name: String
+            name: {
+                first: String,
+                last: String
+            }
         }),
         o = e.model("Idol", n),
-        a = new o({
-            name: "Otome Arisugawa"
+        t = new o({
+            name: {
+                first: "Otome",
+                last: "Arisugawa"
+            }
         });
-    a.save(function(e) {
+    t.save(function(e) {
         e && console.log(e)
     })
 }();
```


# 補足

gitの設定は、`$HOME/.gitconfig`に記述するとグローバルに反映されます。

一方で属性値のほうは、プロジェクト単位でのみ指定が可能です（環境全体で有効にできる方法があれば教えてください）。`$GIT_DIR/info/attributes`ではなく、`.gitattributes`ファイルに記述すると、git管理下のファイルとしてリポジトリにcommitすることができます。

詳しくは、参考資料の公式ドキュメントなどを参照ください。

公式ドキュメントには、バイナリファイルの比較としてWord文書(OpenDocument Text)を変換する例や、`exiftool`を使ってPNG画像をメタ情報で比較する例なども載っているので、興味のある方は見てみると面白いかもしれません。

## 参考資料

- [Git - Git Configuration](https://git-scm.com/book/tr/v2/Customizing-Git-Git-Configuration) （日本語訳: [Git - Git の設定](https://git-scm.com/book/ja/v1/Git-%E3%81%AE%E3%82%AB%E3%82%B9%E3%82%BF%E3%83%9E%E3%82%A4%E3%82%BA-Git-%E3%81%AE%E8%A8%AD%E5%AE%9A))
- [Git - Git Attributes](https://git-scm.com/book/en/v2/Customizing-Git-Git-Attributes) (日本語訳: [Git - Git の属性](https://git-scm.com/book/ja/v1/Git-%E3%81%AE%E3%82%AB%E3%82%B9%E3%82%BF%E3%83%9E%E3%82%A4%E3%82%BA-Git-%E3%81%AE%E5%B1%9E%E6%80%A7))