Cargar un script con una dependencia, es descargar la dependencia de otro script

9

Primero, soy consciente de que mi pregunta está ocurriendo en el contexto de mi trabajo con el complemento WooCommerce, lo que normalmente lo haría fuera de tema. Sin embargo, creo que mi pregunta se relaciona wp_enqueue_script, así que espero que todavía sea sobre el tema.

Entonces WooCommerce está registrando un script en el admin_enqueue_scriptsgancho. Este script requiere un montón de dependencias:

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 );

(está en cola específicamente en la página post.php y post-new.php para el tipo de publicación del producto un poco más adelante en el código)

En el complemento personalizado que estoy escribiendo para trabajar con WooCommerce, también estoy cargando un script en el mismo gancho.

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 );

Si pongo en cola el script de mi complemento y configuro el $in_footerparámetro de manera trueinexplicable, el script jQuery UI Datepicker no se carga (no está en absoluto en el código fuente) y la consola muestra los errores de script correspondientes.

Si cargo mi script en el encabezado, esto no es un problema. Si cargo mi script sin la wc-admin-meta-boxesdependencia, entonces eso también resuelve el problema

Entonces, lo que me pregunto es, ¿por qué cargar mi script en el pie de página afecta la carga del script core datepicker? (No estoy usando datepicker en mi secuencia de comandos). ¿O por qué no tener la secuencia de comandos Woo como una dependencia también afectaría la secuencia de comandos de datepicker? Me parece que el script datepicker debe cargarse, no importa como una dependencia del script metabox de Woo, pero esto no está sucediendo.

Según el comentario de Kaiser, creé el siguiente complemento de MU (ajustado a partir de los comentarios porque $GLOBALS['wp_scripts']es un objeto:

/* 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;'; 
}

Con solo WooCommerce 2.2.8 activo, el resultado dice:

La matriz de dependencias registrada: sí
Las dependencias cargadas en el pie de página: no
Las dependencias impresas en el DOM: no

Con WooCommerce 2.2.8 más mi nuevo complemento "ficticio", el resultado es el mismo (ya sea que mi script esté cargado en el pie de página o no):

La matriz de dependencias registrada: sí
Las dependencias cargadas en el pie de página: no
Las dependencias impresas en el DOM: no

Complemento ficticio

También según los comentarios, aquí hay un complemento ficticio para, con suerte, reproducir el problema para otros. Eliminé mi complemento existente hasta el final para cargar solo un script en las páginas de administración del tipo de publicación del producto. Todavía veo cargar datepicker cuando $in_footeres falso y no cargar cuando $in_footeres verdadero.

<?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
fuente
1
Sólo curioso. ¿Ha intentado establecer la prioridad de su acción en la cola de sus scripts, ya sea por encima o por debajo de la de WooCommerce al hacer cola en el pie de página? Me he encontrado con instancias con complementos que usan dependencias idénticas y anula el registro de cada instancia, y por alguna razón esto lo solucionó. (No lo pensé mucho). Sin embargo, nunca hizo una diferencia entre hacer cola en el encabezado vs. pie de página.
BODA82
Me pregunto qué pasó con todos los otros comentarios. De todos modos, @ BODA82, no, no lo había intentado. Pero agregar una prioridad hace que el selector de fechas se cargue correctamente incluso cuando $in_footeres cierto en mi propio script.
helgatheviking
1
Esto me parece un error en WP: no he seguido la lógica, pero si miras la función do_itemsen "wp-includes / class.wp-dependencies.php", en las líneas 122-125, el código simplemente se desarma el elemento en la lista de tareas pendientes si tiene do_iteméxito o no . Si cambia esas líneas a, if ( $this->do_item( $handle, $group ) ) { $this->done[] = $handle; unset( $this->to_do[$key] ); }entonces el error desaparece ...
bonger
2
Este es un error de WP: consulte el trác # 25247 . Propuse un parche (gitlost c'est moi).
Bonger
@bonger Gracias por la respuesta definitiva. Si desea mover su comentario a una respuesta, lo acepto. Aparentemente, las dependencias son un infierno.
helgatheviking

Respuestas:

2

Actualmente puede forzar una carga para las bibliotecas usando wp_enqueue_script (), de esta manera:

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

Sé que debe cargarse automáticamente, pero funciona de esa manera.

Leo Caseiro
fuente