Skip to content

Commit f708ede

Browse files
committed
Back out icon changes
1 parent b248555 commit f708ede

26 files changed

Lines changed: 120 additions & 120 deletions

File tree

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,9 @@ Import each component from its dynamic entry point to keep bundle size minimal:
3030
import ChatbotToggle from '@patternfly/chatbot/dist/dynamic/ChatbotToggle';
3131
```
3232

33-
Do not import from the package root (`import { ChatbotToggle } from '@patternfly/chatbot'`).
33+
Named imports from the root barrel also tree-shake with modern bundlers that respect the package `sideEffects` field.
34+
35+
`CodeModal`, `PreviewAttachment`, `AttachmentEdit`, and `tracking` are not exported from the root barrel — import them from `dist/dynamic/<Component>` instead. See `packages/module/patternfly-docs/content/extensions/chatbot/tree-shaking.md` for migration details.
3436

3537
To verify tree-shaking in this repo:
3638

packages/module/package.json

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,5 +101,10 @@
101101
"require": "./dist/cjs/*/index.js"
102102
},
103103
"./monaco-environment": "./monaco-environment.js"
104-
}
104+
},
105+
"sideEffects": [
106+
"**/*.css",
107+
"**/*.scss",
108+
"patternfly-docs/**"
109+
]
105110
}

packages/module/patternfly-docs/content/extensions/chatbot/tree-shaking.md

Lines changed: 55 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,12 @@ import ChatbotHeader from '@patternfly/chatbot/dist/dynamic/ChatbotHeader';
2323
import '@patternfly/chatbot/dist/css/main.css';
2424
```
2525

26+
Named imports from the root barrel also tree-shake with modern bundlers:
27+
28+
```tsx
29+
import { ChatbotToggle } from '@patternfly/chatbot';
30+
```
31+
2632
Sub-components can be imported from the same entry point:
2733

2834
```tsx
@@ -32,30 +38,33 @@ import ChatbotHeader, {
3238
} from '@patternfly/chatbot/dist/dynamic/ChatbotHeader';
3339
```
3440

41+
Per-component `dist/dynamic` imports are preferred for faster builds and for components excluded from the root barrel (`CodeModal`, `PreviewAttachment`, `AttachmentEdit`).
42+
3543
## What to avoid
3644

37-
Do **not** import from the package root:
45+
Do **not** use wildcard imports from the package root:
3846

3947
```tsx
40-
// Avoid — pulls in the entire component barrel
41-
import { ChatbotToggle } from '@patternfly/chatbot';
48+
// Avoid — may pull in the entire library
49+
import * as Chatbot from '@patternfly/chatbot';
4250
```
4351

44-
The root `index.js` re-exports every ChatBot component. Bundlers cannot eliminate unused exports from this autogenerated barrel, so your bundle will include components you never render.
45-
4652
## Icon imports
4753

48-
ChatBot source code imports icons individually from deep paths so they tree-shake correctly:
54+
Which PatternFly icons end up in your bundle depends on **which ChatBot components you import**, not on whether those components use deep or barrel icon paths internally. Importing `ChatbotToggle` from its subpath includes only the icons that component uses — currently four icons in the tree-shaking demo.
55+
56+
ChatBot source code uses deep-path icon imports as a defensive convention:
4957

5058
```tsx
5159
import PaperPlaneIcon from '@patternfly/react-icons/dist/esm/icons/paper-plane-icon';
5260
```
5361

54-
In your own application code, follow the same pattern. Avoid importing from the `@patternfly/react-icons` barrel:
62+
Deep paths improve **build performance** (less barrel resolution) and work reliably across bundler configurations. They do not meaningfully change **runtime bundle size** compared to named barrel imports when using modern bundlers, because `@patternfly/react-icons` declares `sideEffects: false`.
63+
64+
In your own application code, deep paths are still recommended:
5565

5666
```tsx
57-
// Avoid — may prevent icon tree-shaking
58-
import { PaperPlaneIcon } from '@patternfly/react-icons';
67+
import PaperPlaneIcon from '@patternfly/react-icons/dist/esm/icons/paper-plane-icon';
5968
```
6069

6170
## PatternFly component imports
@@ -86,7 +95,7 @@ import '@patternfly/chatbot/monaco-environment';
8695
import PreviewAttachment from '@patternfly/chatbot/dist/dynamic/PreviewAttachment';
8796
```
8897

89-
`CodeModal`, `PreviewAttachment`, and `AttachmentEdit` are excluded from the root barrel so Monaco stays out of bundles that do not use attachment editing. Import them from dynamic entry points:
98+
`CodeModal`, `PreviewAttachment`, and `AttachmentEdit` are excluded from the root barrel so Monaco stays out of root-barrel bundles. Import them from dynamic entry points:
9099

91100
```tsx
92101
import PreviewAttachment from '@patternfly/chatbot/dist/dynamic/PreviewAttachment';
@@ -95,9 +104,28 @@ import AttachmentEdit from '@patternfly/chatbot/dist/dynamic/AttachmentEdit';
95104

96105
`monaco-editor` and `@monaco-editor/react` are peer dependencies when you use these components.
97106

107+
## Migration: root barrel changes
108+
109+
The following modules are **not** re-exported from the root barrel (`@patternfly/chatbot`). They were removed so Monaco and internal utilities stay out of default bundles. Update existing root imports to subpath entry points:
110+
111+
| Module | Before (no longer works) | After |
112+
|--------|--------------------------|-------|
113+
| `CodeModal` | `import { CodeModal } from '@patternfly/chatbot'` | `import CodeModal from '@patternfly/chatbot/dist/dynamic/CodeModal'` |
114+
| `PreviewAttachment` | `import { PreviewAttachment } from '@patternfly/chatbot'` | `import PreviewAttachment from '@patternfly/chatbot/dist/dynamic/PreviewAttachment'` |
115+
| `AttachmentEdit` | `import { AttachmentEdit } from '@patternfly/chatbot'` | `import AttachmentEdit from '@patternfly/chatbot/dist/dynamic/AttachmentEdit'` |
116+
| `tracking` | `import { getTrackingProviders } from '@patternfly/chatbot'` | `import { getTrackingProviders } from '@patternfly/chatbot/dist/dynamic/tracking'` |
117+
118+
All other components remain available from the root barrel and continue to tree-shake when your bundler respects the package `sideEffects` field.
119+
120+
When using `CodeModal`, `PreviewAttachment`, or `AttachmentEdit`, also import the Monaco worker helper once at application startup:
121+
122+
```tsx
123+
import '@patternfly/chatbot/monaco-environment';
124+
```
125+
98126
## Verify tree-shaking in your project
99127

100-
The repository includes a tree-shaking demo at `packages/tree-shaking-demo/` that builds three scenarios and compares bundle size, icon count, and component count:
128+
The repository includes a tree-shaking demo at `packages/tree-shaking-demo/` that builds four scenarios and compares bundle size, icon count, and component count:
101129

102130
```bash
103131
npm run build -w @patternfly/chatbot
@@ -106,9 +134,22 @@ npm run analyze:tree-shaking
106134

107135
Open the generated `dist/<scenario>/stats.html` files for interactive bundle visualizations.
108136

137+
Example results from the demo (Vite 6):
138+
139+
| Scenario | JS size | Icons | ChatBot components |
140+
|----------|---------|-------|--------------------|
141+
| `ChatbotToggle` via `dist/dynamic` (source alias) | ~184 KB | 4 | 1 |
142+
| `ChatbotToggle` via root barrel (source alias) | ~184 KB | 4 | 1 |
143+
| `ChatbotToggle` via published package (no alias) | ~184 KB | 4 | 1 |
144+
| Multi-component UI (7 imports) | ~895 KB | 49 | 17 |
145+
146+
The **published** scenario resolves `@patternfly/chatbot` through `package.json` `exports` and `dist/` with no monorepo source alias, matching how npm consumers resolve the package.
147+
109148
## How ChatBot supports tree-shaking
110149

111150
- **ESM output** with a `module` field pointing to `dist/esm/`
112-
- **Per-component entry points** at `dist/dynamic/<Component>/`
113-
- **Deep icon imports** in library source code
114-
- **`exports`** field maps public subpaths (`dist/dynamic/*`, `dist/css/main.css`, `monaco-environment`) for bundler-friendly resolution
151+
- **`sideEffects`** in `package.json` so bundlers can drop unused re-exports from the root barrel while preserving CSS and the documentation-site style entry (`patternfly-docs/**`)
152+
- **Per-component dynamic entry points** at `dist/dynamic/<Component>/`
153+
- **Unbundled compilation** — icons and dependencies remain as external imports for your bundler to resolve
154+
- **`exports`** field maps public subpaths for bundler-friendly resolution
155+
- **Explicit CSS imports** (see above)

packages/module/patternfly-docs/patternfly-docs.css.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
// The docs framework aliases this file as the global client entry (client-styles), so
44
// side-effect imports belong here even though the filename suggests CSS only.
55
// Uses patternfly-docs/monaco-environment.js (monorepo node_modules paths), not the package export.
6+
// This file must stay side-effectful — see package.json "sideEffects" ("patternfly-docs/**").
67
import './monaco-environment.js';
78
import '@patternfly/patternfly/patternfly.css';
89
// Patternfly utilities

packages/module/src/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.test.tsx

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,7 @@ import { fireEvent, render, screen, waitFor } from '@testing-library/react';
44
import { ChatbotDisplayMode } from '../Chatbot/Chatbot';
55
import ChatbotConversationHistoryNav, { Conversation, ConversationGroup } from './ChatbotConversationHistoryNav';
66
import { EmptyStateStatus, Spinner, MenuItem } from '@patternfly/react-core';
7-
import { BellIcon } from '@patternfly/react-icons/dist/esm/icons/bell-icon';
8-
import { OutlinedCommentsIcon } from '@patternfly/react-icons/dist/esm/icons/outlined-comments-icon';
9-
import { SearchIcon } from '@patternfly/react-icons/dist/esm/icons/search-icon';
7+
import { BellIcon, OutlinedCommentsIcon, SearchIcon } from '@patternfly/react-icons';
108
import { ComponentType, useState } from 'react';
119

1210
const ERROR = {

packages/module/src/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.tsx

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,7 @@ import {
4949
ExpandableSectionToggleProps
5050
} from '@patternfly/react-core';
5151

52-
import { RhUiClockIcon } from '@patternfly/react-icons/dist/esm/icons/rh-ui-clock-icon';
53-
import { RhUiCommentIcon } from '@patternfly/react-icons/dist/esm/icons/rh-ui-comment-icon';
54-
import { RhUiEditFillIcon } from '@patternfly/react-icons/dist/esm/icons/rh-ui-edit-fill-icon';
52+
import { RhUiClockIcon, RhUiCommentIcon, RhUiEditFillIcon } from '@patternfly/react-icons';
5553
import { ChatbotDisplayMode } from '../Chatbot/Chatbot';
5654
import ConversationHistoryDropdown from './ChatbotConversationHistoryDropdown';
5755
import LoadingState from './LoadingState';

packages/module/src/ChatbotHeader/ChatbotHeaderCloseButton.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import type { Ref, FunctionComponent } from 'react';
22
import { forwardRef } from 'react';
33

44
import { Button, ButtonProps, Icon, Tooltip, TooltipProps } from '@patternfly/react-core';
5-
import { RhMicronsCloseIcon } from '@patternfly/react-icons/dist/esm/icons/rh-microns-close-icon';
5+
import { RhMicronsCloseIcon } from '@patternfly/react-icons';
66

77
export interface ChatbotHeaderCloseButtonProps extends ButtonProps {
88
/** Callback function for when button is clicked */

packages/module/src/FileDetailsLabel/FileDetailsLabel.test.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { render, screen } from '@testing-library/react';
22
import '@testing-library/jest-dom';
33
import FileDetailsLabel from './FileDetailsLabel';
44
import userEvent from '@testing-library/user-event';
5-
import { BellIcon } from '@patternfly/react-icons/dist/esm/icons/bell-icon';
5+
import { BellIcon } from '@patternfly/react-icons';
66

77
describe('FileDetailsLabel', () => {
88
it('should render file details label', () => {

packages/module/src/FileDetailsLabel/FileDetailsLabel.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { PropsWithChildren } from 'react';
22
import { Button, Label, LabelProps } from '@patternfly/react-core';
33
import FileDetails from '../FileDetails';
44
import { Spinner } from '@patternfly/react-core';
5-
import { RhMicronsCloseIcon } from '@patternfly/react-icons/dist/esm/icons/rh-microns-close-icon';
5+
import { RhMicronsCloseIcon } from '@patternfly/react-icons';
66

77
export interface FileDetailsLabelProps extends Omit<LabelProps, 'onClose' | 'onClick'> {
88
/** Name of file, including extension */

packages/module/src/FileDropZone/FileDropZone.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { MultipleFileUpload, MultipleFileUploadMain } from '@patternfly/react-co
22
import type { FunctionComponent } from 'react';
33
import { useState } from 'react';
44
import { ChatbotDisplayMode } from '../Chatbot';
5-
import { RhUiUploadIcon } from '@patternfly/react-icons/dist/esm/icons/rh-ui-upload-icon';
5+
import { RhUiUploadIcon } from '@patternfly/react-icons';
66
import { Accept, DropEvent, FileError, FileRejection } from 'react-dropzone';
77

88
export interface FileDropZoneProps {

0 commit comments

Comments
 (0)