ITADN

DataViews: remove all private API usage

#81230Openyouknowriad 创建于 17 天前
npm Packages[Package] Private APIs[Package] DataViews
Y
youknowriadcommented
`@wordpress/dataviews` is a **bundled** package — it declares neither `wpScript` nor `wpModuleExports` in its `package.json`. Per `AGENTS.md`: > Avoid using private APIs in bundled packages (packages without `wpScript` or `wpModuleExports`). Private APIs are intended for Core usage; bundled packages may also be imported via npm into plugin scripts, causing incompatibilities. Concretely: `lockedData` is a module-scoped `WeakMap` and `__private` is a plain `Symbol()` — not `Symbol.for()` ([`implementation.ts#L187-L193`](https://github.com/WordPress/gutenberg/blob/trunk/packages/private-apis/src/implementation.ts#L187-L193)). Two copies of `@wordpress/private-apis` in one runtime cannot unlock each other's objects, so a plugin that loads `wp.components` from the WP global alongside a bundled DataViews throws `Cannot unlock an object that was not locked before` at module-eval time, before anything renders. Secondary cost: `unlock()` is typed `<T = any>( object: unknown ): T`, so every unlocked symbol lands as `any`. All 23 call sites below are effectively unchecked by TypeScript — swapping any of them for a public equivalent tends to surface pre-existing type mismatches. ## `@wordpress/components` 18 of the 25 symbols in [`components/src/private-apis.ts`](https://github.com/WordPress/gutenberg/blob/trunk/packages/components/src/private-apis.ts), across 21 production files: | Symbol | Where | Why it's private | |---|---|---| | `Menu` | [add-filter.tsx:22](https://github.com/WordPress/gutenberg/blob/trunk/packages/dataviews/src/components/dataviews-filters/add-filter.tsx#L22), [dataviews-view-config/index.tsx:37](https://github.com/WordPress/gutenberg/blob/trunk/packages/dataviews/src/components/dataviews-view-config/index.tsx#L37), [dataviews-item-actions/index.tsx:27](https://github.com/WordPress/gutenberg/blob/trunk/packages/dataviews/src/components/dataviews-item-actions/index.tsx#L27), [column-header-menu.tsx:33](https://github.com/WordPress/gutenberg/blob/trunk/packages/dataviews/src/components/dataviews-layouts/table/column-header-menu.tsx#L33), [list/index.tsx:62](https://github.com/WordPress/gutenberg/blob/trunk/packages/dataviews/src/components/dataviews-layouts/list/index.tsx#L62) | Ariakit-based menu; no public replacement exists yet — `@wordpress/ui` has no `menu` | | `Badge` | [picker-grid/index.tsx:36](https://github.com/WordPress/gutenberg/blob/trunk/packages/dataviews/src/components/dataviews-layouts/picker-grid/index.tsx#L36), [composite-grid.tsx:45](https://github.com/WordPress/gutenberg/blob/trunk/packages/dataviews/src/components/dataviews-layouts/grid/composite-grid.tsx#L45) | **A public `Badge` already ships in `@wordpress/ui`** and DataViews uses it in [validation-badge.tsx](https://github.com/WordPress/gutenberg/blob/trunk/packages/dataviews/src/components/dataform-layouts/validation-badge.tsx#L4) — this one is a stale holdout | | `kebabCase` | [dataviews-item-actions/index.tsx:27](https://github.com/WordPress/gutenberg/blob/trunk/packages/dataviews/src/components/dataviews-item-actions/index.tsx#L27) | String util, private to avoid committing to a public utils surface | | `DateCalendar`, `DateRangeCalendar` | [date.tsx:57](https://github.com/WordPress/gutenberg/blob/trunk/packages/dataviews/src/components/dataform-controls/date.tsx#L57), [datetime.tsx:24](https://github.com/WordPress/gutenberg/blob/trunk/packages/dataviews/src/components/dataform-controls/datetime.tsx#L24) | New calendar components still stabilizing | | `withIgnoreIMEEvents` | [richtext/control.tsx:47](https://github.com/WordPress/gutenberg/blob/trunk/packages/dataviews/src/components/dataform-controls/richtext/control.tsx#L47) | IME keydown wrapper | | `Validated*` × 12 | one per control in [dataform-controls/](https://github.com/WordPress/gutenberg/tree/trunk/packages/dataviews/src/components/dataform-controls) — `InputControl`, `Checkbox`, `Combobox`, `Number`, `Select`, `Radio`, `ContentEditable`, `Textarea`, `Toggle`, `ToggleGroup`, `FormTokenField` (+`Text` in a story) | The whole validated-form-controls layer is private; DataForm is its only real consumer | ## `@wordpress/rich-text` 5 of the 9 symbols in [`rich-text/src/private-apis.js`](https://github.com/WordPress/gutenberg/blob/trunk/packages/rich-text/src/private-apis.js), all in one file — [`dataform-controls/richtext/control.tsx`](https://github.com/WordPress/gutenberg/blob/trunk/packages/dataviews/src/components/dataform-controls/richtext/control.tsx#L61): | Symbol | Where | Why it's private | |---|---|---| | `useRichText` | [richtext/control.tsx:61](https://github.com/WordPress/gutenberg/blob/trunk/packages/dataviews/src/components/dataform-controls/richtext/control.tsx#L61) | Core editing hook; the public surface is `RichText` in `@wordpress/block-editor`, which DataViews can't depend on | | `KeyboardShortcutContext`, `InputEventContext` | [richtext/control.tsx:61](https://github.com/WordPress/gutenberg/blob/trunk/packages/dataviews/src/components/dataform-controls/richtext/control.tsx#L61) | The same context objects that format types' `RichTextShortcut` / `RichTextInputEvent` read | | `shortcutsListener`, `inputEventsListener` | [richtext/control.tsx:61](https://github.com/WordPress/gutenberg/blob/trunk/packages/dataviews/src/components/dataform-controls/richtext/control.tsx#L61) | Dispatch the registered callbacks from the editable element's own events | ## Exposed by DataViews | Symbol | Where | Notes | |---|---|---| | `RichTextControl` | locked in [`dataviews/src/private-apis.ts`](https://github.com/WordPress/gutenberg/blob/trunk/packages/dataviews/src/private-apis.ts), unlocked by [editor `note-form.js:28`](https://github.com/WordPress/gutenberg/blob/trunk/packages/editor/src/components/collab-sidebar/note-form.js#L28) | DataViews' own private export — one symbol, one consumer. Needs to become a public export or move to the consumer | ## Todo Ordered by effort — the first three are unblocked today. - [x] **`Badge`** — #81236 - [x] **`kebabCase`** — #81284 and #81294 - [x] **`withIgnoreIMEEvents`** — #81343 - [ ] **`Validated*`** — @mirka - [ ] Move `Spinner` component to wp-ui (Prep in #80511) - [ ] Remove `ValidatedTextControl` #80680 - [ ] Move `ControlWithError` and `ValidityIndicator` to wp-ui (depends on `Spinner`) - [ ] Build `TextareaControl` in wp-ui - [ ] Build `ValidatedInputControl` and `ValidatedTextareaControl` in wp-ui (with new components) - [ ] Move all other validated components to keep internal in wp-dataviews - [ ] Could keep a copy of `ValidatedToggleControl` as a private API in wp-components for wp-content-types usage, to be replaced later by a new version in wp-ui - [ ] **`DateCalendar` / `DateRangeCalendar`** — #81337 - [ ] **`Menu`** (5 sites) — @ciampo #79560 - [ ] **`rich-text` × 5** (1 site) — needs a public way to build a rich-text field outside `@wordpress/block-editor`. The largest single item; likely its own issue once the shape is known. - [ ] **`RichTextControl`** — make it a public DataViews export, or move it into `@wordpress/editor` alongside its only consumer. - [ ] Once all of the above land, drop `@wordpress/private-apis` from [`packages/dataviews/package.json`](https://github.com/WordPress/gutenberg/blob/trunk/packages/dataviews/package.json) and delete [`lock-unlock.ts`](https://github.com/WordPress/gutenberg/blob/trunk/packages/dataviews/src/lock-unlock.ts) and [`private-apis.ts`](https://github.com/WordPress/gutenberg/blob/trunk/packages/dataviews/src/private-apis.ts).
7 条评论