Edited at

Lightningのjsがエラーになってしまう理由がわからない時

More than 3 years have passed since last update.

まずは自分の記述が間違っていると考えるのが王道です。おそらく自分の記述が間違っています。ですが、ベータ版だからか、jsファイルの保存や動作時に幾つか予期しない挙動がありました。


文字列{!の繫がり

var fn = function(flag1, flag2){!flag1 && flag2

? this.f()
: this.g();
};

{!value;}
// {!
/* {! */

のように、{!で始まる文字列があると、保存時にその周辺でエラーが起きます。驚くべきことにコメント内の文字列でも起きます。

これは、{ !value;}のように、{!の間に空白文字を挟めばOKです。


/正規表現リテラル中の引用符"'/

現在Lightningのjs内に正規表現リテラルを記載すると、JsonStreamParseExceptionとか言われて保存できないことがあります。

var re = /can't save this?/g;

シングルクォート及びダブルクォートが含まれていると、対応する引用符を探してしまっているようです…。

RegExpオブジェクトを明示的にインスタンス化することで保存できるようになります。

var re = new RegExp("can't save this?", "g");

その他の方法としては、実行時に副作用のない形で、対応する引用符を書いてしまって正規表現を閉じるという方法もあります。保存さえできれば、実行時には通常のJavaScriptの解釈にて処理されます。

// var re=/can't?/;

var re = /can't?/;// '/;

// var re2 = /can't?/,b=true;
var re2 = (/'/,/can't?/),b=true;

1つ目は実行時はコメントですが、パース時には引用符を書いた後、正規表現を終わらせる形です。2つ目は先に引用符付きの正規表現を記述してカンマ区切りすることで、実行時には後ろ側の式が有効になる形にしています。


/正規表現リテラル中のエスケープ中括弧\{/

引用符だけでなく、中括弧も注意が必要です。

var re_ok = /a{1,3}/; // parsed correctly

// var re_ng = /\{\{\{/;
var re_ng = /\}\}\}/;

(出現回数指定などの用途で)エスケープせずに使用している場合は良いのですが、

なぜか、エスケープしている場合に、リテラル外の中括弧と解釈されるらしく、保存時に関数が終わっていないだとか不審なエラーになります。

\{の代わりに[{]で置き換え([]中で使われていたらエスケープ文字を外す)れば大丈夫だと思いますが、より無難に行くならば、全体をnew RegExpでくるめばOKです。


/正規表現リテラル中のコメント風文字列/

引用符や中括弧と似たような理由で、正規表現リテラル中にコメントと解釈されうる文字列を含む場合も注意が必要です。

var re1 = /ends with slash character \//;

var re2 = /0 or more slash characters \/* /;

これらは、保存はできるのですが、実行画面にてソースを見てみると、コメントと解釈されうる部分以降の記述がコメント扱いになり削除されてしまっています。保存ができてしまうので気づく機会が遅れ、引用符や中括弧よりたちが悪いとも言えます。

回避策としては、new RegExpでの対応が好ましいと思います。


検索と置換

例えばminimizeしたJavaScriptには正規表現リテラルが多様されているので、そんな時はこれらどれかの方法を駆使しながらがんばって置き換えて行きましょう。

まずは{!\{\}\/で検索しましょう。

デベロッパーコンソールでは/re/形式で記述すれば正規表現でも検索できるので、引用符用に/\/[^/]*['"].*?\/(?!['"])/辺りで検索してみましょう。

誤マッチも出てしまうので置換は目視しながら行いましょう。

静的リソースに保存してそれを読み込むことで事足りるならこの問題は起きませんので、それに越したことはありません。