Angular17部署MapTiler项目报错:ReferenceError: caches is not defined
问题分析与修复方案
错误原因
ReferenceError: caches is not defined 是因为 caches 是浏览器专属的Cache API,你的项目部署时大概率触发了服务端预渲染(SSR)或静态站点生成(SSG),导致MapTiler SDK在非浏览器环境执行,从而抛出该错误,同时引发地图样式加载失败。
具体修复步骤
1. 严格限制Map相关代码在浏览器环境执行
修改组件的ngOnInit和ngAfterViewInit方法,将Map初始化逻辑包裹在浏览器环境判断内:
ngOnInit(): void { if (this.isBrowser()) { config.apiKey = 'wGRvHdO3WKYFTWYfoxL5'; this.issService.getLocate().subscribe(locate => this.locateISS = locate); } } ngAfterViewInit(): void { if (this.isBrowser() && this.locateISS) { inject(NgZone).runOutsideAngular(() => { this.map = new Map({ container: this.mapContainer.nativeElement, style: MapStyle.STREETS, center: [Number(this.locateISS.iss_position.longitude), Number(this.locateISS.iss_position.latitude)], zoom: 2 }); this.issIcon = new Marker({element : this.elementIcon.nativeElement}) .setLngLat([Number(this.locateISS.iss_position.longitude!), Number(this.locateISS.iss_position.latitude!)]) .setPopup(new Popup().setHTML("<span style='color:black; padding:20px;'>ISS</span>")) .addTo(this.map!); }); } }
2. 保护updateMarker方法
在方法开头添加浏览器环境判断,避免服务端执行:
updateMarker(){ if (!this.isBrowser() || !this.locateISS) return; const oldLat = this.locateISS?.iss_position.latitude; const oldLong = this.locateISS?.iss_position.longitude; this.issService.getLocate().subscribe(locate => this.locateISS = locate); let distance = 60 * 1.1515 * (180/Math.PI) * Math.acos( Math.sin(Number(oldLat) * (Math.PI/180)) * Math.sin(Number(this.locateISS?.iss_position.latitude) * (Math.PI/180)) + Math.cos(Number(oldLat) * (Math.PI/180)) * Math.cos(Number(this.locateISS?.iss_position.latitude) * (Math.PI/180)) * Math.cos(Number(oldLong) - Number(this.locateISS?.iss_position.longitude) * (Math.PI/180)) ); this.speed = Math.round(distance * 1.609344); this.issIcon.setLngLat([Number(this.locateISS?.iss_position.longitude), Number(this.locateISS?.iss_position.latitude)]); }
3. 模板层面添加条件渲染
给地图相关DOM元素添加*ngIf,防止服务端渲染生成无效节点:
<div class="map-container"> <div class="info-container" > <span>Latitude: {{locateISS?.iss_position?.latitude}}</span> <span>Longitude: {{locateISS?.iss_position?.longitude}}</span> <span>Velocidade: {{speed}}km/h</span> </div> <div class="map-wrap" *ngIf="isBrowser()"> <div class="map" #map></div> </div> <div class="icon" #icon *ngIf="isBrowser()"></div> </div>
4. 可选:关闭不必要的服务端渲染
如果你的项目不需要SSR/SSG,可以修改angular.json,关闭预渲染或SSR配置:
{ "architect": { "build": { "options": { "prerender": false } } } }
内容的提问来源于stack exchange,提问作者leonardo mestre
相关产品推荐
相关产品推荐

