WordPress

wp enqueue script – Ładowanie najnowszego pliku modułu zależności javascript w functions.php

  • 14 lutego, 2023
  • 6 min read
wp enqueue script – Ładowanie najnowszego pliku modułu zależności javascript w functions.php


Problem

Importuj oświadczenie, takie jak:

import { export1 } from "./module-name.js";

jest nazywany statyczny import deklaracja.

Dynamiczny ciąg zapytania (aby wymusić załadowanie najnowszego pliku) nie może być używany jako statyczny import deklaracje. Aby rozwiązać ten problem, musisz wybrać jedną z następujących czterech opcji:

  1. Usunąć export I import instrukcje ze wszystkich plików JavaScript i umieszcza je w kolejce jako niemodułowy JavaScript.

  2. Nie ustawiaj się w kolejce ads.js w WordPress podawaj tylko numer wersji ads.js plik jako zmienną globalną JavaScript z wp_add_inline_script() funkcję na stronę i dynamicznie importować ads.js jako moduł z banners.js I ads-search.js.

  3. Ustaw w kolejce ads.js jako moduł przekaż numer wersji ads.js plik jako zmienną globalną JavaScript z wp_add_inline_script() funkcja na stronie, kolejkuj banners.js I ads-search.js jako niemodułowy JavaScript (z ads.js w tablicy zależności) i dynamicznie importować ads.js jako moduł z banners.js I ads-search.js. Różni się to nieco od opcji 2 i może przynieść pewne korzyści w zależności od implementacji.

  4. Użyj pakietu, takiego jak Rollup lub Webpack, i zbuduj pojedynczy zminimalizowany skrypt za pomocą obserwatora plików i umieść skompilowany zminimalizowany plik JavaScript w WordPress jako niemodułowy plik JavaScript. Poleciłbym tę metodę, ale nie wyjaśniałbym jej tutaj, ponieważ wykracza to poza zakres tego pytania.

Opcja-1: Spraw, aby wszystkie pliki JS nie były modułami

Po prostu usuń export I import instrukcje ze wszystkich plików JavaScript, jak poniżej:

// in ads.js
// removed the export declaration
async function selectADS(adNumber, element, adsArray) {
  let usedNum = [];
  let i = 0;
  while (1) {
    var randomNum = Math.floor(Math.random() * adsArray.length);

    if (!usedNum.includes(randomNum)) {
      let link = document.createElement("a");
      link.setAttribute("href", adsArray[randomNum].link);
      link.setAttribute("target", "_blank");

      let ad = document.createElement("img");
      ad.setAttribute("alt", adsArray[randomNum].alt);
      ad.setAttribute("src", adsArray[randomNum].src);

      element.appendChild(link);
      link.appendChild(ad);

      usedNum.push(randomNum);
      i++;
      if (i == adNumber) break;
    }
  }
}

// in banners.js
// call selectADS function normally, no import declaration
selectADS();

Następnie na końcu WordPress umieść je w kolejce my_custom_theme_scripts() tak jak napisałeś w pytaniu

Warto przeczytać!  Jak utworzyć post Roundup w WordPress (łatwy sposób)

Opcja-2: pas ads.js wersja do JS i dynamicznie importuj ads.js

Jeśli z jakiegoś powodu musisz zachować plik export deklaracja w ads.jsi nadal chcesz zaimportować najnowszy plik w banners.js I ads-search.jsbędziesz musiał wprowadzić pewne zmiany w kodzie kolejkowania WordPress oraz w kodzie JavaScript banners.js I ads-search.js.

Na przykład twój my_custom_theme_scripts() funkcja może wyglądać tak:

function my_custom_theme_scripts() {
    $ads_version = filemtime( get_stylesheet_directory() . '/js/ads.js' );
    $banners_version = filemtime( get_stylesheet_directory() . '/js/banners.js' );

    wp_enqueue_script(
        'banners',
        get_stylesheet_directory_uri() . '/js/banners.js',
        array(),
        $banners_version,
        true
    );
    wp_add_inline_script(
        'banners',
        'const My_Custom_Ads_Version = "' . $ads_version . '";',
        'before'
    );
}

W tym przypadku, ads.js plik może być taki jak poprzednio z export oświadczenie i banners.js plik może dynamicznie import to jak poniżej:

(async () => {  
    if( typeof My_Custom_Ads_Version !== 'undefined' ) {
        const adsModule = await import( `./ads.js?ver=${My_Custom_Ads_Version}` );
        const selectADS = adsModule.selectADS;
        selectADS();
    }
})();

Będziesz musiał wprowadzić podobne zmiany w ads-search.js. Po tym twój kod będzie działał.

Pamiętaj, w tym przypadku export deklaracje mogą być takie jak poprzednio (w ads.js), ale instrukcje importu w banners.js I ads-search.js należy zmienić ze statycznego import Deklaracja dynamiczna import instrukcje, jak pokazano w powyższym kodzie.

Warto przeczytać!  Ładowanie skryptu z zależnością powoduje zwolnienie zależności innego skryptu

Opcja-3: Ustaw w kolejce ads.js jako moduł, zalicz ads.js wersja do JS i dynamicznie importuj ads.js

Ta opcja jest bardzo podobna do Opcja 2 powyżej. Jednak opcja-2 importuje ads.js w czasie wykonywania. Więc jeśli implementacja chce opóźnić wykonanie ads.js moduł obiektów, ale nadal chce załadować ads.js moduł z ładowaniem strony, to ta implementacja będzie preferowana.

Aby to zrobić, musisz najpierw podłączyć się do script_loader_tag filtr, aby WordPress dodał type="module" W <script> etykietka.

Poniżej znajduje się przykładowy kod WordPress, który go implementuje:

add_filter( 'script_loader_tag', 'my_custom_module_support', PHP_INT_MAX, 2 );
function my_custom_module_support( $tag, $handle ) {
    if( strpos( $handle, 'my_custom_module_' ) === 0 ) {
        if( current_theme_supports( 'html5', 'script' ) ) { 
            return substr_replace( $tag, '<script type="module"', strpos( $tag, '<script' ), 7 );
        }
        else {
            return substr_replace( $tag, 'module', strpos( $tag, 'text/javascript' ), 15 );
        }
    }

    return $tag;
}
function my_custom_theme_scripts() {
    $ads_version = filemtime( get_stylesheet_directory() . '/js/ads.js' );
    $banners_version = filemtime( get_stylesheet_directory() . '/js/banners.js' );

    // we are loading ads.js as a module.
    // my_custom_module_support() function checks any handle
    // that begins with "my_custom_module_" and adds type="modle"
    // to print it as a ES6 module script 
    wp_enqueue_script(
        'my_custom_module_ads',
        get_stylesheet_directory_uri() . '/js/ads.js',
        array(),
        $ads_version,
        true
    );
    wp_add_inline_script(
        'my_custom_module_ads',
        'const My_Custom_Ads_Version = "' . $ads_version . '";'
    );
    wp_enqueue_script(
        'banners',
        get_stylesheet_directory_uri() . '/js/banners.js',
        array( 'my_custom_module_ads' ),
        $banners_version,
        true
    );
}
add_action( 'wp_enqueue_scripts', 'my_custom_theme_scripts' );

Również z tą opcją ads.js plik może być taki jak poprzednio z export oświadczenie i banners.js I ads-search.js może dynamicznie import z ads.js jak pokazano w opcji-2 powyżej.

Warto przeczytać!  WordPress 6.2 Release Candidate 1 – Wiadomości WordPress

Jednak przy tej opcji przeglądarka się załaduje ads.js module przed dynamicznym importem do banners.js. Więc kiedy wykonywany jest import dynamiczny, przeglądarka użyje już załadowanego pliku.

W większości przypadków nie jest to istotne. Może to jednak mieć znaczenie, gdy wykonujesz import dynamiczny na zdarzeniu takim jak poniższy kod (zwłaszcza jeśli ads.js ładowanie pliku zajmuje dużo czasu):

// sample ads.js code
console.log( 'ads.js loaded:START' );
export async function selectADS( adNumber, element, adsArray ) {
    console.log( 'ads.js as a module loaded' );
};
console.log( 'ads.js loaded:END' );

// banners.js code
console.log( 'banners.js load:START' );

let clicked = false;
document.addEventListener( 'click', async (event) => {   
    if( ! clicked && typeof My_Custom_Ads_Version !== 'undefined' ) {
        const adsModule = await import( `./ads.js?ver=${My_Custom_Ads_Version}` );
        const selectADS = adsModule.selectADS;
        selectADS();
    }
    clicked = true;
});

console.log( 'banners.js load:END' );

Dzięki tej implementacji, jeśli ads.js plik jest znacznie duży i jest importowany dynamicznie tylko podczas zdarzenia, kod staje się prostszy bez konieczności czekania na zaimportowany plik.

Nie jest to jednak najważniejsza zaleta, ponieważ możesz przepisać ten kod JS, aby nadal importować wcześniej. Bardziej znaczącą zaletą tej implementacji jest użycie systemu buforowania lub pakietu, który obserwuje zmiany w kodzie HTML. Dzięki tej opcji łatwiej jest obsłużyć taki scenariusz w przeciwieństwie do opcji-2 (ponieważ z opcją-2 adj.js nie jest widoczny z HTML).


Źródło