Make WordPress Core

Changeset 57269


Ignore:
Timestamp:
01/11/2024 02:45:10 PM (11 months ago)
Author:
Bernhard Reiter
Message:

JavaScript: Add new Modules API.

This changeset adds a new API for WordPress, designed to work with native ES Modules and Import Maps. It introduces functions such as wp_register_module, and wp_enqueue_module.

The API aims to provide a familiar experience to the existing WP_Scripts class, offering similar functionality. However, it's not intended to duplicate the exact functionality of WP_Scripts; rather, it is carefully tailored to address the specific needs and capabilities of ES modules.

For this initial version, the current proposal is intentionally simplistic, covering only the essential features needed to work with ES modules. Other enhancements and optimizations can be added later as the community identifies additional requirements and use cases.

Differences Between WP_Script_Modules and WP_Scripts

Dependency Specification

With WP_Script_Modules, the array of dependencies supports not only strings but also arrays that include the dependency import type (static or dynamic). This design choice allows for future extensions of dependency properties, such as adding a version property to support "scopes" within import maps.

Module Identifier

Instead of a handle, WP_Script_Modules utilizes the module identifier, aligning with the module identifiers used in JavaScript files and import maps.

Deregistration

There is no equivalent of wp_deregister_script at this stage.

API

wp_register_module( $module_identifier, $src, $deps, $version )

Registers a module.

// Registers a module with dependencies and versioning.
wp_register_module(
  'my-module',
  '/path/to/my-module.js',
  array( 'static-dependency-1', 'static-dependency-2' ),
  '1.2.3'
);
// my-module.js
import { ... } from 'static-dependency-1';
import { ... } from 'static-dependency-2';

// ...
// Registers a module with a dynamic dependency.
wp_register_module(
  'my-module',
  '/path/to/my-module.js',
  array(
    'static-dependency',
    array(
      'id'     => 'dynamic-dependency',
      'import' => 'dynamic'
    ),
  )
);
// my-module.js
import { ... } from 'static-dependency';

// ...
const dynamicModule = await import('dynamic-dependency');

wp_enqueue_module( $module_identifier, $src, $deps, $version )

Enqueues a module. If a source is provided, it will also register the module.

wp_enqueue_module( 'my-module' );

wp_dequeue_module( $module_identifier )

Dequeues a module.

wp_dequeue_module( 'my-module' );

Output

  • When modules are enqueued, they are printed within script tags containing type="module" attributes.
  • Additionally, static dependencies of enqueued modules utilize link tags with rel="modulepreload" attributes.
  • Lastly, an import map is generated and inserted using a <script type="importmap"> tag.
<script type="module" src="/path/to/my-module.js" id="my-module"></script>
<link rel="modulepreload" href="/path/to/static-dependency.js" id="static-dependency" />
<script type="importmap">
  {
    "imports": {
      "static-dependency": "/path/to/static-dependency.js",
      "dynamic-dependency": "/path/to/dynamic-dependency.js"
    }
  }
</script>

Import Map Polyfill Requirement

Even though all major browsers already support import maps, an import map polyfill is required until the percentage of users using old browser versions without import map support drops significantly.

This work is ongoing and will be added once it's ready. Progress is tracked in #60232.

Props luisherranz, idad5, costdev, neffff, joemcgill, jorbin, swissspidy, jonsurrell, flixos90, gziolo, westonruter.
Fixes #56313.

Location:
trunk
Files:
4 added
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-settings.php

    r56819 r57269  
    366366require ABSPATH . WPINC . '/fonts/class-wp-font-face.php';
    367367require ABSPATH . WPINC . '/fonts.php';
     368require ABSPATH . WPINC . '/class-wp-script-modules.php';
     369require ABSPATH . WPINC . '/script-modules.php';
    368370
    369371$GLOBALS['wp_embed'] = new WP_Embed();
Note: See TracChangeset for help on using the changeset viewer.