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

Experiment: A Modules API with optional static server dependency graph #56118

Conversation

luisherranz
Copy link
Member

What?

Built on top of #56092.

This is the second of a series of experiments to understand the requirements of a hypothetical Modules API. More info in the Tracking Issue:

This experiment aims to implement an API that is slightly more complex than the one implemented in the first experiment, with the same characteristics but adding an optional static server dependency graph to be able to preload modules and avoid initial waterfalls:

  • An API to register modules using:
    • A module identifier (required)
    • The full URL or the path (required)
    • Whether the module is for the admin, the frontend or both (required)
    • A version (optional)
    • The static dependencies (optional)
  • An API to enqueue modules.
  • All registered modules add an entry in the import map.
  • Enqueued modules add a <script> tag in the head.
  • The static dependencies are preloaded when the module is enqueued using a <link rel="modulepreload"> tag in the head.

Why?

In the first experiment, it's not easy to know which modules need to be preloaded and, therefore, it's not easy to avoid the initial waterfalls.

How?

By leveraging a new Gutenberg_Modules class that acts as a singleton and a couple of functions to expose the functionality:

  • gutenberg_register_module to register modules and add entries to the import map.
  • gutenberg_enqueue_module to enqueue modules.

Then, we print three times using the wp_head action:

  • The import map.
  • The enqueued modules.
  • The preloaded modules.

Testing Instructions

  • Add some interactive blocks: Navigation, Query or Image block.
  • Check that in the frontend, there is an import map script.
  • Check that scripts with type="module" are loaded by the interactive blocks.
  • Check that the @wordpress/interactivity module is loaded by the other modules using import ... from "@wordpress/interactivity".
  • Check that the @wordpress/interactivity module is download at the same time than the rest (instead of after, like in the first experiment), and that there is a link tag with rel="modulepreload" in the head.

@luisherranz luisherranz added the [Type] Experimental Experimental feature or API. label Nov 14, 2023
@luisherranz luisherranz self-assigned this Nov 14, 2023
},
externalsType: 'module',
externals: {
'@wordpress/interactivity': '@wordpress/interactivity',
Copy link
Contributor

Choose a reason for hiding this comment

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

I think at some point in our config we need to maintain an esmodules array to keep these as is in the code (just like we have a dedicated config for bundled modules). I expect interactivity to be just one of these modules

Copy link
Member Author

Choose a reason for hiding this comment

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

Yeah. I didn't pay much attention to the bundling side yet as it shouldn't affect the PHP API, so I just made it work 😄

(I'm not a fan of the code produced by Webpack for ES modules, by the way.)

}

add_action( 'wp_print_scripts', 'block_core_search_ensure_interactivity_dependency' );
add_action( 'init', 'register_block_core_search' );
Copy link
Contributor

Choose a reason for hiding this comment

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

I really like how this simplifies the code of all these "interactive" blocks.

@gziolo
Copy link
Member

gziolo commented Mar 8, 2024

This is now part of WordPress core 🎉

The final approach is documented in the dev note: Script Modules in 6.5.

@gziolo gziolo closed this Mar 8, 2024
@gziolo gziolo deleted the experiment/modules-and-import-maps-api-optional-static-dependency-graph branch March 8, 2024 07:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Type] Experimental Experimental feature or API.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants