Memuat skrip dengan dependensi, sedang menurunkan ketergantungan skrip lain

9

Pertama, saya sadar bahwa pertanyaan saya terjadi dalam konteks pekerjaan saya dengan plugin WooCommerce, yang biasanya membuatnya di luar topik. Namun, saya pikir pertanyaan saya terkait wp_enqueue_script, jadi semoga masih pada topik.

Jadi WooCommerce mendaftarkan skrip di admin_enqueue_scriptshook. Script ini membutuhkan banyak dependensi:

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

(diuraikan secara khusus pada halaman post.php dan post-new.php untuk jenis postingan produk sedikit kemudian dalam kode)

Dalam plugin khusus yang saya tulis untuk berfungsi dengan WooCommerce saya juga memuat skrip pada hook yang sama.

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

Jika saya enqueue skrip plugin saya dan mengatur $in_footerparameter untuk truekemudian dijelaskan, skrip Datepicker jQuery UI tidak dimuat (tidak dalam kode sumber sama sekali) dan konsol menunjukkan kesalahan skrip yang sesuai.

Jika saya memuat skrip saya di header, ini bukan masalah. Jika saya memuat skrip saya tanpa wc-admin-meta-boxesketergantungan, maka itu juga menyelesaikan masalah

Jadi yang saya ingin tanyakan adalah, mengapa memuat skrip saya di footer mempengaruhi pemuatan skrip datepicker inti? (Saya sama sekali tidak menggunakan datepicker dalam skrip saya.) Atau mengapa tidak memiliki skrip Woo sebagai ketergantungan juga akan mempengaruhi skrip datepicker? Sepertinya saya bahwa skrip datepicker harus dimuat tidak peduli apa pun sebagai ketergantungan skrip metabox Woo, tetapi ini tidak terjadi.

Per komentar Kaiser, saya membuat plugin MU berikut (disesuaikan dari komentar karena $GLOBALS['wp_scripts']merupakan objek:

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

Dengan hanya WooCommerce 2.2.8 yang aktif, hasilnya berbunyi:

Ketergantungan Dependensi terdaftar: yep
Ketergantungan yang dimuat dalam footer: nggak
Ketergantungan yang dicetak ke DOM: nggak

Dengan WooCommerce 2.2.8 plus plugin "dummy" baru saya, hasilnya terbaca sama (baik skrip saya dimuat di footer atau tidak):

Ketergantungan Dependensi terdaftar: yep
Ketergantungan yang dimuat dalam footer: nggak
Ketergantungan yang dicetak ke DOM: nggak

Plugin Dummy

Juga per komentar, inilah plugin dummy untuk mudah-mudahan mereproduksi masalah untuk orang lain. Saya menanggalkan plugin yang ada hingga hanya memuat skrip pada halaman admin jenis posting produk. Saya masih melihat beban saat data $in_footersalah dan tidak memuat kapan $in_footerbenar.

<?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
sumber
1
Hanya penasaran. Sudahkah Anda mencoba untuk menetapkan prioritas tindakan Anda mengantri skrip Anda baik di atas atau di bawah itu dari WooCommerce ketika mengantri di footer? Saya telah mengalami beberapa kasus dengan plugin menggunakan dependensi yang identik dan membatalkan pendaftaran setiap contohnya, dan untuk beberapa alasan ini memperbaikinya. (Saya tidak terlalu memikirkannya). Namun, tidak pernah membuat perbedaan antara antrian di header vs footer.
BODA82
Saya ingin tahu apa yang terjadi pada semua komentar lainnya? Bagaimanapun, @ BODA82, tidak, saya belum mencobanya. Tetapi menambahkan prioritas tidak membuat pemuatan datepicker benar bahkan ketika $in_footerbenar pada skrip saya sendiri.
Helgatheviking
1
Ini terlihat seperti bug di WP untuk saya - saya belum mengikuti logika tetapi jika Anda melihat fungsi do_itemsdi "wp-include / class.wp-dependencies.php", pada baris 122-125, kode tersebut hanya tidak disetel item dalam daftar to_do do_itemberhasil atau tidak . Jika Anda mengubah baris itu if ( $this->do_item( $handle, $group ) ) { $this->done[] = $handle; unset( $this->to_do[$key] ); }maka bug hilang ...
bonger
2
Ini adalah bug WP - lihat trac # 25247 . Saya mengusulkan tambalan (gitlost c'est moi).
bonger
@bonger Terima kasih atas jawaban yang pasti. Jika Anda ingin memindahkan komentar Anda ke jawaban, saya akan menerimanya. Rupanya, ketergantungan adalah neraka.
Helgatheviking

Jawaban:

2

Saat ini Anda dapat memaksa pemuatan untuk Perpustakaan menggunakan wp_enqueue_script (), seperti:

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

Saya tahu itu harus memuat secara otomatis, tetapi berfungsi seperti itu.

Leo Caseiro
sumber