Javascript はファイル間の依存関係を一切書けない。ロードする順番は結局 script 要素の出現順、つまり HTML 依存。どう考えても気持ち悪い。のでどうにかして require もどきを作りたい。
function createXMLHttpRequest() { return this.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP"); } var __LOADED_FEATURES = {}; var Global = this; // this == window == Global function require(lib) { if (__LOADED_FEATURES[lib]) return false; var req = createXMLHttpRequest(); req.open("GET", lib, false); // 同期 req.send(null); if (req.status == 200) { // IE ではグローバルコンテキストで実行してくれない。 Global.eval(req.responseText); __LOADED_FEATURES[lib] = true; } else { throw Error("Load Error"); } return true; } require("/ruby.js"); require("/mm.js");
Global という名前のオブジェクトが宣言されてなかったりするので強調をこめて宣言してある。それ以上の意味はないです。window.eval
でも問題なし。見たとおり XMLHttpRequest を使って取得し、eval させてみる。
これは Firefox 1.0.7と Opera 8 ではうまくいくけど、IE 6 ではうまくいかない。
IE の場合 eval する部分のコンテキストが変わってくれない。つまり mm.js に var MottoMottoMeidosan = function () { .. }
とかいう宣言があったとき、require 関数の変数オブジェクトに代入されやがるので、require のあとに new MottoMottoMeidosan()
とか書くと「そんな変数宣言されてません」と怒られる。
解決法なんですが、さっぱりわかりません。誰か助けて。
なんだったら .php にでもして include()
でもいいんだろうけど、これは完全に負けだよね(謎
卑怯な解決方法1を発見した。
eval(req.responseText.replace(/^var/g, ""));
インデント依存っていうか副作用がどれだけあるか不明すぎ。
JSAN つかえよバーカ。
JSAN はそもそもグローバルスコープで eval することなんて考えてない。指定したオブジェクトだけグローバルスコープに登録してる。つまり基本的に一個のファイルで一つの固まりしかロードできない。use は必要なのをグローバルスコープに登録するらしい。 DOM 定数とかをグローバルスコープに登録するなら全部 use/export の引数に書けってことなのか?
なんか素晴らしすぎて使いづらいなぁ。特定ファイルを単純にロードしたい。とくにディレクトリ構造を要求するのがなんともいえない。
疑問なんだけど JSAN は 291 行ものコードを最初から書いておけっていうだろうか?
script 要素二つ書けっていうんだったら目的が違うな。モジュールシステムが欲しいんじゃないし。