Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Script Modules: Allow scripts to depend on modules #10

Closed
wants to merge 2 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 49 additions & 10 deletions src/wp-includes/class-wp-script-modules.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,18 @@ class WP_Script_Modules {
*/
private $enqueued_before_registered = array();

/**
* Holds script module identifiers that have been requested for exposure.
*
* "Exposed" indicates that the script module should be exposed in the
* import map regardless of whether it is a dependency of another script
* module.
*
* @since 6.8.0
* @var array<string, true>
*/
private $exposed = array();

/**
* Tracks whether the @wordpress/a11y script module is available.
*
Expand Down Expand Up @@ -148,6 +160,17 @@ public function enqueue( string $id, string $src = '', array $deps = array(), $v
}
}

/**
* Marks the script module so it will be exposed in the import map.
*
* @since 6.8.0
*
* @param string $id The identifier of the script module.
*/
public function expose( string $id ) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a new concept in WordPress, so I wanted to share some alternatives to help find the final name:

  • add_to_import_map
  • include_in_import_map

Conceptually, the idea makes perfect sense to me. This method might also be useful when third-party code wants to ensure its dependency is listed in the import map, and they don't want to use all the tooling to generate dependencies for their script modules.

$this->exposed[ $id ] = true;
}

/**
* Unmarks the script module so it will no longer be enqueued in the page.
*
Expand Down Expand Up @@ -208,10 +231,15 @@ public function add_hooks() {
*/
public function print_enqueued_script_modules() {
foreach ( $this->get_marked_for_enqueue() as $id => $script_module ) {
$src = $this->get_src( $id );
if ( null === $src ) {
continue;
}

wp_print_script_tag(
array(
'type' => 'module',
'src' => $this->get_src( $id ),
'src' => $src,
'id' => $id . '-js-module',
)
);
Expand All @@ -228,11 +256,16 @@ public function print_enqueued_script_modules() {
*/
public function print_script_module_preloads() {
foreach ( $this->get_dependencies( array_keys( $this->get_marked_for_enqueue() ), array( 'static' ) ) as $id => $script_module ) {
$src = $this->get_src( $id );
if ( null === $src ) {
continue;
}

// Don't preload if it's marked for enqueue.
if ( true !== $script_module['enqueue'] ) {
echo sprintf(
'<link rel="modulepreload" href="%s" id="%s">',
esc_url( $this->get_src( $id ) ),
esc_url( $src ),
esc_attr( $id . '-js-modulepreload' )
);
}
Expand Down Expand Up @@ -262,13 +295,19 @@ public function print_import_map() {
*
* @since 6.5.0
*
* @return array Array with an `imports` key mapping to an array of script module identifiers and their respective
* URLs, including the version query.
* @return array Array with an `imports` key mapping to an array of script
* module identifiers and their respective URLs, including
* the version query.
*/
private function get_import_map(): array {
$imports = array();
foreach ( $this->get_dependencies( array_keys( $this->get_marked_for_enqueue() ) ) as $id => $script_module ) {
$imports[ $id ] = $this->get_src( $id );
$imports = array();
$script_module_ids = array_unique( array_keys( $this->exposed ) + array_keys( $this->get_marked_for_enqueue() ) );
foreach ( $this->get_dependencies( $script_module_ids ) as $id => $script_module ) {
$src = $this->get_src( $id );
if ( null === $src ) {
continue;
}
$imports[ $id ] = $src;
}
return array( 'imports' => $imports );
}
Expand Down Expand Up @@ -335,11 +374,11 @@ function ( $dependency_script_modules, $id ) use ( $import_types ) {
* @since 6.5.0
*
* @param string $id The script module identifier.
* @return string The script module src with a version if relevant.
* @return string|null The script module src with a version if relevant.
*/
private function get_src( string $id ): string {
private function get_src( string $id ): ?string {
if ( ! isset( $this->registered[ $id ] ) ) {
return '';
return null;
}

$script_module = $this->registered[ $id ];
Expand Down
Loading