-
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
Documentation: Update documentation about build process changes #66428
Conversation
Document the wpScript and wpScriptModuleExports fields and their purposes.
The block-library includes instructions for setting up a new block, document special steps necessary for script modules.
The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message.
To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook. |
// Include this line to include the package as a WordPress script. | ||
"wpScript": true, | ||
// Include this line to include the package as a WordPress script module. | ||
"wpScriptModuleExports": "./build-module/index.js" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure I like this. Why should a package.json mention a built file. why wpModule: true
is not enough? since we already have module
defined in the package.json ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think one aspect needs to be documented. Using wpScript
or/and wpScriptModuleExports
marks the package as production package for strict verification of compatibility with GPL license.
module
isn't configured correctly at the moment. Eventually, we can explore migrating to "type": "module"
and exports
configuration but it's a separate effort.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
module isn't configured correctly at the moment.
I'm not sure I understand, we've been relying on module to output ESmodules forever, why is it not correct?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was looking at https://github.com/WordPress/gutenberg/blob/trunk/packages/a11y/package.json for instance
That package has both "module" and "wpScriptModuleExports" and they point to different modules/APIs. So we're saying that this package ships "two different ESmodules" in one package. As an npm package consumer, I'm really confused what import something from '@wordpress/a11y'
will yield to me. Which one of these is going to be used? Ultimately a package can ship multiple modules, that's ok but not two versions of the same module.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think one aspect needs to be documented. Using
wpScript
or/andwpScriptModuleExports
marks the package as production package for strict verification of compatibility with GPL license.
I opened a follow-up #66562.
|
||
For packages that should ship as a WordPress script, include `wpScript: true` in the `package.json` file. This tells the build system to bundle the package for use as a WordPress script. | ||
|
||
For packages that should ship as a WordPress script module, include a `wpScriptModuleExports` field the `package.json` file. The value of this field can be a string to expose a single script module, or an object with a [shape like the standard `exports` object](https://nodejs.org/docs/latest-v20.x/api/packages.html#subpath-exports) to expose multiple script modules from a single package: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't this a duplication of the exports
field for regular npm packages. Do we really need to invent our own convention?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@sirreal can provide a more exhaustive response. We were discussing using the official configuration for ES Modules:
It'll eventually happen, but more work is necessary. For example, all import statements that contain file paths must contain the file extension, for example: import './file.js';
. That isn't the case currently.
|
||
```php | ||
function render_block_core_blinking_paragraph( $attributes, $content ) { | ||
$should_load_view_script = ! empty( $attributes['isInteractive'] ) && ! wp_script_is( 'wp-block-blinking-paragraph-view' ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Noting that there is no wp_script_module_is_enqueued
helper method. It isn't strictly necessary here, but it might be helpful for extenders in different scenarios.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for opening this PR, @sirreal. It documents the current approach for annotating package.json
files to instruct webpack bundler of how to create entry points for scripts and script modules.
It would also be helpful to explain how the production packages are detected when performing license checks as noted in https://github.com/WordPress/gutenberg/pull/66428/files#r1816140475.
I also appreciate the questions raised by @youknowriad. We should continue discussing how to evolve the configuration entries to apply these changes in future iterations.
Flaky tests detected in 03fb0aa. 🔍 Workflow run URL: https://github.com/WordPress/gutenberg/actions/runs/11514286825
|
This reflects the current state of things so I'm going to land it. The conversation is largely around the changes to the build that are already live and not about the documentation. I'll continue to reply to the conversation after merging.
Noted, I'll address this in a follow-up. I want to prioritize getting the essentials documented. |
I'll try to answer all of the questions and provide some motivation. This is all very complex. What a "package" is can be very different things in different contexts. The motivation here is actually to simplify the build so that it can be understood through some declarative configuration instead of having 2 imperative builds that must be kept in sync across Gutenberg and WordPress Core, while improving support for Script Modules and other things like npm workspaces. Packages:
To complicate things, package.json can define the package with different The A lot of these recent changes move logic that was information about package but was centralized in the build system and duplicated in Gutenberg and Core. The changes make the packages declare if and how they should be bundled for WordPress. Nothing has changed for npm packages. Nothing has changed for scripts. Nothing has changed for script modules. This is all about making the build support scripts and script modules and rely on declarative configuration.
This is already a common practice,
Individual packages may expose several script modules, block-library is a good example of that.
The nonstandard With
Not really.
The same thing as before… it depends 🙂
Conceptually it's similar as the exports field (although it's simpler, for example conditional exports are not supported), but this is declarative for WordPress script module bundling. I think re-using the convention is helpful, but switching to use Again, the goal here is to support our needs —declare the exposed script modules for bundling for WordPress— without disrupting anything else. |
Just want to share that I totally agree with normalizing all this config in package.json, it's way better than having all these scattered configs in webpack and else. Now I would like to talk about the "how" and the "details".
The problem is that our packages are both "modules" and "scripts", so how do you do that today in npm world?
Sure but for me, we're risking of creating two APIs for the same module by pointing "module" to a file and "wpScriptModuleExports" to another. I'd rather not do that and having an npm package ship one or multiple module but consistently. Most npm packages ship one module, the make it available as CJS or ESM but the API is the same. But for a11Y it's not really the case. We have 1 CJS version that is equivalent to another ESM version but we also have another slightly different ESM version.
This is where I'm not following, and this is the main important point for me. we need WordPress to ship ES modules, why can't WordPress just use the "module" version of our packages in that case? If the answer is that the current format for our module exports is broken, that's ok, we should fix it. I want to avoid having WordPress ship a module with a given API but the actual npm package is a different API. I think that's not desirable and will create confusion for documentation... |
The modern way of handling that would be to use conditional exports. That's not unlike the approach that's been taken recently with the build for WordPress.
This has always been the case. There's always a risk. The standard
This is less true with exports and subpaths, packages are gradually exposing more entrypoints just like has been done with block-library: gutenberg/packages/block-library/package.json Lines 33 to 39 in 506342b
I understand your position and agree that we want to be consistent. I don't think this is that different from the previous situation. The things that are published as packages to npm are not the same things that are shipped with WordPress. Building and bundling them fundamentally changes them. Scripts and Script Modules have some fundamental differences. Moreso in WordPress where the same APIs cannot be used for initialization (scripts use inline scripts with imperative initialization, modules use the data passing API and should perform initialization themselves). For a11y, we decided it was possible to expose the same API as a script and a script module. #65101 extracted a shared "core" implementation, then exposes a script and a script module version that hides their necessary differences. For some existing scripts, this may work well. For others it may not and a completely separate module may need to be introduced. But when the API can remain the same.
One fundamental difference is that scripts and script modules cannot interdepend (at this time). Script modules cannot depend on scripts and I don't see that changing. It's not as simple as taking a module "build" (which has had some simple babel transformations applied) and compiling it into a WordPress script module will not often not work because the dependencies are not satisfied. For The behavior of these things in WordPress is different. It's not the same as when they're bundled with other applications or used elsewhere. This is true for both scripts and script modules and it's always been the case. The approach taken for script modules recognizes that the build and environment for WordPress is different. It has different constraints and possibilities. I will add another difficulty that does concern me and I've. Right now scripts import If a script does I've been looking at import attributes as a possible solution for this problem when it arises: const { speak } = import('@wordpress/a11y', { with: { wpModule: true } }) |
That's an interesting discussion point. Most of the existing WordPress packages aren't fully compatible with ES Modules despite the fact that we publish to npm To you point, eventually, we should be in the place, when both script module and script use the same entry point, but there still is going to be some backward compatibility layer where the logic specific only for scripts would have to be kept around, for example: functions calls to configure |
…ress#66428) Document recent changes to the build system that change are requirements for publishing WordPress scripts and script modules. WordPress#65064 updated the way that script modules from packages are bundled for Gutenberg and WordPress. WordPress#66272 updated the way that scripts from packages are bundled for Gutenberg and WordPress. --------- Co-authored-by: sirreal <jonsurrell@git.wordpress.org> Co-authored-by: gziolo <gziolo@git.wordpress.org> Co-authored-by: justintadlock <greenshady@git.wordpress.org> Co-authored-by: youknowriad <youknowriad@git.wordpress.org>
What?
Update documentation about build process.
#65064 updated the way that script modules from packages are bundled for Gutenberg and WordPress.
#66272 updated the way that scripts from packages are bundled for Gutenberg and WordPress.
Why?
The build system has been modified and requirements have changed, it's important to keep documentation up to date. The system is expected to be stable now.
Testing Instructions
Do the docs appear accurate and make sense?