Home
Valid.js は Assertion 機能を提供するライブラリです。
JavaScript には静的な型チェックシステムがなく Assertion 機能もありません。
(Assertion とは、プログラマーが「この場合はこうあるべき」と考えている内容をコードで表明したものです。プログラムの矛盾やバグをコンパイル時や実行時に検出する目的で使われます)
Valid.js は JavaScript に不足しているこれらの機能を提供します。
- 例外を発生させる ( Valid )
- 関数と引数を評価する ( Valid.args )
- 型を検証する ( Valid.type )
- 値を検証する ( Valid.keys, Valid.values, Valid.some )
- JSON の構造と型を検証する ( Valid.json )
- スタックトレースをダンプする ( Valid.stack )
サポートしている型の一覧 も参照してください。
WebModule には Valid.js がデフォルトで組み込まれており、WebModule でも Valid.js の機能を利用可能です。
(WebModule 動作環境では Valid.type()
ではなく $type()
でアクセスします)。
Assertion は、デバッグ中は大変有効な機能ですが、十分にデバッグが終わっている前提のリリースビルドにおいては、オーバーヘッドを生む不要な存在です。
WebModule を使うと、リリースビルドから Assertion を取り除くことができます。
リリースビルドから Assertion コードを取り除くには以下のようにします。
WebModule には、{@assert ... }@assert
, {@debug ... }@debug
, {@dev ... }@dev
で囲われたコードブロックをビルド時に自動的に削除する機能(プリプロセス)があります。Valid.js でもこれを使ってコードを取り除きます。
// このコードは残ります
console.log("hello")
//{@assert
for (var i = 0; i < 10000000000; ++i) {
console.log(i);
}
//}@assert
//{@debug
alert("debug");
//}@debug
//{@dev
alert("develop");
//}@dev
上記のコードを npm run min
でビルドすると、
{@assert ... }@asset
,
{@debug ... }@debug
,
{@dev ... }@dev
,
部分は全て消えます。
// このコードは残ります
console.log("hello")
lib/Valid.js や lib/WebModule.js には以下の validate / assertions コードが埋め込まれています。
...
// --- validate and assert functions -----------------------
//{@dev https://github.com/uupaa/WebModule/wiki/Validate
GLOBAL.$type = function(v, types) { return GLOBAL.Valid ? GLOBAL.Valid.type(v, types) : true; };
GLOBAL.$keys = function(o, keys) { return GLOBAL.Valid ? GLOBAL.Valid.keys(o, keys) : true; };
GLOBAL.$some = function(v, cd, ig) { return GLOBAL.Valid ? GLOBAL.Valid.some(v, cd, ig) : true; };
GLOBAL.$args = function(api, args) { return GLOBAL.Valid ? GLOBAL.Valid.args(api, args) : true; };
GLOBAL.$valid = function(v, api, hl) { return GLOBAL.Valid ? GLOBAL.Valid(v, api, hl) : true; };
GLOBAL.$values = function(o, vals) { return GLOBAL.Valid ? GLOBAL.Valid.values(o, vals) : true; };
//}@dev
...
$valid
, $type
や $keys
を {@dev ... }@dev
コードブロックに埋め込んで利用します。
function foo(value) { // @arg Boolean = false
//{@dev
$valid($type(value, "Boolean|omit"), foo, "value");
//}@dev
}
以下の foo は引数(param, callback) をチェックせず、別の関数 bar にそのまま渡しています。
foo は渡された引数に問題があるかどうかをチェックしていないため、
より深い部分(bar)でエラーが発生した場合に、
原因の特定に手間がかかるコードになっています。
// ナイーブなコード
function foo(param, // @arg Object - { type, target }
// @param.type String - "DOM" or "SVG" or "CSS"
// @param.target String = ""
callback) { // @arg Function = null - callback(param.type:String, param.target:String = ""):void
bar(param, callback);
}
function bar(param, callback) {
if (callback) {
callback(param.type, param.target);
}
}
このようなコードはナイーブ(脆弱)なコードと呼ばれます。
ナイーブなコードをより頑強でソリッドなコードにするのが Valid.js です。
以下のようにすることで、型のチェックや、keys/values のバリデーションが行えます。
// ソリッドなコード
function foo(param, // @arg Object - { type, target }
// @param.type String - "DOM" or "SVG" or "CSS"
// @param.target String = ""
callback) { // @arg Function = null - callback(param.type:String, param.target:String = ""):void
//{@dev
// [1] param が Object型 な事を確認しています
// [2] Object.keys(param) に含まれる key が "type" と "target" で、それ以外の不純物がない事を確認しています
// [3] param.type が String型 な事を確認しています
// [4] param.type の内容が "DOM", "SVG", "CSS" の何れかである事を確認しています
// [5] param.target が String型 で省略可能な事を確認しています
// [6] callback が Function型で省略可能な事を確認しています
$valid($type(param, "Object"), foo, "param"); // [1]
$valid($keys(param, "type|target"), foo, "param"); // [2]
$valid($type(param.type, "String"), foo, "param.type"); // [3]
$valid($values(param.type, "DOM|SVG|CSS"), foo, "param.type"); // [4]
$valid($type(param.target, "String|omit"), foo, "param.target"); // [5]
$valid($type(callback, "Function|omit"), foo, "callback"); // [6]
//}@dev
bar(param, callback);
}
function bar(param, callback) {
if (callback) {
callback(param.type, param.target);
}
}
foo({ type: "Canvas", target: "..." }, function(type, target) { });
上記の誤った( type: "Canvas" )のコードを指定すると、Valid.js が機能する様子を確認することができます。
Assertion が発動すると、DevTools のコンソールに foo の内容がダンプされ、
問題の箇所( param.type )がハイライト表示されます。