Ładowanie skryptu z zależnością powoduje rozładowanie zależności innego skryptu

9

Po pierwsze, zdaję sobie sprawę, że moje pytanie dzieje się w kontekście mojej pracy z wtyczką WooCommerce, co normalnie sprawiłoby, że byłoby to nie na temat. Wydaje mi się jednak, że moje pytanie dotyczy wp_enqueue_script, więc mam nadzieję, że wciąż dotyczy tematu.

Więc WooCommerce rejestruje skrypt na admin_enqueue_scriptshaku. Ten skrypt wymaga szeregu zależności:

wp_register_script( 'wc-admin-meta-boxes', WC()->plugin_url() . '/assets/js/admin/meta-boxes' . $suffix . '.js', array( 'jquery', 'jquery-ui-datepicker', 'jquery-ui-sortable', 'accounting', 'round', 'ajax-chosen', 'chosen', 'plupload-all' ), WC_VERSION );

(jest umieszczony w kolejce specjalnie na stronie post.php i post-new.php dla typu postu produktu nieco później w kodzie)

W niestandardowej wtyczce, którą piszę do pracy z WooCommerce, ładuję również skrypt na tym samym haku.

wp_enqueue_script( 'My_Plugin_Metabox', My_Plugin_Class()->plugin_url() . '/assets/js/mnm-write-panel.js', array( 'jquery', 'wc-admin-meta-boxes'), My_Plugin_Class()->version, true );

Jeśli kolejkuję skrypt wtyczki i ustawię $in_footerparametr na trueniewytłumaczalny, skrypt Datepicker jQuery UI nie zostanie załadowany (wcale nie w kodzie źródłowym), a konsola wyświetli odpowiednie błędy skryptu.

Jeśli załaduję mój skrypt do nagłówka, nie stanowi to problemu. Jeśli załaduję skrypt bez wc-admin-meta-boxeszależności, rozwiąże to również problem

Zastanawiam się więc, dlaczego ładowanie skryptu w stopce wpływa na ładowanie podstawowego skryptu datepicker? (W ogóle nie używam datepicker w swoim skrypcie.) Albo dlaczego nie mieć skryptu Woo jako zależności, miałoby to również wpływ na skrypt datepicker? Wydaje mi się, że skrypt datepicker powinien zostać załadowany bez względu na zależność od skryptu metabox Woo, ale tak się nie dzieje.

Na podstawie komentarza Kaiser stworzyłem następującą wtyczkę MU (dostosowaną z komentarzy, ponieważ $GLOBALS['wp_scripts']jest obiektem:

/* Plugin Name: Dump jQUI Dp */ 

add_action( 'shutdown', 'so_dump_query_ui_dependencies' );
function so_dump_query_ui_dependencies() {  
    echo 'Does jQuery UI DatePicker script exist per default in&hellip;?<br>';  
    $s = 'jquery-ui-datepicker';    
    printf( 'The registered Dependencies Array: %s', isset( $GLOBALS['wp_scripts']->registered[ $s ] ) ? 'yep ' : 'nope ' );    
    printf( 'The Dependencies loaded in the footer: %s', isset( $GLOBALS['wp_scripts']->in_footer[ $s ] ) ? 'yep ' : 'nope ' );     
    printf( 'The Dependencies printed to the DOM: %s', isset( $GLOBALS['wp_scripts']->done[ $s ] ) ? 'yep ' : 'nope ' );    
    echo 'All nope? Well, then&hellip;'; 
}

Przy aktywnym tylko WooCommerce 2.2.8 wynik brzmi:

Zarejestrowana tablica zależności: yep
Zależności załadowane w stopce: nope
Zależności wydrukowane do DOM: nope

W przypadku WooCommerce 2.2.8 i mojej nowej „sztucznej” wtyczki wynik brzmi tak samo (niezależnie od tego, czy mój skrypt jest załadowany w stopce, czy nie):

Zarejestrowana tablica zależności: yep
Zależności załadowane w stopce: nope
Zależności wydrukowane do DOM: nope

Atrapa wtyczki

Również w komentarzach oto fałszywa wtyczka, która, mam nadzieję, odtworzy problem dla innych. Rozebrałem moje istniejące wtyczki całą drogę w dół do tylko załadować skryptu na stronach typu administratora pocztowych produkt. Nadal widzę ładowanie datepicker, gdy $in_footerjest fałszem, a nie ładowanie, gdy $in_footerjest prawdą.

<?php
/*
Plugin Name: WooCommerce Dummy Plugin
Plugin URI: http://wordpress.stackexchange.com/q/168688/6477
Author: helgatheviking
Description: Enqueue a script, miraculously dequeue datepicker
*/


/**
 * The Main My_Dummy_Plugin class
 **/
if ( ! class_exists( 'My_Dummy_Plugin' ) ) :

class My_Dummy_Plugin {

    /**
     * @var My_Dummy_Plugin - the single instance of the class
     */
    protected static $_instance = null;

    /**
     * variables
     */
    public $version = '1.0.0';

    /**
     * Main My_Dummy_Plugin instance.
     *
     * Ensures only one instance of My_Dummy_Plugin is loaded or can be loaded
     *
     * @static
     * @return My_Dummy_Plugin - Main instance
     */
    public static function instance() {
        if ( is_null( self::$_instance ) ) {
            self::$_instance = new self();
        }
        return self::$_instance;
    }


    /**
     * Cloning is forbidden.
     */
    public function __clone() {
        _doing_it_wrong( __FUNCTION__, __( 'Cheatin&#8217; huh?' ) );
    }


    /**
     * Unserializing instances of this class is forbidden.
     */
    public function __wakeup() {
        _doing_it_wrong( __FUNCTION__, __( 'Cheatin&#8217; huh?' ) );
    }


    /**
     * My_Dummy_Plugin Constructor
     *
     * @access  public
     * @return  My_Dummy_Plugin
     */
    public function __construct() {

        add_action( 'admin_enqueue_scripts', array( $this, 'admin_scripts' ) );

    }


    /*-----------------------------------------------------------------------------------*/
    /* Helper Functions */
    /*-----------------------------------------------------------------------------------*/

    /**
     * Get the plugin url.
     *
     * @return string
     */
    public function plugin_url() {
        return untrailingslashit( plugins_url( '/', __FILE__ ) );
    }


    /**
     * Get the plugin path.
     *
     * @return string
     */
    public function plugin_path() {
        return untrailingslashit( plugin_dir_path( __FILE__ ) );
    }

    /*-----------------------------------------------------------------------------------*/
    /* Load scripts */
    /*-----------------------------------------------------------------------------------*/

    public function admin_scripts() {

        // Get admin screen id
        $screen = get_current_screen();

        // Product post type page only
        if ( in_array( $screen->id, array( 'product' ) ) ) {

            wp_enqueue_script( 'My_Dummy_Plugin_Metabox', $this->plugin_url() . '/assets/js/metabox.js', array( 'jquery', 'wc-admin-meta-boxes'), $this->version, true );

        }

    }

} //end class: do not remove or there will be no more guacamole for you

endif; // end class_exists check


/**
 * Returns the main instance of My_Dummy_Plugin
 *
 * @return WooCommerce
 */
function My_Dummy_Plugin() {
    return My_Dummy_Plugin::instance();
}

// Launch the whole plugin
My_Dummy_Plugin();
helgatheviking
źródło
1
Po prostu ciekawy. Czy próbowałeś ustawić priorytet akcji w kolejce skryptów albo powyżej, albo poniżej priorytetu WooCommerce, kiedy ustawiasz się w kolejce w stopce? Natknąłem się na instancje z wtyczkami korzystającymi z identycznych zależności i to wyrejestrowało każdą instancję, i z jakiegoś powodu to naprawiło. (Nie zastanawiałem się długo). Jednak nigdy nie zrobiłem różnicy między kolejkowaniem w nagłówku a stopką.
BODA82,
Zastanawiam się, co stało się z wszystkimi innymi komentarzami? W każdym razie, @ BODA82, nie, nie próbowałem tego. Ale dodanie priorytetu powoduje prawidłowe ładowanie datepicker, nawet jeśli $in_footerjest to prawdą w moim skrypcie.
helgatheviking
1
Dla mnie wygląda to na błąd w WP - nie podążałem za logiką, ale jeśli spojrzysz na funkcję do_itemsw „wp-include / class.wp-dependencies.php”, w wierszach 122-125, kod po prostu się wyłącza pozycja na liście to_do, czy się do_itempowiedzie. Jeśli zmienisz te linie na, if ( $this->do_item( $handle, $group ) ) { $this->done[] = $handle; unset( $this->to_do[$key] ); }wtedy błąd zniknie ...
bonger
2
To jest błąd WP - patrz trac # 25247 . Zaproponowałem łatkę (gitlost c'est moi).
bonger
@bonger Dzięki za ostateczną odpowiedź. Jeśli chcesz przenieść komentarz do odpowiedzi, zaakceptuję go. Najwyraźniej zależności są piekłem.
helgatheviking

Odpowiedzi:

2

Obecnie możesz wymusić ładowanie bibliotek za pomocą wp_enqueue_script (), w następujący sposób:

wp_enqueue_script('jquery');
wp_enqueue_script('jquery-ui');

Wiem, że powinien się ładować automatycznie, ale działa w ten sposób.

Leo Caseiro
źródło