結論
wp_enqueue_script() で登録した JavaScript がページに出ないときは、次の5点を順に確認します。
- 依存関係(第3引数)に、未登録のハンドルが含まれていないか。
- 正しいフックで呼んでいるか(フロントは
wp_enqueue_scripts、管理画面はadmin_enqueue_scripts、ログイン画面はlogin_enqueue_scripts)。 - 同じハンドル名が、別の場所で先に登録されていないか。
- テンプレートに
wp_head()/wp_footer()が書かれているか(in_footerが true ならwp_footer()が必須)。 - 条件分岐(
is_page()など)で、意図せず除外されていないか。
特に1は、依存関係が満たされないと script タグが出力されない一方で、以前のバージョンでは警告もエラーも出なかったため、見落としやすい原因です(本検証環境 7.1.2 では、WP_DEBUG 有効時に _doing_it_wrong の通知が出ました。後述のケースA)。
原因・仕組み
wp_enqueue_script() は、スクリプトを「キューに入れる」関数です。実際の出力は、wp_head() や wp_footer() の中で wp_print_scripts() などが走るときに行われます。このとき、依存先がすべて登録済みかどうかが確認されます。
$ver の扱いは、false(既定)なら WordPress のバージョンが付き、null なら付かず、文字列ならその値が付きます。WordPress 6.3 からは、第5引数が $in_footer(真偽値)から $args 配列に拡張され、strategy(defer / async)と in_footer を指定できます(詳細はwp_enqueue_script で defer / async を付ける方法)。
手順(サンプルコード)
正しい登録の基本形です。
add_action( 'wp_enqueue_scripts', function () {
wp_enqueue_script(
'ks-app',
get_theme_file_uri( 'js/app.js' ),
array( 'jquery' ), // 依存先は登録済みのハンドル名
filemtime( get_theme_file_path( 'js/app.js' ) ), // 更新時刻で自動的にキャッシュを更新
array( 'in_footer' => true )
);
} );
原因を調べるときは、次のコードをテンプレートや functions.php に一時的に入れ、状態を確認します。
add_action( 'wp_print_footer_scripts', function () {
foreach ( array( 'registered', 'enqueued', 'done' ) as $s ) {
error_log( "ks-app $s: " . var_export( wp_script_is( 'ks-app', $s ), true ) );
}
}, 1 );
enqueued が true で done が false なら、キューには入ったが出力されていません。依存関係かフッターの欠落を疑います。
動作確認(検証環境と結果)
WordPress 7.1.2、PHP 8.2.12 で実行しました(php C:Tempwp-testrun.php wp-enqueue-script-not-loading.php、ログは tests フォルダ)。
- ケースA:
ks-appが未登録のks-missing-libに依存。enqueued=true、registered=trueだが、出力された script は「なし」、done=false。このバージョンではdoing_it_wrongの通知が発生し、内容は「ハンドルks-appのスクリプトは、未登録の依存関係とともにキューへ追加されました:ks-missing-lib」(バージョン 6.9.1 で追加と表示)でした。デバッグ表示が無効の環境では、気づきにくいままです。 - ケースB: 依存先を
wp_register_scriptで登録し、キューに入れ直すと、ks-missing-lib-jsとks-app-jsの両方が出力された。 - ケースC: 先に
first.jsで登録済みのハンドルに、後から別の src でwp_enqueue_scriptしても、登録された src はfirst.jsのままで、後の指定は無視された。 - ケースD:
$verに false を渡すと?ver=7.1.2、null では付かず、文字列3.1では?ver=3.1になった。
テーマのテンプレートに wp_footer() が無い場合の挙動は、この検証では実行していません。
wp_enqueue_script が読み込まれない原因と対処の注意点
- 依存関係が不明なとき、
wp_script_is( 'handle', 'registered' )で登録の有無を確認します。 - jQuery は WordPress 同梱のハンドル
jqueryを指定します。別の CDN の jQuery を使う場合は、wp_deregister_scriptと再登録が必要で、プラグインとの互換性に注意が要ります。 - 他のプラグインが同じハンドル名を使うと、片方しか有効になりません。ハンドルには接頭辞を付けます。
- キャッシュ系プラグインや CDN が古い JS を配信している場合は、
$verを変更して確認します。 - 管理画面で読み込むスクリプトは、
admin_enqueue_scriptsのフック引数$hook_suffixで対象画面を絞ります。
wp_enqueue_script が読み込まれない原因と対処でよくあるミス
wp_enqueue_scriptsに掛けず、functions.php の直下でwp_enqueue_script()を呼ぶ。get_template_directory_uri()を使い、子テーマ側のファイルを指せていない(get_template_directory_uri と get_stylesheet_directory_uri の違い)。<script>タグを header.php に直書きし、依存関係の順序を壊す。$verを毎回time()にして、ブラウザキャッシュが全く効かなくなる。- 条件分岐で
is_page( 'contact' )を使い、スラッグや ID の指定が実際の固定ページとずれている。
wp_enqueue_script が読み込まれない原因と対処のチェックリスト
- 依存先ハンドルは、すべて登録済みか。
- フック名は、表示する画面に合っているか。
- ハンドル名に接頭辞を付け、重複を避けたか。
wp_head()とwp_footer()がテンプレートにあるか。- ブラウザの開発者ツールで、JS の URL が 404 になっていないか。
- ファイルのパスは、親子テーマの関係を考慮しているか。
wp_enqueue_script が読み込まれない原因と対処のFAQ(よくある質問)
Q. wp_register_script と wp_enqueue_script の違いは?
A. 前者は登録だけ、後者は登録と出力予約です。後者の src を省略すると、登録済みのハンドルをキューに入れるだけになります(wp_register_script() の使い方|説明・引数・注意点)。
Q. 読み込まれたか確認する方法は?
A. wp_script_is( 'ks-app', 'done' ) で出力済みかを確認でき、ブラウザのページソースで id が ks-app-js の script タグを探す方法も使えます。
Q. 読み込み順を変えたい。
A. 依存関係(第3引数)で先に読むものを指定します。依存の宣言が、順序を保証する唯一の正式な方法です。
筆者の見解(wp_enqueue_script が読み込まれない原因と対処)
読み込まれない問題の多くは、ブラウザ側ではなく、PHP 側のキューの状態に原因があると考えます。wp_script_is() の3つの状態を見る習慣を付けると、推測で試行錯誤する時間をかなり減らせます。また、依存関係の未登録に通知が出る環境では、開発中は必ずデバッグ表示を有効にしておくのがよいと思います。
wp_enqueue_script が読み込まれない原因と対処の関連項目
- wp_enqueue_script() の使い方|説明・引数・注意点
- wp_register_script() の使い方|説明・引数・注意点
- wp_enqueue_scripts フックの使い方|説明・引数・注意点
- wp_script_is() の使い方|説明・引数・注意点
- wp_dequeue_script() の使い方|説明・引数・注意点
