Make WordPress Core

Changeset 61550 for branches/6.9


Ignore:
Timestamp:
01/28/2026 09:28:06 PM (7 months ago)
Author:
jorbin
Message:

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

First Developed in https://github.com/WordPress/wordpress-develop/pull/10545. Backport developed in https://github.com/WordPress/wordpress-develop/pull/10789.

Follow-up to [60999].

Reviewed by jorbin, wildworks.
Merges [61323], [61357], and [61542].

Props deepakprajapati, westonruter, mukeshpanchal27, jorbin, wildworks.
See #63486.
Fixes #64229.

Location:
branches/6.9
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • branches/6.9

  • branches/6.9/src/wp-includes/class-wp-dependencies.php

    r60948 r61550  
    104104         */
    105105        private $queued_before_register = array();
     106
     107        /**
     108         * List of handles for dependencies encountered which themselves have missing dependencies.
     109         *
     110         * A dependency handle is added to this list when it is discovered to have missing dependencies. At this time, a
     111         * warning is emitted with {@see _doing_it_wrong()}. The handle is then added to this list, so that duplicate
     112         * warnings don't occur.
     113         *
     114         * @since 6.9.1
     115         * @var string[]
     116         */
     117        private $dependencies_with_missing_dependencies = array();
    106118
    107119        /**
     
    200212                        }
    201213
    202                         $keep_going = true;
     214                        $keep_going           = true;
     215                        $missing_dependencies = array();
     216                        if ( isset( $this->registered[ $handle ] ) && count( $this->registered[ $handle ]->deps ) > 0 ) {
     217                                $missing_dependencies = array_diff( $this->registered[ $handle ]->deps, array_keys( $this->registered ) );
     218                        }
    203219                        if ( ! isset( $this->registered[ $handle ] ) ) {
    204220                                $keep_going = false; // Item doesn't exist.
    205                         } elseif ( $this->registered[ $handle ]->deps && array_diff( $this->registered[ $handle ]->deps, array_keys( $this->registered ) ) ) {
     221                        } elseif ( count( $missing_dependencies ) > 0 ) {
     222                                if ( ! in_array( $handle, $this->dependencies_with_missing_dependencies, true ) ) {
     223                                        _doing_it_wrong(
     224                                                get_class( $this ) . '::add',
     225                                                $this->get_dependency_warning_message( $handle, $missing_dependencies ),
     226                                                '6.9.1'
     227                                        );
     228                                        $this->dependencies_with_missing_dependencies[] = $handle;
     229                                }
    206230                                $keep_going = false; // Item requires dependencies that don't exist.
    207231                        } elseif ( $this->registered[ $handle ]->deps && ! $this->all_deps( $this->registered[ $handle ]->deps, true, $new_group ) ) {
     
    536560                return 'W/"' . md5( $etag ) . '"';
    537561        }
     562
     563        /**
     564         * Gets a dependency warning message for a handle.
     565         *
     566         * @since 6.9.1
     567         *
     568         * @param string   $handle                     Handle with missing dependencies.
     569         * @param string[] $missing_dependency_handles Missing dependency handles.
     570         * @return string Formatted, localized warning message.
     571         */
     572        protected function get_dependency_warning_message( $handle, $missing_dependency_handles ) {
     573                return sprintf(
     574                        /* translators: 1: Handle, 2: List of missing dependency handles. */
     575                        __( 'The handle "%1$s" was enqueued with dependencies that are not registered: %2$s.' ),
     576                        $handle,
     577                        implode( wp_get_list_item_separator(), $missing_dependency_handles )
     578                );
     579        }
    538580}
  • branches/6.9/src/wp-includes/class-wp-script-modules.php

    r61506 r61550  
    7070                'high',
    7171        );
     72
     73        /**
     74         * List of IDs for script modules encountered which have missing dependencies.
     75         *
     76         * An ID is added to this list when it is discovered to have missing dependencies. At this time, a warning is
     77         * emitted with {@see _doing_it_wrong()}. The ID is then added to this list, so that duplicate warnings don't occur.
     78         *
     79         * @since 6.9.1
     80         * @var string[]
     81         */
     82        private $modules_with_missing_dependencies = array();
    7283
    7384        /**
     
    723734
    724735                // If the item requires dependencies that do not exist, fail.
    725                 if ( count( array_diff( $dependency_ids, array_keys( $this->registered ) ) ) > 0 ) {
     736                $missing_dependencies = array_diff( $dependency_ids, array_keys( $this->registered ) );
     737                if ( count( $missing_dependencies ) > 0 ) {
     738                        if ( ! in_array( $id, $this->modules_with_missing_dependencies, true ) ) {
     739                                _doing_it_wrong(
     740                                        get_class( $this ) . '::register',
     741                                        sprintf(
     742                                                /* translators: 1: Script module ID, 2: List of missing dependency IDs. */
     743                                                __( 'The script module with the ID "%1$s" was enqueued with dependencies that are not registered: %2$s.' ),
     744                                                $id,
     745                                                implode( wp_get_list_item_separator(), $missing_dependencies )
     746                                        ),
     747                                        '6.9.1'
     748                                );
     749                                $this->modules_with_missing_dependencies[] = $id;
     750                        }
     751
    726752                        return false;
    727753                }
  • branches/6.9/src/wp-includes/class-wp-scripts.php

    r61506 r61550  
    11651165                $this->ext_handles    = '';
    11661166        }
     1167
     1168        /**
     1169         * Gets a script-specific dependency warning message.
     1170         *
     1171         * @since 6.9.1
     1172         *
     1173         * @param string   $handle                     Script handle with missing dependencies.
     1174         * @param string[] $missing_dependency_handles Missing dependency handles.
     1175         * @return string Formatted, localized warning message.
     1176         */
     1177        protected function get_dependency_warning_message( $handle, $missing_dependency_handles ) {
     1178                return sprintf(
     1179                        /* translators: 1: Script handle, 2: List of missing dependency handles. */
     1180                        __( 'The script with the handle "%1$s" was enqueued with dependencies that are not registered: %2$s.' ),
     1181                        $handle,
     1182                        implode( wp_get_list_item_separator(), $missing_dependency_handles )
     1183                );
     1184        }
    11671185}
  • branches/6.9/src/wp-includes/class-wp-styles.php

    r61084 r61550  
    494494                $this->print_html     = '';
    495495        }
     496
     497        /**
     498         * Gets a style-specific dependency warning message.
     499         *
     500         * @since 6.9.1
     501         *
     502         * @param string   $handle                     Style handle with missing dependencies.
     503         * @param string[] $missing_dependency_handles Missing dependency handles.
     504         * @return string Formatted, localized warning message.
     505         */
     506        protected function get_dependency_warning_message( $handle, $missing_dependency_handles ) {
     507                return sprintf(
     508                        /* translators: 1: Style handle, 2: List of missing dependency handles. */
     509                        __( 'The style with the handle "%1$s" was enqueued with dependencies that are not registered: %2$s.' ),
     510                        $handle,
     511                        implode( wp_get_list_item_separator(), $missing_dependency_handles )
     512                );
     513        }
    496514}
  • branches/6.9/tests/phpunit/tests/dependencies/scripts.php

    r61536 r61550  
    41334133                return $processor->get_updated_html();
    41344134        }
     4135
     4136        /**
     4137         * Tests that WP_Scripts emits a _doing_it_wrong() notice for missing dependencies.
     4138         *
     4139         * @ticket 64229
     4140         * @covers WP_Dependencies::all_deps
     4141         */
     4142        public function test_wp_scripts_doing_it_wrong_for_missing_dependencies() {
     4143                $expected_incorrect_usage = 'WP_Scripts::add';
     4144                $this->setExpectedIncorrectUsage( $expected_incorrect_usage );
     4145
     4146                wp_register_script( 'registered-dep', '/registered-dep.js' );
     4147                wp_enqueue_script( 'main', '/main.js', array( 'registered-dep', 'missing-dep' ) );
     4148
     4149                $markup = get_echo( 'wp_print_scripts' );
     4150                $this->assertStringNotContainsString( 'main.js', $markup, 'Expected script to be absent.' );
     4151
     4152                $this->assertArrayHasKey(
     4153                        $expected_incorrect_usage,
     4154                        $this->caught_doing_it_wrong,
     4155                        "Expected $expected_incorrect_usage to trigger a _doing_it_wrong() notice for missing dependency."
     4156                );
     4157
     4158                $this->assertStringContainsString(
     4159                        'The script with the handle "main" was enqueued with dependencies that are not registered: missing-dep',
     4160                        $this->caught_doing_it_wrong[ $expected_incorrect_usage ],
     4161                        'Expected _doing_it_wrong() notice to indicate missing dependencies for enqueued script.'
     4162                );
     4163        }
    41354164}
  • branches/6.9/tests/phpunit/tests/dependencies/styles.php

    r61536 r61550  
    816816                $this->assertEqualHTML( $expected, $printed );
    817817        }
     818
     819        /**
     820         * Tests that WP_Styles emits a _doing_it_wrong() notice for missing dependencies.
     821         *
     822         * @ticket 64229
     823         * @covers WP_Dependencies::all_deps
     824         */
     825        public function test_wp_style_doing_it_wrong_for_missing_dependencies() {
     826                $expected_incorrect_usage = 'WP_Styles::add';
     827                $this->setExpectedIncorrectUsage( $expected_incorrect_usage );
     828
     829                wp_enqueue_style(
     830                        'main-style',
     831                        '/main-style.css',
     832                        array( 'missing-style-dep' )
     833                );
     834
     835                $markup = get_echo( 'wp_print_styles' );
     836                $this->assertStringNotContainsString( 'main-style.css', $markup, 'Expected style to be absent.' );
     837
     838                $this->assertArrayHasKey(
     839                        $expected_incorrect_usage,
     840                        $this->caught_doing_it_wrong,
     841                        "Expected $expected_incorrect_usage to trigger a _doing_it_wrong() notice for missing dependency."
     842                );
     843
     844                $this->assertStringContainsString(
     845                        'The style with the handle "main-style" was enqueued with dependencies that are not registered: missing-style-dep',
     846                        $this->caught_doing_it_wrong[ $expected_incorrect_usage ],
     847                        'Expected _doing_it_wrong() notice to indicate missing dependencies for enqueued styles.'
     848                );
     849        }
    818850}
  • branches/6.9/tests/phpunit/tests/script-modules/wpScriptModules.php

    r61536 r61550  
    21072107                );
    21082108
    2109                 $deregister( array( 'b', 'c ' ) );
     2109                $deregister( array( 'b', 'c' ) );
    21102110
    21112111                // Test that registered dependency in footer doesn't place dependant in footer.
     
    23562356                );
    23572357        }
     2358
     2359        /**
     2360         * Tests that a missing script module dependency triggers a _doing_it_wrong() notice.
     2361         *
     2362         * @ticket 64229
     2363         * @covers WP_Script_Modules::sort_item_dependencies
     2364         */
     2365        public function test_missing_script_module_dependency_triggers_incorrect_usage() {
     2366                $expected_incorrect_usage = 'WP_Script_Modules::register';
     2367                $this->setExpectedIncorrectUsage( $expected_incorrect_usage );
     2368
     2369                $this->script_modules->enqueue( 'main-module', '/main-module.js', array( 'missing-mod-dep' ) );
     2370
     2371                $markup = get_echo( array( $this->script_modules, 'print_enqueued_script_modules' ) );
     2372                $this->assertStringNotContainsString( 'main-module.js', $markup, 'Expected script module to be absent.' );
     2373
     2374                $this->assertArrayHasKey(
     2375                        $expected_incorrect_usage,
     2376                        $this->caught_doing_it_wrong,
     2377                        'Expected WP_Script_Modules::register to be reported via doing_it_wrong().'
     2378                );
     2379
     2380                // Assert the message mentions the missing dependency handle.
     2381                $this->assertStringContainsString(
     2382                        'The script module with the ID "main-module" was enqueued with dependencies that are not registered: missing-mod-dep',
     2383                        $this->caught_doing_it_wrong[ $expected_incorrect_usage ]
     2384                );
     2385        }
    23582386}
Note: See TracChangeset for help on using the changeset viewer.