Skip to content
Advertisement

Importing node modules in a WordPress plugin

I’m using wp_register_script and wp_enqueue_script to bring in some custom JavaScript logic for the admin screen of a WordPress plugin I’m developing.

The problem comes when I try to add import statements at the top of my JavaScript in order to bring in a couple node modules. Understandably, this gives me the following browser console message:

import declarations may only appear at top level of a module

What is the standard way to tell WordPress to treat a custom bit of JavaScript as a module? And are there other steps I need to follow in order to make sure that my node modules can be imported?

Advertisement

Answer

What is the standard way to tell WordPress to treat a custom bit of JavaScript as a module?

All you need is type="module" on the <script> tag and the browser will treat this script as ECMAScript module.

With wordpress, to add the type attribute on a script, first enqueue the script

function enqueue_plugin_scripts() {
    wp_enqueue_script('module_handle', get_template_directory_uri() . '/path/to/module.js')
}
add_action( 'wp_enqueue_scripts', 'enqueue_plugin_scripts' );

Then Add type="module" to module_handle using script_loader_tag hook

function set_scripts_type_attribute( $tag, $handle, $src ) {
    if ( 'module_handle' === $handle ) {
        $tag = '<script type="module" src="'. $src .'"></script>';
    }
    return $tag;
}
add_filter( 'script_loader_tag', 'set_scripts_type_attribute', 10, 3 );

And are there other steps I need to follow in order to make sure that my node modules can be imported?

You can’t use bare import, for example : import $ from "jquery" will fail in the browser. To import from the node_modules, you must provide the full path to the module otherwise the browser will complain with Relative references must start with either "/", "./", or "../"

Here is some examples:

This won’t work

import $ from "jquery";
import Swiper from "swiper";

This will work

import "./node_modules/jquery/dist/jquery.js" //because jquery doesn't have browser-compatible ES module
import Swiper from "./node_modules/swiper/js/swiper.esm.browser.bundle.js";
import Swiper from 'https://unpkg.com/swiper/js/swiper.esm.browser.bundle.min.js'; //from external source
console.log($, Swiper) //will output jquery and swiper

Here is a good article on ECMAScript modules in browsers

User contributions licensed under: CC BY-SA
1 People found this is helpful
Advertisement