どこでおかしくなるのかはわかった。
「require.jsとQの組み合わせにおけるintellisenseの挙動」続き。
いろいろ試してみたところq.js
のdefine()
部分をjqueryのソースコードを参考に以下のように書き換えたら動作するようになった。
// RequireJS
} else if (typeof define === "function" && define.amd) {
define("Q", [], definition);
//define(definition);
// SES (Secure EcmaScript)
} else if (typeof ses !== "undefined") {
なんでこれでOKなのかはまだわかっていない。RequireJSのソースも読んでいるんだけれども、RequireJSのコンセプトがいまいち理解できていないせいかコード読んでも頭にぜんぜん入ってこない。でこの件を調べるのにjQueryのjquery/amd.js
を覗いてみた。コード自体は以下となっている。
気になったのはコメントの記述だ。引用がてら直訳してみる。
jQueryはdefineを使用する他のファイルと連結することができるが、匿名AMDモジュールを理解し適切な連結スクリプトを経由することができないため、名前つきAMDモジュールとして登録する。名前付きAMDはもっとも安全で強固な登録方法である。AMDモジュール名はファイル名を継承し、jQueryは小文字のファイル名を使用されるため小文字のjquery
が使用される。もしAMDモジュールがこのバージョンのjQueryを隠すためにnoConflict
を呼び出したい場合はグローバルオブジェクト生成したあと行うこと。そうすればうまく動くだろう。最大のポータビリティをのための注意として、jQuery以外のライブラリは匿名モジュールとして定義し、AMDローダーが公開するグローバル設定を避けることが望ましい。jQueryは特殊なケースである。詳細な情報は「https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon」を参照せよ。
つまり匿名AMDモジュールとして定義するのは可搬性を確保するうえで望ましい定義なのであった。intellisenseのために名前付きAMDモジュールで登録するように元コードを改変するのはいけない行いであるが、デザイン時の例外としてintellisense.jsに書くことで元コードをいじらずにうまくこの問題を解決できそうな気がするのでためしてみることにする。
require.intellisense.jsはVS2013では不要そう。
require.jsでロードするモジュールをintellisenseに対応させるためにVS2012用に「require.intellisense.js」というものがRequireJSの作者より提供されていたが、VS2013では不要なようだ。私が試した結果でも不要であった。
ただ気になるのはVS2013のインストールディレクトリのJavaScript\References
フォルダにrequire.intellisense.js
というファイルがあること。ひょっとするとこのディレクトリにこのファイルがあるせいでうまく動いているのかもしれないけれども、暗黙でこのディレクトリのファイルが参照されるようなことも書いてなかったし、暗黙参照の画面でもこのフォルダの中の他のファイルが明示的に参照されていたから、このフォルダに入れているからといって暗黙参照されているわけでもなさそうだ。ちなみにこのVS2013のrequire.intellisense.js
はRquireJSの作者のものとは違う中身であった。やっていることは大差ないが。