-
Notifications
You must be signed in to change notification settings - Fork 4.2k
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
Proposal: Support module metadata in block.json for Blocks + Modules API #57492
Comments
I'll some notes from speaking with @gziolo and @luisherranz about this. GeneralWithout more WordPress modules available, it doesn't seem like there's a use case for We can remove support for @wordpress/dependency-extraction-webpack-pluginThis part seems straightforward. We should mark module compilation as experimental for now. That could be via a configuration option or a notice in the README. I plan to add an experimental warning to the README in #57199. If anyone feels strongly that a configuration option should be required for modules, we can consider it. With modules, there's some risk of bundling WordPress packages, e.g. Block registrationIt's a good idea to ship this in Gutenberg first and Core later. That will allow us to test it out. We can use it on https://wpmovies.dev/ once it's available in Gutenberg. View modules will need to be exposed in the REST API endpoint for block types. None of the core block.json files should be migrated to use As noted above, we'll start with just @wordpress/scriptsThe scripts package has more uncertainty than other changes. There remain some open questions. Keeping this feature clearly marked as experimental without changing any of the default behavior will allow us to iterate more freely.
There remain some open questions about outputting to a single build directory from a webpack multi-compilation. There's risk of assets colliding or being removed incorrectly. One of the compilations is responsible for copying PHP files (render.php) and block.json. Using another directory might help. but we'd need to rewrite parts of block.json instead of copying it if we change the relative path. |
Hey all 👋 Thanks for this proposal and all the detailed notes here. I have to say I am nowhere near an expert on ES Modules and all the benefits they bring but I have some specific workflow question relating to how this will impact (hopefully better) the experience of building blocks. Lets imagine an example where I have two separate blocks that both have some frontend JS. Both are trying to also use some shared utility functions from a separate file. We want to make sure that the JS only actually gets loaded when the block is on the current page and also we don't want the shared file with the utility functions to be loaded twice. Today even without modules this is possible by registering the helper file separately in WordPress and then adding that files handle as a script dependency to the This paired with the fact that we have the Of course if I didn't do that step this would still work but the code from the shared file would be bundled into both of the blocks view scripts and therefore add bloat to the page if both blocks are present. Is my understanding of this proposal correct in that this would essentially simplify this step of having to manually register any file we want to import as a separate script and automate that by making each imported file an additional module that therefore also makes sure the code isn't duplicated? |
Thanks for the questions! The short answer is that the situation you describe will not be drastically different. This is largely about adding In the case you describe, the shared module can still be shared, but it will be up to developers to split things up properly. The shared module will still need to be built as its own module and registered as a WordPress module. With modules coming to WordPress it may open up a lot of interesting opportunities in the bundling and tooling space, but that's beyond the scope of this proposal. One important improvement over scripts we have here is that scripts and script dependencies will always be loaded, even if they're deferred. Modules don't have that limitation, they can be loaded on demand. If we have a shared module, but none of the modules that depend on it ever need it, it's possible to avoid ever downloading the shared module.
No. That may be possible but that's not what this proposal is about. We still expect to compile the viewModule with @wordpress/scripts into a single module. More advanced builds are possible, but they're not the focus of this proposal. |
There is one thing that isn't covered in this issue, and it is tracked on WordPress Trac – Blocks: Introduce a way to enqueue view scripts only when needed for interactivity. It would be great to refactor existing core blocks by offering a formal way for block developers to automatically enqueue registered modules only when related directives are present in the printed HTML for the block. This is handled with the following code as of today: gutenberg/packages/block-library/src/search/index.php Lines 94 to 114 in fc3715f
In the prototypes shared, like for instance sirreal/wordpress-develop#2, all registered view modules with |
@gziolo Do you think that should be considered in the first iteration of this proposal? Or could this move ahead with a default behavior to always load the module, then be improved later with different module enqueuing strategies? |
It isn't mandatory as of today, but the truth is that all 5 core blocks won't benefit from integration with |
If it is helpful I would like to add as a reference an experiment I did recently, aiming to replace webpack with Vite. Additionally, I need to include the link (and credits) to this repository: https://github.com/kucrut/vite-for-wp, and this discussion on Vite's GitHub page: vitejs/vite#9411 These resources provided much of the information I used to develop the Vite plugin that resolves dependencies and generates the necessary PHP file to load the block. Currently, some features, such as HMR, are not working |
Add handling of viewModule field in block.json when using wp-scripts build or start. As the Modules API matures, our tooling should support it. We add an option to clearly mark this an an experimental feature: `wp-scripts build --experimental-modules` or `wp-scripts start --experimental-modules`. To support modules with webpack, it was necessary to run a multi-compilation. An array of webpack configurations is used instead of a single webpack configuration. This is because module compilation is an option at the compilation level and cannot be set for specific entrypoints. If the `--experimental-modules` option is found, we use an environment variable to change the webpack.config export to return an array `[ scriptWebpackConfig, moduleWebpackConfig ]`. Without the experimental option, the `webpack.config` export is the same. Consumers should be able to continue extending this config without noticing any differences. Part of #57492.
The work in Gutenberg had landed so as of now:
|
I've started implementing modules support in WordPress Core in WordPress/wordpress-develop#5860. "Modules" became "script modules" in the Core implementation, so I'm planning to rename the |
I'll close this issue, the most significant topics have been covered. |
What problem does this address?
As the Modules API matures and is considered for WordPress Core (WordPress/wordpress-develop#5818), we should consider the experience for working with modules and blocks. The experience of working with modules should not regress compared to the experience of working with scripts.
This proposal is to add Modules API support to blocks via
block.json
. The proposal suggests the addition ofeditorModule
,module
, andviewModule
toblock.json
metadata. These fields are analogous toeditorScript
,script
, andviewScript
but use the Modules API.This issue is intended for discussion and tracking of the necessary work to better support modules when working with blocks. The ideas here came from discussions with @luisherranz.
Current status and suggested changes
Block registration
Blocks can be registered using
register_block_type_from_metadata
and ablock.json
file. These mechanisms support theeditorScript
,script
, andviewScript
fields to associate scripts with the block in different contexts so the scripts and be registered and enqueued under the appropriate circumstances.The Modules API is in Gutenberg and has a proposal for WordPress Core: WordPress/wordpress-develop#5818.
Suggested changes:
register_block_type_from_metadata
should support *module fields:WordPress script/module dependencies
@wordpress/dependency-extraction-webpack-plugin handles automatic externalization of WordPress script dependencies and generation of a
[script].asset.php
file used byregister_block_type_from_metadata
.Suggested changes:
@wordpress/scripts will detect
block.json
files in a project and perform webpack compilation to generate the expected assets for use in a production site.Suggested changes:
*module
fields discovered inblock.json
: WP Scripts: Build block.json viewModule #57461 (proof of concept)Script/Module compatibility
WordPress core scripts are only available as scripts at this time. None of the core scripts can be used as modules. The exception is
@wordpress/interactivity
which is only available as a module.viewModule
can be used with block using the Interactivity API (@wordpress/interactivity
), but not with other core scripts. Some core scripts are not well suited for use on the frontend so this may not be limiting forviewModule
. One notable exception is an internalization library,@wordpress/i18n
would be nice to have available to modules.Block.json
editorModule
andmodule
become much less useful, because they will likely need to use scripts to integrate with the editor. We can still build out functionality to support these fields which is very similar toviewModule
.Suggested changes:
None. This is a broader consideration for the Modules API. Existing scripts need to be made available to modules. I know that @luisherranz has ideas for how to move forward in this area (#55942 (comment)), but for simplicity I'd like to consider the modules-scripts interoperability out of scope for this discussion.
The text was updated successfully, but these errors were encountered: