Make WordPress Core

Opened 4 weeks ago

Last modified 44 hours ago

#64229 reopened enhancement

Enqueueing scripts and script modules should warn when dependencies are missing

Reported by: westonruter's profile westonruter Owned by: westonruter's profile westonruter
Milestone: 6.9.1 Priority: normal
Severity: normal Version: 6.9
Component: Script Loader Keywords: has-patch has-unit-tests fixed-major
Focuses: javascript Cc:

Description (last modified by westonruter)

Given the following plugin code:

<?php
/**
 * Plugin Name: Try in enqueuing classic script and script module with missing dependencies
 */

namespace TryEnqueueingScriptsWithMissingDependencies;

add_action(
        'wp_enqueue_scripts',
        static function () {
                wp_enqueue_script( 'classic-script-with-missing-dependency', 'https://example.com/classic-script.js', array( 'classic-dependency' ) );
                wp_enqueue_script_module( 'script-module-with-missing-dependency', 'https://example.com/script-module.js', array( 'module-dependency' ) );
        }
);

In WordPress 6.8, the classic script is not printed but the script module is. However, as of WordPress 6.9, script modules now behave the same as classic scripts when they have missing dependencies: the script module is not printed. This change was introduced in r60999 to fix #63486. See code in question.

As was extensively troubleshooted in the #core-interactivity-api channel in Slack, this change in behavior was difficult to debug, and it was difficult to identify why a script was not being printed.

Query Monitor actually helpfully warns when attempting to enqueue a classic script script that is missing dependencies, but it doesn't currently do the same for script modules:

https://core.trac.wordpress.org/raw-attachment/ticket/64229/query-monitor.png

This may be due to #60597, where WP_Script_Modules lacks the necessary accessors.

In any case, WordPress core should itself issue a _doing_it_wrong() for both classic scripts and script modules whenever there is a missing dependency for an enqueued script.

Attachments (1)

query-monitor.png (165.9 KB) - added by westonruter 4 weeks ago.

Download all attachments as: .zip

Change History (13)

#1 @westonruter
4 weeks ago

  • Description modified (diff)

This ticket was mentioned in PR #10545 on WordPress/wordpress-develop by @deepakprajapati.


2 weeks ago
#2

  • Keywords has-patch added; needs-patch removed

This PR adds developer-facing _doing_it_wrong() notices when a script or script module is enqueued with dependencies that have not been registered.

Currently, WordPress silently skips printing such assets, which makes dependency issues difficult to diagnose. This change improves debugging clarity during development.

What’s changed
✅ Classic scripts (WP_Scripts)

  • Detects missing dependencies in all_deps().
  • Emits a _doing_it_wrong() notice identifying the script handle and missing dependency handles.

✅ Script modules (WP_Script_Modules)

  • Detects missing dependencies during dependency sorting.
  • Emits a _doing_it_wrong() notice with the module ID and missing dependency IDs.

Both implementations:

  • Prevent duplicate notices using a static cache.

Trac ticket: https://core.trac.wordpress.org/ticket/64229

https://github.com/user-attachments/assets/64a0d617-2b42-4544-b119-d20553f38363

@westonruter commented on PR #10545:


2 weeks ago
#3

Let's make sure to add unit tests for these changes as well.

#4 @westonruter
2 weeks ago

  • Keywords needs-unit-tests added

@westonruter commented on PR #10545:


12 days ago
#5

This is looking good to me. I will plan to finish reviewing and commit by next week.

@westonruter commented on PR #10545:


9 days ago
#6

I'm testing this with the following plugin code:

add_action(
        'wp_enqueue_scripts',
        static function () {
                wp_enqueue_script( 'bad-script', '/bad.js', array( 'nope' ) );
                wp_enqueue_style( 'bad-style', '/bad.css', array( 'nope' ) );
                wp_enqueue_script_module( 'bad-module', '/bad.mjs', array( 'nope' ) );
        }
);

I get the following log entries:

  • PHP Notice: Function WP_Dependencies::all_deps was called <strong>incorrectly</strong>. The style with the handle bad-style was enqueued with dependencies that are not registered: nope. Please see <a href="https://developer.wordpress.org/advanced-administration/debug/debug-wordpress/">Debugging in WordPress</a> for more information. (This message was added in version 7.0.0.) in /var/www/src/wp-includes/functions.php on line 6131
  • PHP Notice: Function WP_Dependencies::all_deps was called <strong>incorrectly</strong>. The script with the handle bad-script was enqueued with dependencies that are not registered: nope. Please see <a href="https://developer.wordpress.org/advanced-administration/debug/debug-wordpress/">Debugging in WordPress</a> for more information. (This message was added in version 7.0.0.) in /var/www/src/wp-includes/functions.php on line 6131
  • PHP Notice: Function WP_Script_Modules::sort_item_dependencies was called <strong>incorrectly</strong>. The script module bad-module was enqueued with dependencies that are not registered: nope. Please see <a href="https://developer.wordpress.org/advanced-administration/debug/debug-wordpress/">Debugging in WordPress</a> for more information. (This message was added in version 7.0.0.) in /var/www/src/wp-includes/functions.php on line 6131
  • PHP Notice: Function WP_Script_Modules::sort_item_dependencies was called <strong>incorrectly</strong>. The script module bad-module was enqueued with dependencies that are not registered: nope. Please see <a href="https://developer.wordpress.org/advanced-administration/debug/debug-wordpress/">Debugging in WordPress</a> for more information. (This message was added in version 7.0.0.) in /var/www/src/wp-includes/functions.php on line 6131
  • PHP Notice: Function WP_Script_Modules::sort_item_dependencies was called <strong>incorrectly</strong>. The script module bad-module was enqueued with dependencies that are not registered: nope. Please see <a href="https://developer.wordpress.org/advanced-administration/debug/debug-wordpress/">Debugging in WordPress</a> for more information. (This message was added in version 7.0.0.) in /var/www/src/wp-includes/functions.php on line 6131
  • PHP Notice: Function WP_Dependencies::all_deps was called <strong>incorrectly</strong>. The style with the handle bad-style was enqueued with dependencies that are not registered: nope. Please see <a href="https://developer.wordpress.org/advanced-administration/debug/debug-wordpress/">Debugging in WordPress</a> for more information. (This message was added in version 7.0.0.) in /var/www/src/wp-includes/functions.php on line 6131
  • PHP Notice: Function WP_Dependencies::all_deps was called <strong>incorrectly</strong>. The script with the handle bad-script was enqueued with dependencies that are not registered: nope. Please see <a href="https://developer.wordpress.org/advanced-administration/debug/debug-wordpress/">Debugging in WordPress</a> for more information. (This message was added in version 7.0.0.) in /var/www/src/wp-includes/functions.php on line 6131

The duplication of the notices is indeed not great. I think what I'll do is just add a private member variable to the classes to keep track of what has been flagged with _doing_it_wrong(). This will solve the problem of a static variable not being reset with tests.

What's also confusing is the functions being flagged are unrelated to the functions which may have been called incorrectly by the user. So I think I'll update these to use the WP_Scripts::add(), WP_Styles::add(), and WP_Script_Modules::register() methods which are actually flagged as being called incorrectly. This will make much more sense to a developer.

Also, I'll add quotes around the initial handle ID.

@westonruter commented on PR #10545:


9 days ago
#7

There, I think it is more developer-friendly now. When registering a script, style, and script module with missing dependencies, I now get just three notices:

  1. <b>Notice</b>: Function WP_Styles::add was called <strong>incorrectly</strong>. The style with the handle "bad-style" was enqueued with dependencies that are not registered: nope. Please see <a href="https://developer.wordpress.org/advanced-administration/debug/debug-wordpress/">Debugging in WordPress</a> for more information. (This message was added in version 7.0.0.) in <b>/var/www/src/wp-includes/functions.php</b> on line <b>6131</b><br />
  2. <b>Notice</b>: Function WP_Scripts::add was called <strong>incorrectly</strong>. The script with the handle "bad-script" was enqueued with dependencies that are not registered: nope. Please see <a href="https://developer.wordpress.org/advanced-administration/debug/debug-wordpress/">Debugging in WordPress</a> for more information. (This message was added in version 7.0.0.) in <b>/var/www/src/wp-includes/functions.php</b> on line <b>6131</b><br />
  3. <b>Notice</b>: Function WP_Script_Modules::register was called <strong>incorrectly</strong>. The script module "bad-module" was enqueued with dependencies that are not registered: nope. Please see <a href="https://developer.wordpress.org/advanced-administration/debug/debug-wordpress/">Debugging in WordPress</a> for more information. (This message was added in version 7.0.0.) in <b>/var/www/src/wp-includes/functions.php</b> on line <b>6131</b><br />

@westonruter commented on PR #10545:


9 days ago
#8

Notices as displayed in Query Monitor:

https://github.com/user-attachments/assets/64c6680c-9ed3-423d-bd09-5d4fac43d990

This is in addition to Query Monitor's built-in warnings for scripts and styles (but it doesn't currently warn for missing script module dependencies):

https://github.com/user-attachments/assets/9b6f6073-c35d-43be-8bd4-261d201c7c08
https://github.com/user-attachments/assets/3ee9c905-dccc-439c-ab7a-4595aa9bc654

#9 @westonruter
9 days ago

  • Owner set to westonruter
  • Resolution set to fixed
  • Status changed from new to closed

In 61323:

Script Loader: Emit notices when enqueueing a script, style, or script module with missing dependencies.

Developed in https://github.com/WordPress/wordpress-develop/pull/10545

Follow-up to [60999].

Props deepakprajapati, westonruter.
See #63486.
Fixes #64229.

#10 @westonruter
5 days ago

  • Keywords has-unit-tests added; needs-unit-tests removed
  • Milestone changed from 7.0 to 6.9.1
  • Resolution fixed deleted
  • Status changed from closed to reopened

Given the change in behavior in 6.9 where script modules with missing dependencies are no longer printed, it may be that sites will start breaking where previously they worked in 6.8. This was reported as a big in #64342. Given this, I think we should re-milestone the missing dependency notices for 6.9.1.

The docblocks added in [61323] will need to have their @since tags updated to 6.9.1.

Last edited 44 hours ago by westonruter (previous) (diff)

#11 @westonruter
44 hours ago

In 61357:

Script Loader: Re-target release for missing dependency notices from 7.0.0 to 6.9.1.

Follow-up to [61323], [60999].

See #64229.

#12 @westonruter
44 hours ago

  • Keywords fixed-major added

Commits [61323] and [61357] are ready for review for backporting to 6.9 branch for 6.9.1.

Note: See TracTickets for help on using tickets.