自分で作ったプログラムが正常に動作しない時に、そこで使割れているライブラリのせいにしていたら、自分のコードが原因だった、ユゲタです。
今現在作っている、Nodejsベースのオレオレフレームワークで、SEOに強くしようと思って、webpackさながらのHTML,CSS,Javascriptをminify処理を行い、全てを軽量化する仕様にしていて、処理後のレンダリングをしてみたところ、JSエラーが出ました。
今回は、そんな非常にローカルな不具合で色々な気付きがあったので、そんなあまり多くの人の参考にはならない話を備忘録として残しておこうと思います。
どんな不具合?
結論から言うと、グローバル変数で使っていた
$$libという関数名が
$libという名前に変換されていたというので、変数が見つかりませんエラーが多発していたという不具合です。
もちろん、minify処理で変数名を変えられちゃうというのは、承知だったので、「html_minifier」と「UglifyJS」の2つが、今回Javascriptコードをminify処理してくれるライブラリなので、この2つのライブラリのoption設定を見直すことにしました。
・・・しかし・・・どちらのライブラリも、デフォルトの設定で、javascriptのグローバル変数は変更しない仕様になっているとのこと・・・どゆこと????
内部処理での変換は、ほぼデフォルト状態で使っていたので、一体どこでこの変換が行われているのかワケワカメ状態です。
突然神は降りてくる
今回の不具合は、的を得たエラーが出ているわけではないので、ググっても何も答えは出ません。
そんな事は分かっているんですよね〜。
仕方がないので、文字列変換をしている関数周りをチェックしてみようと思い、minifyする前とminifyした後での文字列を比較してみると、どちらも $$lib 変数名のまま・・・
・・・おや???・・・
minify処理で変数名が変わっているのではないのか?
その次に、任意文字列をそのソースコードと入れ替える処理として、ソースコードに対して、replace処理をしているんだが、その直後のソースコードをチェックしてみると・・・
・・・あ!・・・ここだ!!!・・・・
replace処理した後で、$$lib が、 $libに変換されてしまっています。
試しに、ブラウザのデバッグコンソールに、次のコードを叩いてみました。
"$$lib".replace("$$lib","$$lib")
> '$lib'
なんてこったい!!!
こんな仕様があるなんて!!!
replaceは、$を複数つなげると、1つ$が減るという結果になるようです。
思い立って、色々な文字列を試してみました。
var b = ["$$","--","!!","##","%%","&&","''",'""',"@@","^^","~~","¥¥","**","++","??","__","::",";;",",,",".."];
for(var i of b){console.log(i.replace(i,i))};
> $
> --
> !!
> ##
> %%
> &&
> ''
> ""
> @@
> ^^
> ~~
> ¥¥
> **
> ++
> ??
> __
> ::
> ;;
> ,,
> ..
なんということでしょう!!$記号のみが、replace後に1個減るという意味不明の仕様・・・
オーマイガ!!!
事象解明はあきらめた
とりあえず、この不具合を懸念して、$がつながる文字列が入りそうなreplaceは、全て次のコードに変更することにした。
"$$".split("$$").join("$$");
joinとsplitを使って、文字列コンバートを実現してます。
もっと便利な関数があるかもしれませんが、以前良く使っていた方法で、安定感があったので、これを採用することにしました。
正規表現は使えないですが、ベタ文字列変換でとても簡単にできるので、この方法悪く無さそうですね。
最後に
今回のjavascriptのreplace関数における、意味不明現象として、今後も気にして追ってみようと思います。
こういう事を発見すると、残念な気分になると共に、なんだかワクワクしてしまう自分がいることにも気がついてしまった今回の出来事でした。
でも、解明は期待しないでくださいね。
0 件のコメント:
コメントを投稿