Skip to content

Commit dbb34fc

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

32 files changed

Lines changed: 197 additions & 215 deletions

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: 49 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,12 @@ Import each component from its dynamic entry point:
2020
```tsx
2121
import ChatbotToggle from '@patternfly/chatbot/dist/dynamic/ChatbotToggle';
2222
import ChatbotHeader from '@patternfly/chatbot/dist/dynamic/ChatbotHeader';
23-
import '@patternfly/chatbot/dist/css/main.css';
23+
```
24+
25+
Named imports from the root barrel also tree-shake with modern bundlers:
26+
27+
```tsx
28+
import { ChatbotToggle } from '@patternfly/chatbot';
2429
```
2530

2631
Sub-components can be imported from the same entry point:
@@ -32,40 +37,20 @@ import ChatbotHeader, {
3237
} from '@patternfly/chatbot/dist/dynamic/ChatbotHeader';
3338
```
3439

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

37-
Do **not** import from the package root:
44+
Do **not** use wildcard imports from the package root:
3845

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

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-
4651
## Icon imports
4752

48-
ChatBot source code imports icons individually from deep paths so they tree-shake correctly:
49-
50-
```tsx
51-
import PaperPlaneIcon from '@patternfly/react-icons/dist/esm/icons/paper-plane-icon';
52-
```
53-
54-
In your own application code, follow the same pattern. Avoid importing from the `@patternfly/react-icons` barrel:
55-
56-
```tsx
57-
// Avoid — may prevent icon tree-shaking
58-
import { PaperPlaneIcon } from '@patternfly/react-icons';
59-
```
60-
61-
## PatternFly component imports
62-
63-
When importing PatternFly components alongside ChatBot, prefer dynamic entry points:
64-
65-
```tsx
66-
import { Button } from '@patternfly/react-core/dist/dynamic/Button';
67-
import { Stack } from '@patternfly/react-core/dist/dynamic/Stack';
68-
```
53+
Which PatternFly icons end up in your bundle depends on **which ChatBot components you import**, not on whether ChatBot source code or your app uses barrel or deep icon paths. Importing `ChatbotToggle` via `dist/dynamic` includes only the icons that component uses — currently four icons in the tree-shaking demo.
6954

7055
## CSS import
7156

@@ -86,7 +71,7 @@ import '@patternfly/chatbot/monaco-environment';
8671
import PreviewAttachment from '@patternfly/chatbot/dist/dynamic/PreviewAttachment';
8772
```
8873

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:
74+
`CodeModal`, `PreviewAttachment`, and `AttachmentEdit` are excluded from the root barrel so Monaco stays out of root-barrel bundles. Import them from dynamic entry points:
9075

9176
```tsx
9277
import PreviewAttachment from '@patternfly/chatbot/dist/dynamic/PreviewAttachment';
@@ -95,9 +80,28 @@ import AttachmentEdit from '@patternfly/chatbot/dist/dynamic/AttachmentEdit';
9580

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

83+
## Migration: root barrel changes
84+
85+
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:
86+
87+
| Module | Before (no longer works) | After |
88+
|--------|--------------------------|-------|
89+
| `CodeModal` | `import { CodeModal } from '@patternfly/chatbot'` | `import CodeModal from '@patternfly/chatbot/dist/dynamic/CodeModal'` |
90+
| `PreviewAttachment` | `import { PreviewAttachment } from '@patternfly/chatbot'` | `import PreviewAttachment from '@patternfly/chatbot/dist/dynamic/PreviewAttachment'` |
91+
| `AttachmentEdit` | `import { AttachmentEdit } from '@patternfly/chatbot'` | `import AttachmentEdit from '@patternfly/chatbot/dist/dynamic/AttachmentEdit'` |
92+
| `tracking` | `import { getTrackingProviders } from '@patternfly/chatbot'` | `import { getTrackingProviders } from '@patternfly/chatbot/dist/dynamic/tracking'` |
93+
94+
All other components remain available from the root barrel and continue to tree-shake when your bundler respects the package `sideEffects` field.
95+
96+
When using `CodeModal`, `PreviewAttachment`, or `AttachmentEdit`, also import the Monaco worker helper once at application startup:
97+
98+
```tsx
99+
import '@patternfly/chatbot/monaco-environment';
100+
```
101+
98102
## Verify tree-shaking in your project
99103

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:
104+
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:
101105

102106
```bash
103107
npm run build -w @patternfly/chatbot
@@ -106,9 +110,22 @@ npm run analyze:tree-shaking
106110

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

113+
Example results from the demo (Vite 6):
114+
115+
| Scenario | JS size | Icons | ChatBot components |
116+
|----------|---------|-------|--------------------|
117+
| `ChatbotToggle` via `dist/dynamic` (source alias) | ~184 KB | 4 | 1 |
118+
| `ChatbotToggle` via root barrel (source alias) | ~184 KB | 4 | 1 |
119+
| `ChatbotToggle` via published package (no alias) | ~184 KB | 4 | 1 |
120+
| Multi-component UI (7 imports) | ~895 KB | 49 | 17 |
121+
122+
The **published** scenario resolves `@patternfly/chatbot` through `package.json` `exports` and `dist/` with no monorepo source alias, matching how npm consumers resolve the package.
123+
109124
## How ChatBot supports tree-shaking
110125

111126
- **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
127+
- **`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/**`)
128+
- **Per-component dynamic entry points** at `dist/dynamic/<Component>/`
129+
- **Unbundled compilation** — icons and dependencies remain as external imports for your bundler to resolve
130+
- **`exports`** field maps public subpaths for bundler-friendly resolution
131+
- **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)