いつものように、VScodeを使って、Webシステムを作っていたら、なんかエラーが出てる・・・
SyntaxError: Unexpected token 'if'
非常にニッチなエラーで、他の人は起こり得ない内容でもあるけど、
もしかしたら世の中にもう一人ぐらい同じエラーで悩まされる人もいるのではないかと思い、ブログにエラーの内容と影響範囲とその対応方法を書いておきます。
エラー詳細
このエラーは、VScodeでLiveServerという機能拡張のプラグインを使っていて、特定の状況で発生しました。
※LiveServerがわからない人は、下記ページを参照ください。
https://www.freecodecamp.org/news/vscode-live-server-auto-refresh-browser/
通常、LiveServerを使うと、bodyタグにLiveServerでページをハックする用のscriptタグが埋め込まれます。
以下のような内容でした。
<!-- Code injected by live-server -->
<script>
// <![CDATA[ <-- For SVG support
if ('WebSocket' in window) {
(function () {
function refreshCSS() {
var sheets = [].slice.call(document.getElementsByTagName("link"));
var head = document.getElementsByTagName("head")[0];
for (var i = 0; i < sheets.length; ++i) {
var elem = sheets[i];
var parent = elem.parentElement || head;
parent.removeChild(elem);
var rel = elem.rel;
if (elem.href && typeof rel != "string" || rel.length == 0 || rel.toLowerCase() == "stylesheet") {
var url = elem.href.replace(/(&|\?)_cacheOverride=\d+/, '');
elem.href = url + (url.indexOf('?') >= 0 ? '&' : '?') + '_cacheOverride=' + (new Date().valueOf());
}
parent.appendChild(elem);
}
}
var protocol = window.location.protocol === 'http:' ? 'ws://' : 'wss://';
var address = protocol + window.location.host + window.location.pathname + '/ws';
var socket = new WebSocket(address);
socket.onmessage = function (msg) {
if (msg.data == 'reload') window.location.reload();
else if (msg.data == 'refreshcss') refreshCSS();
};
if (sessionStorage && !sessionStorage.getItem('IsThisFirstTime_Log_From_LiveServer')) {
console.log('Live reload enabled.');
sessionStorage.setItem('IsThisFirstTime_Log_From_LiveServer', true);
}
})();
}
else {
console.error('Upgrade your browser. This Browser is NOT supported WebSocket for Live-Reloading.');
}
// ]]>
</script>
LiveServerの機能で、HTMLなどの静的ファイルを更新した場合に即座に表示に反映するための、機能と思われます。
このscriptタグが埋め込まれただけだとエラーにならないのですが、独自で使っているフレームワークで、
ヘッダメニューなどHTMLパーツをJavascriptで自動読み込みするライブラリを実行させた時に、その中で読み込まれたhtmlソース内のscriptコードは、
src属性は再読み込み、プログラムが描かれている場合は、即時実行するようにセットしているんですが、
このscriptタグの内容を即時実行しようとしてエラーになっているようでした。
影響範囲
色々調べてみて、このLiveServerの埋め込みscriptにはある特性がありました。
今のところの調査結果では、bodyタグと、svgタグの内部にscriptタグを埋め込むという仕様になっているようです。
何故、svgタグ?
と思った人もいると思いますが、よく考えると、svgは、個別にnamespaceを持った、内部完結の構造体です。
要するにHTML内のbodyと同じと考えると納得が行きます。
もちろん、今回エラーがでたページの読み込みソース内にもsvgタグが存在していました。
対応方法
とりあえずエラーが出ても、構築するwebページへの影響は無さそうなので、try~catchでエラーが出ても無きものとして継続処理できるようにすることで解決できましたが、
VScodeの機能拡張設定で回避できるかもしれません(設定見たけどよくわからんかった)
でも、そもそも、設定をいじると、環境依存で発生するバグになるので、できればデフォルトで使いたいとも考えたので、ここは無視してもOKかも。
次に、埋め込み機能のプログラムの改善をしようとしたんですが、こちらもAjaxでの読み込み時点で埋め込まれてしまうため、VScodeのLiveServerとの相性と割り切ったほうがいいかもしれません。
あとがき
久しぶりに、ワケのわからないエラーに悩まされた休日でした。
こんな対応で丸一日費やしたけど、なんだか原因追及している間や、解決方法を考えている間、とても楽しく感じたのは、やはり変態系プログラマーだからかもしれませんね。
変態・・・いい響きですね。
プログラマーは変態たれ。
0 件のコメント:
コメントを投稿