はじめに
お久しぶりです!
今回は、私が作っている WSH JScript用の汎用ライブラリ SenkoWSH などをアップデート(バージョン 3.6.0 → バージョン 7.3.0)したので、紹介したいと思います!
SenkoWSHの紹介
Windows上に最初から搭載しているWSH JScript実行環境用の汎用ライブラリとなります。
WSH JScript
バッチの実行環境で以下のような特徴があります。
- JavaScript で Windows 用のバッチを作成できる
- WSH JScript はどの Windows にも入っているため、Node.js をインストールしなくてもよい
- 会社内で配布/展開しやすい
- デメリットとして1999年に制定された ECMAScript Edition 3 (以下、ES3) までの機能しか使えない
詳細は、以下の記事で解説しております。
SenkoWSH
WSH JScript実行環境用の汎用ライブラリで、Visual Studio Code 上での開発、ES3の強化(Polyfill)、及びファイル操作や自動実行などが簡単に行えるようになります。
詳細は、以下の記事で解説しております。
SenkoWSHのアップデート
以前から自分用に作っていたのですが、最近さらに利用するようになり、より欲しい機能があったり、粗が見つかったりしたため、ゴールデンウィークを利用して、気になる部分の改善を行いました。
以下、大きく変わった点を説明します。
ES3の機能強化 Polyfill の改善
システム用のクラスの Polyfill の修正
Polyfill はここのソースコード内で行っているのですが、重大な問題がありました。
元々、Array の prototype
に ES3 になかった includes
や indexOf
などを追加していたのですが、なんと、これらの追加メソッドが for in
文で出てきてしまうんですよね。これはダメだと思い削除しました・・・。何かいい方法があれば良いのですが。
globalThisの追加
globalThis
系の変数は、JScriptに用意はされておらず、この変数は作ることが出来ないと思っていたのですが、以下のように作ることが出来ることが分かったので実装。
const global_var = ( function() { return this; } ).apply( null, [] ); if(!("globalThis" in global_var)) { // @ts-ignore globalThis = global_var; }
以下のページを参考にしました。
globalThis
がなかったので、これまで変数が定義されているかどうかを調べる方法がないと思っていました。これで、以下のように、グローバル空間で定義されているか調べることが可能となります。
if(!("xxx" in globalThis)) { // xxx が定義されていなかったらこの中が実行できる }
JSONの追加
JSON クラスは ES3 にはないんです。文字列からデータへは eval
でなんとか対応できるのですが、その逆(データから文字列変換)はできないですし、やっぱり JSON クラスで JSON.parse()
、JSON.stringify()
が欲しいと思い追加しました。
JSON.stringify()
の実装なんですが、htmlfile
のActiveXObject
を使う方法が有名なのですが、なぜかうまく動作せず、自分でコントロールできたほうが楽かと思い一から実装しました。
ファイル操作 SFile クラスの改善
バイナリ操作の強化
これまで、バイナリファイルはファイルを全て読み込む、あるいは全て書き換えるということしかできませんでしたが、バイナリファイルの一部分のみの読み書きが行えるように対応しました。
これまで、ADODB.Stream
などで取得したバイナリデータの配列(ByteArray
)と、JavaScriptの配列とで互換性がなく、このようなことはできないと思っていたのですが、調査したらMicrosoft.XMLDOM
で相互変換が行えることが分かり、実装できました。
以下のページを参考にしました。
ファイルの圧縮と展開を追加
zipファイルの圧縮と展開を追加しました。
7-zipがインストールされている場合は、そちらを自動的に利用し色々な拡張子に対応できるようにしました。また、.tar.gz
を指定した場合でも、一発で圧縮/展開が行えるように工夫しました。通常、7-zipのコマンドライン版を使用すると一発ではできないのですが、一度に実行できるようにしています。
システム機能 System クラスの改善
バッチスクリプトの実行
文字列を引数に取り、その引数の内容のバッチを実行する機能を追加しました。
バッチを実行時にShift_JIS
として実行するか、UTF-8
として実行するかが選べるようにしました。これは、CUI用の実行ファイルによっては、UTF-8
で出力するソフト(sqlite-toolsなど)があり、Shift_JISだtl文字化けするためです。
UTF-8
モードの実装方法ですが、デフォルトのShift_JIS
モードで起動後にchcp 65001
で文字コードを変更し、call
コマンドで、BOM無しUTF-8
(BOM有りだとエラーが発生する)を実行するようにしています。
その他の関連ライブラリの修正
さらに今回、SenkoWSHを強化するにあたり、他にも気になっていた自作のJavaScriptのライブラリも修正しました。
高機能数学ライブラリ konpeito
元々、JavaScriptで動作するライブラリ konpeito ですが、UMD (Universal Module Definition) 用のライブラリもビルドしていたにも関わらず、なぜかWSH上で実行できないことが判明。そのため、WSHで動くように調整を行い、複素行列部分のみを抜き出したライブラリを作成しました。
WSHで動かなかったか調査をしたところ、ES3にはhasOwnProperty
が存在しないなど複数の問題があり、以下のような部分の修正が必要でした。
- ゲッター/セッター
getter / setter
が利用できない - クラスの拡張
extends
が利用できない - 分散で使用していたメソッド名
var
が、予約語名と一致した名前が利用できない Array.prototype.splice()
の仕様が ES3時代と現在の仕様で違う
また、原因不明でinstanceof
が思った通りの動作をしない場合もあり、修正を重ねてなんとかWSH上で動くようになり、konpeito-ES3という新規ライブラリとして公開しました。
通常版の konpeito より任意精度計算等の機能が減っていますが、それ以外の複素行列計算が行えるため役に立つかと思います。
文字列処理ライブラリ MojiJS
日本語文字列の Windows-31J
、Shift_JIS-2004
などのエンコードやデコード、漢字水準の調査などが行えるライブラリ MojiJS ですが、こちらも WSH 用のライブラリを用意していましたが動作しないことが判明。これもまた、WSHで動くように調整を行いました。
なぜ、動作しなかったかというと、どうやらJScriptファイルの1ファイルのサイズが、500KBを超えると動作しないようなのです。MojiJSは文字変換マップのために、600KB近くあり、これによってエラーが起きていました。
文字変換マップの作成アルゴリズムを改善(コードポイントを数字で記録していたのを文字データで記録)して150KB程度にすることで、WSHでも動作するようにしました。
おわりに
最後まで見ていただきありがとうございます。もしよかったら使ってみて下さい!
最近、リアルが忙しかったり色々あり、githubでプログラムしていない日々があったのですが、久しぶりに修正を行えて、とても楽しかったです。これまで気になっていた部分を直せると気持ちもすっきりしますし、何よりプログラミングは楽しいですよね!
コメント