WordPressdeでjQueryを使用する際に$が競合する理由とnoConflict()の正体

`$`が競合する理由と`noConflict()`の役割

jQueryのトラブルの中でも、最も頻出するエラーがあります。

`$ is not a function`

このエラーは「jQueryが読み込まれていない」時だけに出るわけではありません。
むしろ、jQueryは存在しているのに使えない時に出ます。

そしてこの現象の正体が `noConflict()` です。

多くの解説では「他ライブラリと競合するから」とだけ説明されますが、それだけでは不十分です。
本質は、`$` がそもそもjQuery専用の記号ではない、という点にあります。

`$`は特別な記号ではない

JavaScriptでは、次のコードは普通に成立します。

var $ = 123;
console.log($);

`$` は予約語でもキーワードでもありません。
単なる変数名です。
つまり、誰でも自由に使えます。

jQueryはこの短い名前を採用したことで、コードを簡潔に書けるようになりました。

$('.box').hide();

しかし同時に問題を生みました。
他のライブラリも同じ変数名を使えるという問題です。

競合は実際に起きる

たとえば、Prototype.js という古いライブラリがあります。
これも `$` を使用します。

$('header');

この `$` は「DOM要素を返す関数」です。
一方、jQueryの `$` は「jQueryオブジェクトを返す関数」です。

同じ記号なのに意味が違います。

もし両方が同時に読み込まれると、後に読み込まれた方が `$` を上書きします。
つまり、jQueryが存在していても、`$` がjQueryを指さなくなります。

これが `$ is not a function` の正体です。

`noConflict()`が何をしているのか

jQueryはこの問題を解決するため、起動時に次の処理を行えます。

jQuery.noConflict();

この関数が行っている処理はシンプルです。

  • `$` を解放する
  • `jQuery` という名前だけを残す

つまり「$はもうjQueryのものではない」と宣言します。

内部的には、jQuery読み込み前に存在していた `$` の参照を復元しています。
そのため、先に読み込まれていたライブラリは壊れません。

実際の状態の変化

noConflict前:

  • `$` → jQuery
  • `jQuery` → jQuery

noConflict後:

  • `$` → 元のライブラリ
  • `jQuery` → jQuery

この状態が、WordPressの標準です。

WordPressが必ずnoConflictを使う理由

WordPressは、テーマとプラグインが自由に追加されるCMSです。
つまり、どのJavaScriptライブラリが読み込まれるか事前に分かりません。

もし `$` をjQueryが占有したままだと、次のような問題が起きます。

  • プラグイン同士の破壊
  • 管理画面のUI停止
  • 外部ウィジェットの不具合

そこでWordPressは、安全側に倒します。
常にnoConflict状態のjQueryを提供するのです。

これにより、他ライブラリは `$` を自由に使用できます。

ではどうやってjQueryを書くのか

WordPressでは、次の書き方が基本になります。

jQuery(function($){
  $('.button').on('click', function(){
    $('.panel').toggleClass('open');
  });
});

この `$` は「引数として渡されたローカル変数」です。
グローバルの `$` とは別物です。

ここが重要です。
WordPressでは `$` を使えないのではなく、グローバル `$` を使ってはいけないのです。

よくある誤解

1. jQueryが壊れていると思う

多くの人は `$ is not a function` を見て、jQueryが壊れたと考えます。
しかし実際には、jQueryは正常に動作しています。

問題は「参照している変数」です。

2. CDN版にすれば直る

CDNのjQueryを読み込むと一時的に直ることがあります。
しかしそれは `$` を上書きしただけです。

プラグインが別のライブラリを使っている場合、今度はそちらが壊れます。

3. `$` を使えないのは不便

実際には使えます。
ただしスコープを限定する必要があります。

(function($){
  $('.menu').show();
})(jQuery);

これは即時関数でローカル `$` を作っています。
WordPressテーマではこの書き方がよく使われます。

なぜこの設計が重要なのか

この仕組みは単なる互換性対策ではありません。
大規模システムにおける「名前空間」の問題です。

JavaScriptには本来、強い名前空間がありません。
そのため、グローバル変数は共有資源になります。

WordPressは、jQueryをnoConflictにすることで次のことを実現しています。

  • テーマはjQueryを使える
  • プラグインもjQueryを使える
  • 他ライブラリも使える

つまり、衝突しない共存環境を作っています。

注意点:最も危険なコード

次のコードは特に危険です。

<script>
$('.slider').slick();
</script>

HTML直書きのインラインスクリプトです。
WordPressの読み込み順に依存するため、タイミングによって動いたり止まったりします。

必ずenqueueしたスクリプトファイル内で、jQueryラッパーを使用するべきです。

まとめ

`noConflict()`は制限ではありません。
むしろ、複数のJavaScriptが共存するための安全装置です。

`$` が使えないのではなく、グローバル `$` を使わない設計になっています。
そしてこれを理解すると、原因不明の「ボタンが効かない」「スライダーが動かない」といった不具合の理由が見えてきます。

jQueryのトラブルの多くはライブラリの問題ではありません。
変数スコープを理解していないコードが原因です。

そしてWordPressでは、それが最も表面化しやすいのです。