
本文详解如何在 es 模块环境中正确初始化并导出 google maps 实例,解决因 `google is not defined` 和 `initmap is not a function` 导致的控制台报错,核心在于避免静态 script 加载冲突,改用动态注入 + 全局挂载方式。
在现代前端开发中,直接将 Google Maps JavaScript API 与 ES 模块(type="module")混合使用时,常遇到两个典型错误:
- Uncaught ReferenceError: google is not defined:说明 inicializar.js 中调用 google.maps.Map 时,Google Maps SDK 尚未加载完成;
- InvalidValueError: initMap is not a function:源于
根本原因在于:ES 模块具有严格的作用域隔离,而 Google Maps API 的 callback 参数要求 initMap 必须是全局可访问的函数。静态引入
✅ 正确解法是:不静态加载 API 脚本,而是由模块动态创建并注入 。
✅ 推荐实现结构(三文件方案)
1. exportmap.js(地图初始化逻辑,可复用)
// exportmap.js —— 替代原 inicializar.js
const apikey = 'AIzaSyXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'; // 替换为你的有效 API Key
function initMap() {
const mapElement = document.getElementById('map');
if (!mapElement) throw new Error('Map container #map not found');
const map = new google.maps.Map(mapElement, {
zoom: 11,
center: { lat: 40.23238925881008, lng: -100.70052936550995 }
});
// 可选:添加标记、事件等扩展逻辑
return map;
}
export { initMap, apikey };⚠️ 注意:此处 不使用 export function initMap(),而是 export { initMap },便于后续统一挂载;同时避免在模块内直接调用 google.maps.*(确保执行时机安全)。
2. gmap.js(主模块入口,负责桥接与加载)
// gmap.js —— 替代原 codigo.js,作为 HTML 中唯一 type="module" 的脚本
import * as mapModule from './exportmap.js';
// ✅ 关键步骤:将 initMap 和 apikey 显式挂载到 window,供 Google Maps API 回调使用
window.initMap = mapModule.initMap;
window.apikey = mapModule.apikey;
// 动态创建并插入 Google Maps API 脚本
const script = document.createElement('script');
script.src = `https://maps.googleapis.com/maps/api/js?key=${apikey}&libraries=places,geometry&callback=initMap`;
script.async = true;
script.defer = true;
document.head.appendChild(script); // 推荐 append to head,更符合规范3. HTML 页面(极简干净)
Google Maps 模块化集成
? 为什么这样能工作?
- gmap.js 是首个执行的模块,它先将 initMap 绑定到 window,再动态插入 API 脚本;
- Google Maps SDK 加载后,自动调用 window.initMap(),此时 google.maps 已可用,且 DOM 元素 #map 已存在;
- 所有逻辑受模块作用域保护,无全局污染,同时满足 Google Maps 的回调契约。
? 常见误区与避坑提示
- ❌ 不要在模块内直接 import 后立即调用 initMap()(如原 codigo.js 写法),这会触发 google is not defined;
- ❌ 不要将 Google Maps API
- ✅ API Key 必须启用 Maps JavaScript API 服务,并配置合法的 HTTP 引用白名单(如 localhost);
- ✅ 若需在其他模块中复用 map 实例,可在 exportmap.js 中增加 export let mapInstance = null; 并在 initMap() 中赋值,后续通过 import { mapInstance } from './exportmap.js' 访问(注意异步时序)。
通过此方案,你既能享受 ES 模块的工程化优势,又能完全兼容 Google Maps 官方加载机制,彻底消除控制台报错,实现健壮、可维护的地图集成。










