Skip to content

Commit 2618a6d

Browse files
committed
feat(docs): add tree-shaking analysis for @codefast/ui package
Added a detailed analysis to the documentation addressing tree-shaking effectiveness for the `@codefast/ui` package. The document outlines current limitations, optimization recommendations, and expected impact on bundle size and import efficiency, prioritizing backward compatibility while improving selective import usage.
1 parent e79af58 commit 2618a6d

File tree

1 file changed

+167
-0
lines changed

1 file changed

+167
-0
lines changed

docs/tree-shaking-analysis.md

Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
# Tree-shaking Analysis for @codefast/ui Package
2+
3+
## Current State Analysis
4+
5+
### ✅ Positive Aspects for Tree-shaking
6+
7+
1. **Package Configuration**:
8+
- `"sideEffects": false` - Correctly configured
9+
- `"type": "module"` - Uses ES modules
10+
- Proper `exports` field with ESM/CJS support
11+
- `bundle: false` in rslib.config.ts - Preserves modular structure
12+
13+
2. **Build Output**:
14+
- Individual component files are preserved (1-20KB each)
15+
- Modular directory structure maintained in dist/
16+
- Both ESM and CJS formats generated
17+
18+
### ❌ Tree-shaking Issues Identified
19+
20+
1. **Three-Level Barrel Export Chain**:
21+
```
22+
src/index.ts (572 lines)
23+
↓ imports from @/components
24+
src/components/index.ts (616 lines)
25+
↓ imports from individual components
26+
component/index.ts
27+
↓ imports from actual component files
28+
```
29+
30+
2. **Main Entry Point Problems**:
31+
- `dist/esm/index.js`: 11KB minified single line with all imports
32+
- `dist/esm/components/index.js`: 14KB barrel export
33+
- Single entry point in package.json exports field
34+
35+
3. **Bundle Size Impact**:
36+
- Total package size: 488.2KB
37+
- Main index files create large import graphs
38+
- Importing single component may pull in references to all components
39+
40+
## Tree-shaking Effectiveness Test
41+
42+
When importing `import { Button } from '@codefast/ui'`:
43+
- Bundler must process the entire 11KB index.js file
44+
- File contains references to all ~60+ components
45+
- Even with tree-shaking, the import graph is unnecessarily large
46+
47+
## Recommendations for Improvement
48+
49+
### 1. **Individual Component Exports** (Recommended)
50+
Add individual component exports to package.json:
51+
52+
```json
53+
{
54+
"exports": {
55+
".": {
56+
"import": "./dist/esm/index.js",
57+
"require": "./dist/cjs/index.cjs"
58+
},
59+
"./button": {
60+
"import": "./dist/esm/components/button/index.js",
61+
"require": "./dist/cjs/components/button/index.cjs"
62+
},
63+
"./accordion": {
64+
"import": "./dist/esm/components/accordion/index.js",
65+
"require": "./dist/cjs/components/accordion/index.cjs"
66+
},
67+
"./styles.css": "./dist/styles/index.css"
68+
}
69+
}
70+
```
71+
72+
### 2. **Remove Barrel Export Layers**
73+
- Keep individual component index.ts files
74+
- Remove or minimize src/components/index.ts
75+
- Consider making src/index.ts optional for backward compatibility
76+
77+
### 3. **Build Configuration Optimization**
78+
Update rslib.config.ts to generate individual entry points:
79+
80+
```typescript
81+
export default defineConfig({
82+
lib: [
83+
// Main entry (for backward compatibility)
84+
{
85+
bundle: false,
86+
dts: true,
87+
format: "esm",
88+
output: { distPath: { root: "./dist/esm" } }
89+
},
90+
// Individual component entries
91+
{
92+
bundle: false,
93+
dts: true,
94+
format: "esm",
95+
output: { distPath: { root: "./dist/esm" } }
96+
}
97+
],
98+
source: {
99+
entry: {
100+
index: "./src/index.ts",
101+
"components/button/index": "./src/components/button/index.ts",
102+
"components/accordion/index": "./src/components/accordion/index.ts"
103+
}
104+
}
105+
});
106+
```
107+
108+
### 4. **Documentation Updates**
109+
Update documentation to encourage individual imports:
110+
111+
```typescript
112+
// ❌ Avoid (pulls entire barrel export)
113+
import { Button, Accordion } from '@codefast/ui';
114+
115+
// ✅ Prefer (optimal tree-shaking)
116+
import { Button } from '@codefast/ui/button';
117+
import { Accordion } from '@codefast/ui/accordion';
118+
```
119+
120+
### 5. **Automated Export Generation**
121+
Create a script to automatically generate the exports field based on available components:
122+
123+
```javascript
124+
// scripts/generate-exports.js
125+
const fs = require('fs');
126+
const path = require('path');
127+
128+
const componentsDir = './src/components';
129+
const components = fs.readdirSync(componentsDir);
130+
131+
const exports = {
132+
".": {
133+
"import": "./dist/esm/index.js",
134+
"require": "./dist/cjs/index.cjs"
135+
}
136+
};
137+
138+
components.forEach(component => {
139+
exports[`./${component}`] = {
140+
"import": `./dist/esm/components/${component}/index.js`,
141+
"require": `./dist/cjs/components/${component}/index.cjs`
142+
};
143+
});
144+
145+
// Update package.json
146+
```
147+
148+
## Expected Impact
149+
150+
### Before Optimization:
151+
- Single component import: ~11KB+ initial processing
152+
- Bundle includes references to all components
153+
- Suboptimal tree-shaking effectiveness
154+
155+
### After Optimization:
156+
- Single component import: ~1-5KB processing
157+
- Bundle includes only required component
158+
- Optimal tree-shaking effectiveness
159+
- Estimated 60-80% reduction in bundle size for selective imports
160+
161+
## Implementation Priority
162+
163+
1. **High Priority**: Add individual component exports to package.json
164+
2. **Medium Priority**: Update build configuration for individual entries
165+
3. **Low Priority**: Remove barrel export layers (breaking change)
166+
167+
This approach maintains backward compatibility while providing optimal tree-shaking for new usage patterns.

0 commit comments

Comments
 (0)