Carregar um script com uma dependência está descarregando a dependência de outro script

9

Primeiro, estou ciente de que minha pergunta está acontecendo no contexto do meu trabalho com o plug-in WooCommerce, o que normalmente o tornaria fora de tópico. No entanto, acho que minha pergunta está relacionada wp_enqueue_script, por isso espero que ainda esteja no tópico.

Então o WooCommerce está registrando um script no admin_enqueue_scriptsgancho. Este script requer várias dependências:

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

(ele está enfileirado especificamente na página post.php e post-new.php para o tipo de publicação do produto um pouco mais tarde no código)

No plug-in personalizado que estou escrevendo para trabalhar com o WooCommerce, também estou carregando um script no mesmo 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 );

Se enfileirar o script do meu plug-in e definir o $in_footerparâmetro para trueinexplicavelmente, o script jQuery UI Datepicker não será carregado (não está no código-fonte) e o console mostrará os erros de script correspondentes.

Se eu carregar o meu script no cabeçalho, isso não será um problema. Se eu carregar meu script sem a wc-admin-meta-boxesdependência, isso também resolverá o problema

Então, o que eu quero saber é: por que carregar meu script no rodapé afeta o carregamento do script principal do datepicker? (Não estou usando o datepicker no meu script.) Ou por que não ter o script Woo como uma dependência também afetaria o script datepicker? Parece-me que o script datepicker deve ser carregado, independentemente da dependência do script Woo metabox, mas isso não está acontecendo.

Pelo comentário de Kaiser, criei o seguinte plugin MU (ajustado a partir dos comentários porque $GLOBALS['wp_scripts']é um 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;'; 
}

Com apenas o WooCommerce 2.2.8 ativo, o resultado é:

A matriz de dependências registrada: sim
As dependências carregadas no rodapé: não
As dependências impressas no DOM: não

Com o WooCommerce 2.2.8 mais meu novo plugin "fictício", o resultado é o mesmo (se meu script está carregado no rodapé ou não):

A matriz de dependências registrada: sim
As dependências carregadas no rodapé: não
As dependências impressas no DOM: não

Dummy Plugin

Também pelos comentários, aqui está um plugin fictício para reproduzir o problema para outras pessoas. Tirei todo o meu plugin existente para carregar apenas um script nas páginas de administração do tipo de postagem do produto. Ainda estou vendo o carregamento do datepicker quando $in_footeré falso e não é carregado quando $in_footeré verdadeiro.

<?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
fonte
11
Apenas curioso. Você tentou definir a prioridade de sua ação na fila de seus scripts acima ou abaixo da do WooCommerce ao fazer fila no rodapé? Corri para instâncias com plug-ins usando dependências idênticas e ele cancelou o registro de todas as instâncias, e por algum motivo isso foi corrigido. (Não pensei muito nisso). Mas nunca fez diferença entre enfileirar no cabeçalho x rodapé.
BODA82
Eu me pergunto o que aconteceu com todos os outros comentários? Enfim, @ BODA82, não, eu não tinha tentado isso. Mas acrescentando uma prioridade faz manter datepicker carga corretamente, mesmo quando $in_footeré verdade no meu próprio script.
helgatheviking
11
Isso parece um bug no WP para mim - eu não segui a lógica, mas se você observar a função do_itemsem "wp-includes / class.wp-dependencies.php", nas linhas 122-125, o código simplesmente desativa o item na lista to_do, com ou sem do_itemêxito. Se você alterar essas linhas para if ( $this->do_item( $handle, $group ) ) { $this->done[] = $handle; unset( $this->to_do[$key] ); }, em seguida, o erro vai embora ...
Bonger
2
Este é um bug do WP - veja o trac # 25247 . Eu propus um patch (gitlost c'est moi).
Bonger
@ bonger Obrigado pela resposta definitiva. Se você quisesse mudar seu comentário para uma resposta, eu o aceitaria. Aparentemente, as dependências são um inferno.
helgatheviking

Respostas:

2

Atualmente, você pode forçar um carregamento para as bibliotecas usando wp_enqueue_script (), assim:

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

Eu sei que ele deve carregar automaticamente, mas funciona dessa maneira.

Leo Caseiro
fonte