Commit 47e43905467 for woocommerce
commit 47e4390546709dfcd3fc69d1f2651893d0c3d1f6
Author: Luigi Teschio <gigitux@gmail.com>
Date: Mon Jul 27 10:42:11 2026 +0200
Separate entity registration from entity utilities (#66978)
* Separate entity registration from entity utilities
* Add changelog entry for entity utility deprecations
* delete file
* fix unit test
* Remove internal package from deprecation guidance
* Simplify wcEntities webpack configuration
diff --git a/plugins/woocommerce/client/blocks/CLAUDE.md b/plugins/woocommerce/client/blocks/CLAUDE.md
index dcdd595c69c..5ad512aaf84 100644
--- a/plugins/woocommerce/client/blocks/CLAUDE.md
+++ b/plugins/woocommerce/client/blocks/CLAUDE.md
@@ -185,6 +185,8 @@ Webpack is configured with **11 separate configs** in `bin/webpack-configs.js`:
Webpack writes directly to `plugins/woocommerce/assets/client/blocks/` so PHP enqueues run against the final asset locations with no copy step. TypeScript uses **60+ path aliases** defined in `tsconfig.base.json`.
+`@woocommerce/entities` resolves to pure entity helpers that are bundled into consumers and can be tree-shaken. The `wc-entities` entry registers those entities as a side effect. It temporarily retains deprecated utility exports on `wc.wcEntities` for backward compatibility. Manual registration helpers also remain available as deprecated compatibility wrappers.
+
## Testing
### Jest Unit Tests
diff --git a/plugins/woocommerce/client/blocks/assets/js/entities/README.md b/plugins/woocommerce/client/blocks/assets/js/entities/README.md
index 7d138e79d05..10938634ad9 100644
--- a/plugins/woocommerce/client/blocks/assets/js/entities/README.md
+++ b/plugins/woocommerce/client/blocks/assets/js/entities/README.md
@@ -1,12 +1,12 @@
# WooCommerce Block Entities
-This module contains the entity registration and management system for WooCommerce. Entities provide a standardized way to interact with WordPress data stores and enable consistent data access patterns across the admin interface.
+This module contains the entity helpers for WooCommerce. Entities provide a standardized way to interact with WordPress data stores and enable consistent data access patterns across the admin interface.
## Overview
-Entities have a dedicated module that loads consistently on every admin screen, ensuring they can be accessed and extended throughout the entire admin experience. This makes it possible to use the entities in this folder across all the admin screens.
+The pure entity helpers in this directory are bundled into their consumers and can be tree-shaken. Registration lives separately in `../entity-registration` and builds as a dedicated script that loads consistently on every admin screen.
-With this approach, third-party developers can also start using entities outside of the Gutenberg editor whenever needed.
+For backward compatibility, the registration script continues to expose the runtime helpers on `wc.wcEntities`. That global API is deprecated as of WooCommerce 11.1.0 and emits a warning when a helper is called.
## Available Entities
@@ -23,19 +23,20 @@ The product entity provides access to WooCommerce product data through WordPress
### Automatic Registration
-Entities are automatically registered when the module is loaded. This happens on every admin page through the `wc-entities` script.
+Entities are automatically registered on every admin page through the `wc-entities` script. The script performs registration as a side effect and temporarily retains the deprecated `wc.wcEntities` global for backward compatibility.
-### Manual Registration
+### Deprecated manual registration
-If you need to register entities manually (e.g., in tests), you can use the registration functions:
+The manual registration functions remain exported temporarily for compatibility:
```typescript
import { registerProductEntity } from './entities/register-entities';
-// Register the product entity
registerProductEntity();
```
+These functions are deprecated as of WooCommerce 11.1.0 and emit a warning when called. Rely on the automatically loaded `wc-entities` script instead.
+
### Using Entity Hooks
```typescript
@@ -55,4 +56,4 @@ function MyComponent() {
1. **Consistent Availability**: Entities are now available across all admin pages, not just the editor
2. **Better Performance**: Centralized registration reduces duplicate entity definitions
-3. **Developer Experience**: Third-party developers can use entities outside of Gutenberg
+3. **Encapsulation**: Entity helpers remain internal to the bundles that consume them
diff --git a/plugins/woocommerce/client/blocks/assets/js/entities/index.ts b/plugins/woocommerce/client/blocks/assets/js/entities/index.ts
index 9e92aa3417c..73ea967cbb0 100644
--- a/plugins/woocommerce/client/blocks/assets/js/entities/index.ts
+++ b/plugins/woocommerce/client/blocks/assets/js/entities/index.ts
@@ -1,20 +1,2 @@
-/**
- * Internal dependencies
- */
-import { isExperimentalWcRestApiV4Enabled } from '../settings/blocks/feature-flags';
-import {
- registerProductEntity,
- registerSettingsEntity,
-} from './register-entities';
-
export * from './product';
export * from './settings';
-
-registerProductEntity();
-
-/**
- * Register the settings entity only when the experimental v4 REST API is enabled.
- */
-if ( isExperimentalWcRestApiV4Enabled() ) {
- registerSettingsEntity();
-}
diff --git a/plugins/woocommerce/client/blocks/assets/js/entities/register-entities.ts b/plugins/woocommerce/client/blocks/assets/js/entities/register-entities.ts
index d21acd42cf1..51f017a9edd 100644
--- a/plugins/woocommerce/client/blocks/assets/js/entities/register-entities.ts
+++ b/plugins/woocommerce/client/blocks/assets/js/entities/register-entities.ts
@@ -1,31 +1,46 @@
/**
* External dependencies
*/
-import { store as coreStore } from '@wordpress/core-data';
-import { dispatch } from '@wordpress/data';
+import deprecated from '@wordpress/deprecated';
/**
* Internal dependencies
*/
-import { PRODUCT_ENTITY } from './product/constants';
-import { SETTINGS_ENTITY } from './settings/constants';
+import {
+ registerProductEntity as registerProductEntityInternal,
+ registerSettingsEntity as registerSettingsEntityInternal,
+} from '../entity-registration/register-entities';
-const registered: string[] = [];
+const deprecationNoticesShown = new Set< string >();
-export const registerProductEntity = () => {
- if ( registered.includes( PRODUCT_ENTITY.name ) ) {
+const showDeprecationNotice = ( functionName: string ) => {
+ if ( deprecationNoticesShown.has( functionName ) ) {
return;
}
- const { addEntities } = dispatch( coreStore );
- void addEntities( [ PRODUCT_ENTITY ] );
- registered.push( PRODUCT_ENTITY.name );
+
+ deprecated( `${ functionName }()`, {
+ since: '11.1.0',
+ alternative: 'automatic entity registration',
+ plugin: 'WooCommerce',
+ hint: 'Entities are registered automatically by the wc-entities script. Remove this call.',
+ } );
+ deprecationNoticesShown.add( functionName );
};
+/**
+ * @deprecated Since WooCommerce 11.1.0. Entities are registered automatically
+ * by the wc-entities script.
+ */
+export const registerProductEntity = () => {
+ showDeprecationNotice( 'registerProductEntity' );
+ return registerProductEntityInternal();
+};
+
+/**
+ * @deprecated Since WooCommerce 11.1.0. Entities are registered automatically
+ * by the wc-entities script.
+ */
export const registerSettingsEntity = () => {
- if ( registered.includes( SETTINGS_ENTITY.name ) ) {
- return;
- }
- const { addEntities } = dispatch( coreStore );
- void addEntities( [ SETTINGS_ENTITY ] );
- registered.push( SETTINGS_ENTITY.name );
+ showDeprecationNotice( 'registerSettingsEntity' );
+ return registerSettingsEntityInternal();
};
diff --git a/plugins/woocommerce/client/blocks/assets/js/entity-registration/deprecated-exports.ts b/plugins/woocommerce/client/blocks/assets/js/entity-registration/deprecated-exports.ts
new file mode 100644
index 00000000000..999262f1969
--- /dev/null
+++ b/plugins/woocommerce/client/blocks/assets/js/entity-registration/deprecated-exports.ts
@@ -0,0 +1,59 @@
+/**
+ * External dependencies
+ */
+import deprecated from '@wordpress/deprecated';
+
+/**
+ * Internal dependencies
+ */
+import {
+ isExternalProduct as isExternalProductInternal,
+ isProductResponseItem as isProductResponseItemInternal,
+ useProduct as useProductInternal,
+} from '../entities';
+
+const deprecationNoticesShown = new Set< string >();
+
+const showDeprecationNotice = ( functionName: string ) => {
+ if ( deprecationNoticesShown.has( functionName ) ) {
+ return;
+ }
+
+ deprecated( `wc.wcEntities.${ functionName }()`, {
+ since: '11.1.0',
+ plugin: 'WooCommerce',
+ hint: 'The wc.wcEntities global is deprecated and will be removed in a future release.',
+ } );
+ deprecationNoticesShown.add( functionName );
+};
+
+/**
+ * @deprecated Since WooCommerce 11.1.0. The wc.wcEntities global will be
+ * removed in a future release.
+ */
+export const useProduct: typeof useProductInternal = ( postId ) => {
+ showDeprecationNotice( 'useProduct' );
+ return useProductInternal( postId );
+};
+
+/**
+ * @deprecated Since WooCommerce 11.1.0. The wc.wcEntities global will be
+ * removed in a future release.
+ */
+export const isExternalProduct: typeof isExternalProductInternal = (
+ product
+) => {
+ showDeprecationNotice( 'isExternalProduct' );
+ return isExternalProductInternal( product );
+};
+
+/**
+ * @deprecated Since WooCommerce 11.1.0. The wc.wcEntities global will be
+ * removed in a future release.
+ */
+export const isProductResponseItem: typeof isProductResponseItemInternal = (
+ product
+) => {
+ showDeprecationNotice( 'isProductResponseItem' );
+ return isProductResponseItemInternal( product );
+};
diff --git a/plugins/woocommerce/client/blocks/assets/js/entity-registration/index.ts b/plugins/woocommerce/client/blocks/assets/js/entity-registration/index.ts
new file mode 100644
index 00000000000..89064b8c529
--- /dev/null
+++ b/plugins/woocommerce/client/blocks/assets/js/entity-registration/index.ts
@@ -0,0 +1,20 @@
+/**
+ * Internal dependencies
+ */
+import { isExperimentalWcRestApiV4Enabled } from '../settings/blocks/feature-flags';
+import {
+ registerProductEntity,
+ registerSettingsEntity,
+} from './register-entities';
+
+export {
+ isExternalProduct,
+ isProductResponseItem,
+ useProduct,
+} from './deprecated-exports';
+
+registerProductEntity();
+
+if ( isExperimentalWcRestApiV4Enabled() ) {
+ registerSettingsEntity();
+}
diff --git a/plugins/woocommerce/client/blocks/assets/js/entity-registration/register-entities.ts b/plugins/woocommerce/client/blocks/assets/js/entity-registration/register-entities.ts
new file mode 100644
index 00000000000..f498e3d0110
--- /dev/null
+++ b/plugins/woocommerce/client/blocks/assets/js/entity-registration/register-entities.ts
@@ -0,0 +1,31 @@
+/**
+ * External dependencies
+ */
+import { store as coreStore } from '@wordpress/core-data';
+import { dispatch } from '@wordpress/data';
+
+/**
+ * Internal dependencies
+ */
+import { PRODUCT_ENTITY } from '../entities/product/constants';
+import { SETTINGS_ENTITY } from '../entities/settings/constants';
+
+const registered: string[] = [];
+
+export const registerProductEntity = () => {
+ if ( registered.includes( PRODUCT_ENTITY.name ) ) {
+ return;
+ }
+ const { addEntities } = dispatch( coreStore );
+ void addEntities( [ PRODUCT_ENTITY ] );
+ registered.push( PRODUCT_ENTITY.name );
+};
+
+export const registerSettingsEntity = () => {
+ if ( registered.includes( SETTINGS_ENTITY.name ) ) {
+ return;
+ }
+ const { addEntities } = dispatch( coreStore );
+ void addEntities( [ SETTINGS_ENTITY ] );
+ registered.push( SETTINGS_ENTITY.name );
+};
diff --git a/plugins/woocommerce/client/blocks/bin/webpack-entries.js b/plugins/woocommerce/client/blocks/bin/webpack-entries.js
index a1b3b48eb39..c32eb5c119c 100644
--- a/plugins/woocommerce/client/blocks/bin/webpack-entries.js
+++ b/plugins/woocommerce/client/blocks/bin/webpack-entries.js
@@ -363,7 +363,7 @@ const entries = {
wcSchemaParser: './assets/js/utils/schema-parser/index.ts',
priceFormat: './packages/prices/index.js',
wcTypes: './assets/js/types/index.ts',
- wcEntities: './assets/js/entities/index.ts',
+ wcEntities: './assets/js/entity-registration/index.ts',
},
main: {
// Shared blocks code
diff --git a/plugins/woocommerce/client/blocks/changelog/dev-deprecate-wc-entities-global b/plugins/woocommerce/client/blocks/changelog/dev-deprecate-wc-entities-global
new file mode 100644
index 00000000000..c2db48651a1
--- /dev/null
+++ b/plugins/woocommerce/client/blocks/changelog/dev-deprecate-wc-entities-global
@@ -0,0 +1,4 @@
+Significance: patch
+Type: dev
+
+Separate entity registration from tree-shaken helpers while deprecating the global utilities and manual registration functions.
diff --git a/plugins/woocommerce/client/blocks/tests/integration/helpers/integration-test-editor.tsx b/plugins/woocommerce/client/blocks/tests/integration/helpers/integration-test-editor.tsx
index 60012d94d2a..1abbc48c772 100644
--- a/plugins/woocommerce/client/blocks/tests/integration/helpers/integration-test-editor.tsx
+++ b/plugins/woocommerce/client/blocks/tests/integration/helpers/integration-test-editor.tsx
@@ -26,7 +26,7 @@ import {
*/
import { waitForStoreResolvers } from './wait-for-store-resolvers';
import { unlock } from '../../utils/lock-unlock';
-import { registerProductEntity } from '../../../assets/js/entities/register-entities';
+import { registerProductEntity } from '../../../assets/js/entity-registration/register-entities';
const { ExperimentalBlockCanvas: BlockCanvas } = unlock(
blockEditorPrivateApis