You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular 17生产构建后Leaflet-Draw出现TypeError:无法读取'Event'属性

Angular 17 + Leaflet-Draw生产构建后报错:Cannot read properties of undefined (reading 'Event')

错误信息

生产构建后控制台抛出:

ERROR TypeError: Cannot read properties of undefined (reading 'Event')
    at t.initMap (main-LBMRC7E2.js:7:213297)
    at t.ngOnInit (main-LBMRC7E2.js:7:212880)
    at Od (main-LBMRC7E2.js:7:17665)
    at j_ (main-LBMRC7E2.js:7:17812)
    at Hh (main-LBMRC7E2.js:7:17571)
    at oo (main-LBMRC7E2.js:7:17299)
    at fw (main-LBMRC7E2.js:7:40199)
    at ja (main-LBMRC7E2.js:7:41255)
    at hw (main-LBMRC7E2.js:7:39798)
    at Of (main-LBMRC7E2.js:7:39691)

出错代码片段

import {Component, OnInit} from '@angular/core';
import { RouterOutlet } from '@angular/router';
import * as L from 'leaflet';
import 'leaflet-draw'

@Component({
  selector: 'app-root',
  standalone: true,
  imports: [RouterOutlet],
  template: `
    <div id="map" style="height: 600px;"></div>
  `,
  styleUrl: './app.component.css'
})
export class AppComponent implements OnInit{
  private map: L.Map | undefined;

  ngOnInit(): void {
    this.initMap();
  }

  private initMap(): void {
    this.map = L.map('map').setView([51.505, -0.09], 13);

    L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
      attribution: '© OpenStreetMap contributors'
    }).addTo(this.map);

    // 初始化用于存储可编辑图层的FeatureGroup
    const drawnItems = new L.FeatureGroup();
    this.map.addLayer(drawnItems);

    // 初始化绘制控件并传入可编辑图层的FeatureGroup
    const drawControl = new L.Control.Draw({
      edit: {
        featureGroup: drawnItems
      }
    });
    this.map.addControl(drawControl);

    // 添加已有地理围栏
    const geofence = L.polygon([
      [51.509, -0.08],
      [51.503, -0.06],
      [51.51, -0.047]
    ]);
    drawnItems.addLayer(geofence);

    // 监听绘制完成事件
    this.map.on(L.Draw.Event.CREATED, (event: any) => {
      const layer = event.layer;
      drawnItems.addLayer(layer);
    });

    // 监听编辑完成事件
    this.map.on(L.Draw.Event.EDITED, (event: any) => {
      const layers = event.layers;
      layers.eachLayer((layer: any) => {
        console.log('图层已编辑:', layer);
      });
    });

    // 监听删除完成事件
    this.map.on(L.Draw.Event.DELETED, (event: any) => {
      const layers = event.layers;
      layers.eachLayer((layer: any) => {
        console.log('图层已删除:', layer);
      });
    });
  }
}

环境信息

  • Angular版本:17.3.0
  • Leaflet版本:1.9.4
  • Leaflet-Draw版本:1.0.4
  • @types/leaflet: 1.9.12
  • @types/leaflet-draw: 1.0.11

解决方案

1. 修复Tree Shaking导致的模块未正确打包

Angular生产构建的Tree Shaking可能误判Leaflet-Draw的依赖关系,导致L.Draw未被正确注入。在angular.json的build配置中添加允许的CommonJS依赖:

"projects": {
  "your-project-name": {
    "architect": {
      "build": {
        "options": {
          "allowedCommonJsDependencies": [
            "leaflet",
            "leaflet-draw"
          ]
        }
      }
    }
  }
}

2. 显式声明Leaflet的Draw扩展

在组件文件中添加类型声明,确保TypeScript能识别L.Draw:

import * as L from 'leaflet';
import 'leaflet-draw';

// 显式扩展Leaflet模块类型
declare module 'leaflet' {
  namespace Draw {
    const Event: {
      CREATED: string;
      EDITED: string;
      DELETED: string;
    };
  }
}

3. 改用全局CDN加载(备选方案)

如果上述方法无效,直接在index.html中引入CDN资源,确保全局L对象包含Draw属性:

<!-- 在index.html的head中添加 -->
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" />
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>
<link rel="stylesheet" href="https://unpkg.com/leaflet-draw@1.0.4/dist/leaflet.draw.css" />
<script src="https://unpkg.com/leaflet-draw@1.0.4/dist/leaflet.draw.js"></script>

此时组件中无需import Leaflet和Leaflet-Draw,直接使用全局L对象即可。

4. 检查类型配置

确保tsconfig.json中包含leaflet和leaflet-draw的类型:

"compilerOptions": {
  "types": ["leaflet", "leaflet-draw"]
}

内容的提问来源于stack exchange,提问作者ayoub ait si ahmad

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 01:45:01