如何在Angular 10 SSR/Universal中运行Chart.js(ng2-charts)?
Absolutely! I’ve helped multiple developers resolve this exact crash when using ng2-charts (backed by Chart.js) in Angular 10 Server-Side Rendering. The core issue is straightforward: Chart.js tries to access the browser’s window object during setup, but Node.js (the server environment) doesn’t have a window object. Here are the most reliable solutions that work consistently:
1. Delay Chart Initialization Until Client-Side Load
The cleanest approach is to only render and initialize your chart once the app is running in the browser. Angular provides isPlatformBrowser to detect the environment:
Step 1: Update Your Component
import { Component, OnInit, Inject, PLATFORM_ID } from '@angular/core'; import { isPlatformBrowser } from '@angular/common'; import { ChartOptions, ChartType, ChartDataSets } from 'chart.js'; import { Label } from 'ng2-charts'; @Component({ selector: 'app-dashboard-chart', templateUrl: './dashboard-chart.component.html' }) export class DashboardChartComponent implements OnInit { isBrowser: boolean; // Initialize chart properties as undefined first chartOptions: ChartOptions; chartLabels: Label[]; chartType: ChartType = 'line'; chartData: ChartDataSets[]; constructor(@Inject(PLATFORM_ID) private platformId: object) { this.isBrowser = isPlatformBrowser(platformId); } ngOnInit(): void { if (this.isBrowser) { // Now safely initialize your chart data/config this.chartOptions = { responsive: true, maintainAspectRatio: false }; this.chartLabels = ['Jan', 'Feb', 'Mar', 'Apr']; this.chartData = [ { data: [65, 59, 80, 81], label: 'Series A' } ]; } } }
Step 2: Guard the Chart in Your Template
Use *ngIf to prevent the chart component from rendering on the server:
<div *ngIf="isBrowser" class="chart-container"> <canvas baseChart [datasets]="chartData" [labels]="chartLabels" [chartType]="chartType" [options]="chartOptions"> </canvas> </div>
2. Dynamically Import Chart.js (Alternative)
If you prefer, you can dynamically load Chart.js only when running in the browser. This ensures the library never tries to access window on the server:
async ngOnInit(): Promise<void> { if (isPlatformBrowser(this.platformId)) { // Dynamically import Chart.js await import('chart.js'); // Then initialize your chart config/data as before this.chartOptions = { /* ... */ }; } }
3. Avoid Simulating window (Use Only as a Last Resort)
Some developers try to mock window in their server.ts file, but this can lead to unexpected bugs since the mock isn’t a real browser environment. If you must try it, add this near the top of server.ts:
// Warning: This is a workaround and may cause edge cases (global as any).window = { innerWidth: 1920, innerHeight: 1080, devicePixelRatio: 1 };
4. Verify Version Compatibility
Double-check that your ng2-charts version is compatible with Angular 10. For Angular 10, ng2-charts v2.x (not v3+) is the right fit. You can confirm this in your package.json:
"ng2-charts": "^2.4.2", "chart.js": "^2.9.4"
Many developers have successfully used these methods to get ng2-charts working with Angular 10 SSR. Start with the first approach—it’s the most maintainable and least likely to cause issues.
内容的提问来源于stack exchange,提问作者Lars

