ペペロン頭脳

ソフトウェアエンジニアのメモ的なアレ。

JScript5.8をES5化してバッチに利用するのだ

2015年とは思えないクソレガシーな話題だが、現場では必要なんだ。
現場では、必要なんだ!!!

カジュアルに、移植性の高いバッチを書きたい

Windows環境で日々devるITエンジニアの皆さんへ。

PowerShellが登場してずいぶん経ち、アップデートも重なってきている。けど職場環境を見渡してみるとあまり普及しているとはいえない。利用されているのは相変わらず古き良き.batだ。
ちょっと高度なことはC++,C#等で書いたバイナリやらRubyPythonに仕事を受け渡したり。あるいはVBScriptJScript(WSH)で書いたり。

ん?JScriptってJavaScript的なやつなのか。
じゃあフロントエンドで書き慣れてるJSで、バッチが書ける?

WSH(Windows Script Host)ではJScriptが使える

WSHやらJScriptとはなんぞやということについては各自調べていただくとして、WSHは廃れてるので本来はPowerShell使うべきですよというのも置いといて。
一言で言うと「ほぼJavaScriptな言語でバッチが書けます」ということだ。これが追加の環境構築なしで使える(客先常駐なんかで重要)のがうれしい。

こんな感じでコマンドやバッチファイルからスクリプトを呼び出して使う。

> cscript hoge.wsf
<!-- hoge.wsf -->
<job>
<script language="JavaScript">

function hoge() {
  var fso = WScript.CreateObject('Scripting.FileSystemObject');
  // ファイル読み込み
  var streamReader = fso.OpenTextFile('hoge.txt', 1, false);
  var lines = streamReader.ReadAll();
  // ファイル書き込み
  var streamWriter = fso.CreateTextFile('huga.txt', true);
  streamWriter.Write(lines);

  // コンソールに出力
  WScript.Echo('hoge!');
}

// 関数を呼んでスクリプト終了
WScript.Quit(hoge());

</script>
</job>

同じような仕組みでVBScriptも書いたりできるのだが、よりマシなJScriptで処理が書けることがわかった。よっしゃよっしゃ。
と言いたいところだがちょっと待って欲しい。
おそらく未だ多くの現場で使われているであろうWindows7には、JScript5.8が搭載されている。JScript5.8はJavaScriptでいうところの1.5であり、これはECMAScript3ベースだ。つまり、String.prototype.trimやらArray.prototype.mapなどの便利メソッドは使えないのだ。

なお、IEはバージョンアップに伴って新しいバージョンのJScriptを使用できるが、WSHから利用するエンジンはJScript5.8で固定されてしまう。いろいろ頑張っても固定されてしまう。subtech.g.hatena.ne.jp

JScript5.8環境でもECMAScript5相当のコードを

やっぱりES5から登場した素敵メソッドを使いたい。使いたいなら作ればいいじゃない!というか先人のコードを利用させてもらえばいいじゃない!
ということで、JScript拡張ライブラリを用意した。

github.com

自分では大したことはしていない。偉大なるES5-shimとJSON3をconcatして、クラス的な仕組みとファイル操作系のヘルパーを追加したのみ。みんな大好きiniファイルが扱える。
以下のように、dist/JScriptExtender.js あるいはminの方をインクルードして使う。
なおテストはしたが独自実装部分のドキュメントは未作成だ。しばし待て。
(追記:2015/06/22)ドキュメント書きました。READMEも。

<job>
<!-- ここでインクルードする -->
<script language="JavaScript" src="dist/JScriptExtender.js"></script>
<script language="JavaScript">

function es5Test() {
  // Arrayの素敵メソッド
  var num = [1, 2, 3, 4, 5].filter(function(v){
    return (v % 2 === 0);
  }).map(function(v) {
    return v * v;
  }).reduce(function(prev, current, i , ar) {
    return prev + current;
  });
  WScript.Echo(num); // => 20

  // JSONを扱う
  var str = JSON.stringify({'Hello': 123});
  WScript.Echo(str); // => '{"Hello":123}'

  // iniファイルを読む
  //   iniの内容がハッシュ/配列としてオブジェクトにロードされる
  var iniReader = new Ini('hoge.ini');
  var iniObj = iniReader.Load();
}
WScript.Quit(es5Test());

</script>
</job>

他にも、マルチプラットフォームが考慮されてるライブラリはインクルードして使うことができる。ちょっと試した感じだと、underscore.jsは使えた。

おまけ:VisualStudioでデバッグできます

デバッグは素のWindowsではできないのだが、VisualStudioがあればできる。セットアップについては下記が詳しいので紹介。kaeruz.com

さいごに

一手間加えれば、生まれたままのWindowsでもわりと快適にJSなバッチ書けますよということで。あまりクリティカルなところには使えないけど、ちゃちゃっと何か動かしたいときにはアリな選択肢ではないかと。ECMA標準に定義されてない機能も使えますしね。MSDNのドキュメントはいまいち辿りづらいけど。

しかし、そもそもWSH脆弱性やドキュメント整備不良が理由で廃れてるわけでしで、ドザーなエスイーとしてはPowerShellをちゃんと使えるようにするか、最近活気のある.Net方面に走るのが正しいと思われま。

エンジョイ。