igniteui-cli 14.10.0-alpha.2 → 14.10.0-alpha.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,709 @@
1
+ ---
2
+ name: igniteui-wc-optimize-bundle-size
3
+ description: Optimize application bundle size by importing only necessary components and using tree-shaking effectively
4
+ user-invocable: true
5
+ ---
6
+
7
+ # Optimize Bundle Size
8
+
9
+ This skill helps users minimize their application's bundle size when using Ignite UI Web Components by importing only the components they need and following best practices for tree-shaking.
10
+
11
+ ## Example Usage
12
+
13
+ - "My bundle size is too large"
14
+ - "How do I reduce the size of igniteui-webcomponents?"
15
+ - "Import only the components I need"
16
+ - "Tree-shake unused components"
17
+ - "Optimize imports for production"
18
+
19
+ ## Related Skills
20
+
21
+ - [igniteui-wc-integrate-with-framework](../igniteui-wc-integrate-with-framework/SKILL.md) - Proper integration setup
22
+ - [igniteui-wc-customize-component-theme](../igniteui-wc-customize-component-theme/SKILL.md) - Theming after optimization
23
+
24
+ ## When to Use
25
+
26
+ - User's bundle size is too large
27
+ - User wants to optimize for production
28
+ - User is importing more components than needed
29
+ - User asks about tree-shaking or optimization
30
+ - User wants to improve load times
31
+
32
+ ## Key Principles
33
+
34
+ 1. **Import only what you use** - Don't use `defineAllComponents()`
35
+ 2. **Use named imports** - Enable tree-shaking
36
+ 3. **Analyze your bundle** - Identify what's being included
37
+ 4. **Lazy load when possible** - Load components on demand
38
+
39
+ ## Import Strategies
40
+
41
+ ### ❌ Bad: Import Everything
42
+
43
+ ```typescript
44
+ // DON'T DO THIS - imports ALL components (~500KB+)
45
+ import { defineAllComponents } from 'igniteui-webcomponents';
46
+
47
+ defineAllComponents();
48
+ ```
49
+
50
+ **Impact:** Includes all 60+ components whether you use them or not.
51
+
52
+ ### ✅ Good: Import Specific Components
53
+
54
+ ```typescript
55
+ // DO THIS - import only what you need
56
+ import {
57
+ defineComponents,
58
+ IgcButtonComponent,
59
+ IgcInputComponent,
60
+ IgcCardComponent
61
+ } from 'igniteui-webcomponents';
62
+
63
+ defineComponents(IgcButtonComponent, IgcInputComponent, IgcCardComponent);
64
+ ```
65
+
66
+ **Impact:** Bundle includes only 3 components and their dependencies.
67
+
68
+ ## React Applications
69
+
70
+ If you're using React, consider using the **`igniteui-react`** package instead of `igniteui-webcomponents`. It provides the same components with React-friendly wrappers and typically results in better tree-shaking:
71
+
72
+ ```bash
73
+ npm install igniteui-react
74
+ ```
75
+
76
+ ```tsx
77
+ import { IgrButton, IgrInput, IgrCard } from 'igniteui-react';
78
+
79
+ // No need to call defineComponents - components register automatically
80
+ function MyComponent() {
81
+ return (
82
+ <div>
83
+ <IgrButton variant="contained">Click me</IgrButton>
84
+ <IgrInput label="Name" />
85
+ <IgrCard>Content</IgrCard>
86
+ </div>
87
+ );
88
+ }
89
+ ```
90
+
91
+ **Benefits for bundle size:**
92
+ - Automatic tree-shaking (only imported components are included)
93
+ - No need for component registration overhead
94
+ - Better integration with React build tools
95
+
96
+ For more details, see the [igniteui-wc-integrate-with-framework](../igniteui-wc-integrate-with-framework/SKILL.md) skill.
97
+
98
+ ## Analyzing Your Bundle
99
+
100
+ ### Using Webpack Bundle Analyzer
101
+
102
+ **Installation:**
103
+
104
+ ```bash
105
+ npm install --save-dev webpack-bundle-analyzer
106
+ ```
107
+
108
+ **Configuration (`webpack.config.js`):**
109
+
110
+ ```javascript
111
+ const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer');
112
+
113
+ module.exports = {
114
+ plugins: [
115
+ new BundleAnalyzerPlugin({
116
+ analyzerMode: 'static',
117
+ openAnalyzer: false,
118
+ reportFilename: 'bundle-report.html'
119
+ })
120
+ ]
121
+ };
122
+ ```
123
+
124
+ **Run analysis:**
125
+
126
+ ```bash
127
+ npm run build
128
+ # Open bundle-report.html to see what's included
129
+ ```
130
+
131
+ ### Using Vite Bundle Analyzer
132
+
133
+ **Installation:**
134
+
135
+ ```bash
136
+ npm install --save-dev rollup-plugin-visualizer
137
+ ```
138
+
139
+ **Configuration (`vite.config.ts`):**
140
+
141
+ ```typescript
142
+ import { defineConfig } from 'vite';
143
+ import { visualizer } from 'rollup-plugin-visualizer';
144
+
145
+ export default defineConfig({
146
+ plugins: [
147
+ visualizer({
148
+ open: true,
149
+ gzipSize: true,
150
+ brotliSize: true,
151
+ })
152
+ ]
153
+ });
154
+ ```
155
+
156
+ **Run analysis:**
157
+
158
+ ```bash
159
+ npm run build
160
+ # Opens stats.html automatically
161
+ ```
162
+
163
+ ### Using source-map-explorer
164
+
165
+ **Installation:**
166
+
167
+ ```bash
168
+ npm install --save-dev source-map-explorer
169
+ ```
170
+
171
+ **Package.json:**
172
+
173
+ ```json
174
+ {
175
+ "scripts": {
176
+ "analyze": "source-map-explorer 'dist/**/*.js'"
177
+ }
178
+ }
179
+ ```
180
+
181
+ **Run:**
182
+
183
+ ```bash
184
+ npm run build
185
+ npm run analyze
186
+ ```
187
+
188
+ ## Audit Your Component Usage
189
+
190
+ ### 1. Find What Components You're Actually Using
191
+
192
+ Search your codebase for component usage:
193
+
194
+ ```bash
195
+ # Search for component tags in templates
196
+ grep -r "igc-" src/ --include="*.html" --include="*.tsx" --include="*.vue"
197
+
198
+ # List unique components
199
+ grep -roh "igc-[a-z-]*" src/ | sort | uniq
200
+ ```
201
+
202
+ ### 2. Compare with Your Imports
203
+
204
+ Check what you're importing vs what you're using:
205
+
206
+ ```typescript
207
+ // Find in your code
208
+ import {
209
+ defineComponents,
210
+ IgcButtonComponent,
211
+ IgcInputComponent,
212
+ IgcCardComponent,
213
+ IgcSelectComponent, // ← Are you using this?
214
+ IgcComboComponent, // ← Are you using this?
215
+ } from 'igniteui-webcomponents';
216
+ ```
217
+
218
+ ### 3. Remove Unused Imports
219
+
220
+ Remove components you're not using:
221
+
222
+ ```typescript
223
+ // Before: 5 components imported
224
+ import {
225
+ defineComponents,
226
+ IgcButtonComponent,
227
+ IgcInputComponent,
228
+ IgcCardComponent,
229
+ IgcSelectComponent,
230
+ IgcComboComponent,
231
+ } from 'igniteui-webcomponents';
232
+
233
+ defineComponents(
234
+ IgcButtonComponent,
235
+ IgcInputComponent,
236
+ IgcCardComponent,
237
+ IgcSelectComponent,
238
+ IgcComboComponent
239
+ );
240
+
241
+ // After: Only 3 components needed
242
+ import {
243
+ defineComponents,
244
+ IgcButtonComponent,
245
+ IgcInputComponent,
246
+ IgcCardComponent,
247
+ } from 'igniteui-webcomponents';
248
+
249
+ defineComponents(IgcButtonComponent, IgcInputComponent, IgcCardComponent);
250
+ ```
251
+
252
+ ## Lazy Loading Components
253
+
254
+ Load components only when needed to reduce initial bundle size.
255
+
256
+ ### Vanilla JavaScript / TypeScript
257
+
258
+ ```typescript
259
+ // Load immediately (increases initial bundle)
260
+ import { defineComponents, IgcDialogComponent } from 'igniteui-webcomponents';
261
+ defineComponents(IgcDialogComponent);
262
+
263
+ // Lazy load (smaller initial bundle)
264
+ async function showDialog() {
265
+ const { defineComponents, IgcDialogComponent } = await import('igniteui-webcomponents');
266
+ defineComponents(IgcDialogComponent);
267
+
268
+ const dialog = document.createElement('igc-dialog');
269
+ // ... use dialog
270
+ }
271
+ ```
272
+
273
+ ### React (using igniteui-react)
274
+
275
+ ```tsx
276
+ import React, { lazy, Suspense, useState } from 'react';
277
+
278
+ // Lazy load the dialog component
279
+ const IgrDialog = lazy(() =>
280
+ import('igniteui-react').then(module => ({ default: module.IgrDialog }))
281
+ );
282
+
283
+ function MyComponent() {
284
+ const [showDialog, setShowDialog] = useState(false);
285
+
286
+ return (
287
+ <>
288
+ <button onClick={() => setShowDialog(true)}>Open Dialog</button>
289
+ {showDialog && (
290
+ <Suspense fallback={<div>Loading...</div>}>
291
+ <IgrDialog open>
292
+ <h2>Dialog Content</h2>
293
+ </IgrDialog>
294
+ </Suspense>
295
+ )}
296
+ </>
297
+ );
298
+ }
299
+ ```
300
+
301
+ ### React (using web components directly)
302
+
303
+ ```tsx
304
+ import React, { useState } from 'react';
305
+
306
+ // Lazy load component registration
307
+ const lazyLoadDialog = async () => {
308
+ const { defineComponents, IgcDialogComponent } = await import('igniteui-webcomponents');
309
+ defineComponents(IgcDialogComponent);
310
+ };
311
+
312
+ function MyComponent() {
313
+ const [dialogReady, setDialogReady] = useState(false);
314
+
315
+ const openDialog = async () => {
316
+ if (!dialogReady) {
317
+ await lazyLoadDialog();
318
+ setDialogReady(true);
319
+ }
320
+ // Show dialog
321
+ };
322
+
323
+ return (
324
+ <button onClick={openDialog}>Open Dialog</button>
325
+ );
326
+ }
327
+ ```
328
+
329
+ ### Vue 3
330
+
331
+ ```vue
332
+ <script setup lang="ts">
333
+ import { ref } from 'vue';
334
+
335
+ const dialogReady = ref(false);
336
+
337
+ async function openDialog() {
338
+ if (!dialogReady.value) {
339
+ const { defineComponents, IgcDialogComponent } = await import('igniteui-webcomponents');
340
+ defineComponents(IgcDialogComponent);
341
+ dialogReady.value = true;
342
+ }
343
+ // Show dialog
344
+ }
345
+ </script>
346
+
347
+ <template>
348
+ <button @click="openDialog">Open Dialog</button>
349
+ <igc-dialog v-if="dialogReady" open>
350
+ <h2>Dialog Content</h2>
351
+ </igc-dialog>
352
+ </template>
353
+ ```
354
+
355
+ ### Angular
356
+
357
+ ```typescript
358
+ import { Component } from '@angular/core';
359
+
360
+ @Component({
361
+ selector: 'app-my-component',
362
+ template: `
363
+ <button (click)="openDialog()">Open Dialog</button>
364
+ <igc-dialog *ngIf="dialogReady" [open]="true">
365
+ <h2>Dialog Content</h2>
366
+ </igc-dialog>
367
+ `
368
+ })
369
+ export class MyComponent {
370
+ dialogReady = false;
371
+
372
+ async openDialog() {
373
+ if (!this.dialogReady) {
374
+ const { defineComponents, IgcDialogComponent } = await import('igniteui-webcomponents');
375
+ defineComponents(IgcDialogComponent);
376
+ this.dialogReady = true;
377
+ }
378
+ }
379
+ }
380
+ ```
381
+
382
+ ## Route-Based Code Splitting
383
+
384
+ Load components only for specific routes.
385
+
386
+ ### React Router
387
+
388
+ ```tsx
389
+ import { BrowserRouter, Routes, Route } from 'react-router-dom';
390
+ import { lazy, Suspense } from 'react';
391
+
392
+ // Lazy load route components
393
+ const HomePage = lazy(() => import('./pages/Home'));
394
+ const DashboardPage = lazy(() => import('./pages/Dashboard'));
395
+
396
+ function App() {
397
+ return (
398
+ <BrowserRouter>
399
+ <Suspense fallback={<div>Loading...</div>}>
400
+ <Routes>
401
+ <Route path="/" element={<HomePage />} />
402
+ <Route path="/dashboard" element={<DashboardPage />} />
403
+ </Routes>
404
+ </Suspense>
405
+ </BrowserRouter>
406
+ );
407
+ }
408
+ ```
409
+
410
+ **In route component (`pages/Dashboard.tsx`):**
411
+
412
+ ```tsx
413
+ import { IgrCard, IgrButton } from 'igniteui-react';
414
+
415
+ function Dashboard() {
416
+ return (
417
+ <div>
418
+ <IgrCard>
419
+ <h2>Dashboard</h2>
420
+ <p>Dashboard content here</p>
421
+ </IgrCard>
422
+ </div>
423
+ );
424
+ }
425
+ ```
426
+
427
+ ### Vue Router
428
+
429
+ ```typescript
430
+ // router/index.ts
431
+ import { createRouter, createWebHistory } from 'vue-router';
432
+
433
+ const routes = [
434
+ {
435
+ path: '/',
436
+ component: () => import('../views/Home.vue') // Lazy load
437
+ },
438
+ {
439
+ path: '/dashboard',
440
+ component: () => import('../views/Dashboard.vue') // Lazy load
441
+ }
442
+ ];
443
+
444
+ export default createRouter({
445
+ history: createWebHistory(),
446
+ routes
447
+ });
448
+ ```
449
+
450
+ **In route component (`views/Dashboard.vue`):**
451
+
452
+ ```vue
453
+ <script setup lang="ts">
454
+ import { onMounted } from 'vue';
455
+
456
+ onMounted(async () => {
457
+ // Load components only for this route
458
+ const { defineComponents, IgcCardComponent } = await import('igniteui-webcomponents');
459
+ defineComponents(IgcCardComponent);
460
+ });
461
+ </script>
462
+ ```
463
+
464
+ ### Angular
465
+
466
+ ```typescript
467
+ // app-routing.module.ts
468
+ import { NgModule } from '@angular/core';
469
+ import { RouterModule, Routes } from '@angular/router';
470
+
471
+ const routes: Routes = [
472
+ {
473
+ path: 'dashboard',
474
+ loadChildren: () => import('./dashboard/dashboard.module').then(m => m.DashboardModule)
475
+ }
476
+ ];
477
+
478
+ @NgModule({
479
+ imports: [RouterModule.forRoot(routes)],
480
+ exports: [RouterModule]
481
+ })
482
+ export class AppRoutingModule {}
483
+ ```
484
+
485
+ ## Build Configuration Optimizations
486
+
487
+ ### Vite Configuration
488
+
489
+ ```typescript
490
+ // vite.config.ts
491
+ import { defineConfig } from 'vite';
492
+
493
+ export default defineConfig({
494
+ build: {
495
+ // Enable minification
496
+ minify: 'terser',
497
+ terserOptions: {
498
+ compress: {
499
+ drop_console: true, // Remove console.logs
500
+ drop_debugger: true
501
+ }
502
+ },
503
+
504
+ // Optimize chunk splitting
505
+ rollupOptions: {
506
+ output: {
507
+ manualChunks: {
508
+ // Separate vendor chunks
509
+ 'vendor': ['igniteui-webcomponents'],
510
+ }
511
+ }
512
+ },
513
+
514
+ // Set chunk size warning limit
515
+ chunkSizeWarningLimit: 600,
516
+ },
517
+
518
+ // Optimize deps
519
+ optimizeDeps: {
520
+ include: ['igniteui-webcomponents']
521
+ }
522
+ });
523
+ ```
524
+
525
+ ### Webpack Configuration
526
+
527
+ ```javascript
528
+ // webpack.config.js
529
+ module.exports = {
530
+ optimization: {
531
+ splitChunks: {
532
+ chunks: 'all',
533
+ cacheGroups: {
534
+ vendor: {
535
+ test: /[\\/]node_modules[\\/]/,
536
+ name: 'vendors',
537
+ priority: 10,
538
+ },
539
+ igniteui: {
540
+ test: /[\\/]node_modules[\\/]igniteui-webcomponents[\\/]/,
541
+ name: 'igniteui',
542
+ priority: 20,
543
+ }
544
+ }
545
+ },
546
+ minimize: true,
547
+ },
548
+
549
+ // Tree shaking
550
+ mode: 'production',
551
+ };
552
+ ```
553
+
554
+ ## Size Comparison
555
+
556
+ Here's what you can expect in terms of bundle size:
557
+
558
+ | Import Strategy | Approximate Size (gzipped) | Components Included |
559
+ |----------------|---------------------------|---------------------|
560
+ | `defineAllComponents()` | ~500KB+ | All 60+ components |
561
+ | 10 components via `defineComponents()` | ~150-200KB | 10 components + deps |
562
+ | 5 components via `defineComponents()` | ~100-150KB | 5 components + deps |
563
+ | 3 components via `defineComponents()` | ~80-120KB | 3 components + deps |
564
+ | 1 component via `defineComponents()` | ~50-80KB | 1 component + deps |
565
+
566
+ **Note:** Sizes vary based on which components you import (some have more dependencies than others).
567
+
568
+ ## Best Practices Checklist
569
+
570
+ - [ ] **Never use `defineAllComponents()`** unless you truly need every component
571
+ - [ ] **Use `defineComponents()` with specific components** you need
572
+ - [ ] **Audit your imports regularly** - remove unused components
573
+ - [ ] **Lazy load rarely-used components** (dialogs, modals, etc.)
574
+ - [ ] **Split by routes** - load components only for active routes
575
+ - [ ] **Analyze your bundle** - use bundle analyzer tools
576
+ - [ ] **Enable tree-shaking** - use named imports, not side-effect imports
577
+ - [ ] **Minify in production** - ensure build tool minification is enabled
578
+ - [ ] **Use compression** - enable gzip/brotli on your server
579
+
580
+ ## Common Issues and Solutions
581
+
582
+ ### Issue: Bundle still large after following best practices
583
+
584
+ **Investigate:**
585
+
586
+ 1. Check if you're importing many components at once
587
+ 2. Verify tree-shaking is working (check build output)
588
+ 3. Look for duplicate dependencies
589
+ 4. Check if source maps are included in production
590
+ 5. For React, ensure you're using `igniteui-react` instead of `igniteui-webcomponents`
591
+
592
+ **Solutions:**
593
+
594
+ ```typescript
595
+ // Review your imports - are you using all of these?
596
+ import {
597
+ defineComponents,
598
+ IgcButtonComponent,
599
+ IgcInputComponent,
600
+ IgcSelectComponent,
601
+ IgcComboComponent,
602
+ IgcDatePickerComponent
603
+ } from 'igniteui-webcomponents';
604
+
605
+ // Consider lazy loading components you don't need immediately
606
+ async function loadDialog() {
607
+ const { defineComponents, IgcDialogComponent } = await import('igniteui-webcomponents');
608
+ defineComponents(IgcDialogComponent);
609
+ }
610
+ ```
611
+
612
+ ### Issue: Components not working after optimizing imports
613
+
614
+ **Cause:** Forgot to import a component you're using
615
+
616
+ **Solution:**
617
+
618
+ ```typescript
619
+ // Error: <igc-button> not working
620
+ // You're using igc-button but didn't import it
621
+
622
+ import { defineComponents, IgcButtonComponent } from 'igniteui-webcomponents';
623
+ defineComponents(IgcButtonComponent); // Add this
624
+ ```
625
+
626
+ ### Issue: TypeScript errors after changing imports
627
+
628
+ **Solution:** Update type imports:
629
+
630
+ ```typescript
631
+ // Import types separately if needed
632
+ import type { IgcButtonComponent } from 'igniteui-webcomponents';
633
+ ```
634
+
635
+ ## Monitoring Bundle Size
636
+
637
+ ### Set up bundle size monitoring in CI/CD
638
+
639
+ **Using bundlesize (for any build tool):**
640
+
641
+ ```bash
642
+ npm install --save-dev bundlesize
643
+ ```
644
+
645
+ **Package.json:**
646
+
647
+ ```json
648
+ {
649
+ "scripts": {
650
+ "test:size": "bundlesize"
651
+ },
652
+ "bundlesize": [
653
+ {
654
+ "path": "./dist/**/*.js",
655
+ "maxSize": "300 kB"
656
+ }
657
+ ]
658
+ }
659
+ ```
660
+
661
+ **Run in CI:**
662
+
663
+ ```bash
664
+ npm run build
665
+ npm run test:size
666
+ ```
667
+
668
+ ### GitHub Actions Example
669
+
670
+ ```yaml
671
+ name: Bundle Size Check
672
+
673
+ on: [pull_request]
674
+
675
+ jobs:
676
+ size:
677
+ runs-on: ubuntu-latest
678
+ steps:
679
+ - uses: actions/checkout@v3
680
+ - uses: actions/setup-node@v3
681
+ - run: npm ci
682
+ - run: npm run build
683
+ - run: npm run test:size
684
+ ```
685
+
686
+ ## Expected Results
687
+
688
+ After optimization, you should see:
689
+
690
+ - **Initial load time reduced** by 40-60%
691
+ - **Bundle size reduced** by 50-80%
692
+ - **Better Core Web Vitals** scores
693
+ - **Faster time to interactive**
694
+ - **Lower bandwidth usage** for users
695
+
696
+ ## Next Steps
697
+
698
+ - Profile your application with Chrome DevTools Performance tab
699
+ - Implement lazy loading for heavy components
700
+ - Consider using CDN for static assets
701
+ - Enable HTTP/2 for better resource loading
702
+ - Check [igniteui-wc-integrate-with-framework](../igniteui-wc-integrate-with-framework/SKILL.md) for proper setup
703
+
704
+ ## Additional Resources
705
+
706
+ - [Webpack Tree Shaking](https://webpack.js.org/guides/tree-shaking/)
707
+ - [Vite Build Optimizations](https://vitejs.dev/guide/build.html)
708
+ - [Web Performance Optimization](https://web.dev/fast/)
709
+ - [Bundle Size Analysis Tools](https://bundlephobia.com/)
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "servers": {
3
- "igniteui-cli": {
3
+ "igniteui": {
4
4
  "command": "npx",
5
- "args": ["-y", "igniteui-cli-mcp"]
5
+ "args": ["-y", "igniteui-cli@next", "mcp"]
6
6
  },
7
7
  "igniteui-theming": {
8
8
  "command": "npx",