jsfmtを使ってみる


## リポジトリURL

```bash
$ npm view jsfmt repository

{ type: 'git',
  url: 'https://github.com/rdio/jsfmt' }

```

## インストール

コマンドラインツールなのでグローバルインストール。

```bash
$ npm install -g jsfmt
```

## 動作確認したバージョン

```bash
$ jsfmt --version
jsfmt 0.3.2
```

## コマンドラインオプション確認

```bash
$ jsfmt --help
Usage:
  jsfmt [--no-format] [--diff|--list|--write] [--validate] [--rewrite PATTERN|--search PATTERN] [--json] [<file>...]
  jsfmt (--version | --help)

Options:
  -h --help                      Show this help text
  --version                      Show jsfmt version
  -d --diff                      Show diff against original file
  -l --list                      List the files which differ from jsfmt output
  -v --validate                  Validate the input file(s)
  --no-format                    Do not format the input file(s)
  -w --write                     Overwrite the original file with jsfmt output
  -j --json                      Tell jsfmt that the file being parsed is json
  -r=PATTERN --rewrite PATTERN   Rewrite rule (e.g., 'a.slice(b, len(a) -> a.slice(b)')
  -s=PATTERN --search PATTERN    Search rule (e.g., 'a.slice')
```

コード整形だけではなく、パターン置換と検索といった機能もあるみたい。

## 実行してみる

インプットのサンプルはワンライナーな以下内容。

```bash
$ cat a.js
function flatten(){var a=arguments,l=0;while(l!=a.length){l=a.length;a=Array.prototype.concat.apply([],a);}return a;}
```

オプションなしで実行すると標準出力に出力される。

```bash
$ jsfmt a.js 
function flatten() {
  var a = arguments,
    l = 0;
  while (l != a.length) {
    l = a.length;
    a = Array.prototype.concat.apply([], a);
  }
  return a;
}
```

標準入力の内容も受け付けてくれるみたい。

```bash
$ cat a.js | jsfmt
function flatten() {
  var a = arguments,
    l = 0;
  while (l != a.length) {
    l = a.length;
    a = Array.prototype.concat.apply([], a);
  }
  return a;
}
```

`-d`オプションで整形前後の差分を表示してくれる。

```bash
$ echo 'if (1) {
  2;
}
else {
  3;
}' | jsfmt
if (1) {
  2;
} else {
  3;
}

$ echo 'if (1) {
  2;
}
else {
  3;
}' | jsfmt -d
diff --git a/var/folders/20/34gzkpq979x5gshl3gmq_hjw0009rs/T/tmp-6204tolusy8.tmp b/var/folders/20/34gzkpq979x5gshl3gmq_hjw0009rs/T/tmp-620494kehb4.tmp
index 349ac32..4221086 100644
--- a/var/folders/20/34gzkpq979x5gshl3gmq_hjw0009rs/T/tmp-6204tolusy8.tmp
+++ b/var/folders/20/34gzkpq979x5gshl3gmq_hjw0009rs/T/tmp-620494kehb4.tmp
@@ -1,6 +1,5 @@
 if (1) {
   2;
-}
-else {
+} else {
   3;
 }
```

`-w`で整形して上書き。

```bash
$ jsfmt -w a.js
$ cat a.js
function flatten() {
  var a = arguments,
    l = 0;
  while (l != a.length) {
    l = a.length;
    a = Array.prototype.concat.apply([], a);
  }
  return a;
}
```

## ソースで`//`のコメントを含むと出力コードが壊れる問題

コメントと`else`の位置に注目。出力コードではコメントの後ろに`else`が出力されているのでコードが壊れる。

```bash
$ echo 'if (1) {
  2;
} // brabrabra...
else {
  3;
}' | jsfmt
if (1) {
  2;
} // brabrabra... else {
  3;
}
```

issuesにバグ報告されている。 [#96](https://github.com/rdio/jsfmt/issues/96)

内容確認すると依存モジュールの`esformatter`側の問題らしい。[#97](https://github.com/rdio/jsfmt/pull/97)でClosedになっているが、まだnpmへはpublishしていないらしい。

## master最新で試してみる

`npm install <folder>`の形式があるので`git clone`したmaster最新をインストールして動かしてみる。

```bash
$ git clone https://github.com/rdio/jsfmt.git
$ npm install ./jsfmt/ -g
```

`esformatter`がいい感じのバージョンになっているか確認。

```bash
$ npm ls esformatter -g
/usr/local/lib
└─┬ jsfmt@0.3.2
  └── esformatter@0.4.1 
```

よしよし。前述のイケてないパターンを再度試してみる。

```bash
$ echo 'if (1) {
  2;
} // brabrabra...
else {
  3;
}' | jsfmt
if (1) {
  2;
} // brabrabra...
else {
  3;
}
```

コードがぶっ壊れるのは抑止されているみたい。

## grunt-jsfmt

GitHubにリポジトリはあるけどこれもnpmにpublishされていない。

https://github.com/james2doyle/grunt-jsfmt

jsfmt本体が絶賛開発中らしいので、ある程度安定版がリリースされるまで待っているらしい。

## 現時点まとめ

まだ気軽に利用できる状態にはなっていないっぽい。うーん、残念。