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

Nuxt3执行nuxt generate时@googlemaps/js-api-loader导入报错

问题原因
  • @googlemaps/js-api-loader 提供的默认入口是UMD格式的CommonJS模块,nuxt generate 执行预渲染构建时走原生ESM模块解析逻辑,无法直接识别CommonJS模块的命名导出,这就是第一个Named export 'Loader' not found报错的直接来源。本地开发环境正常是因为Vite开发服务器内置了CommonJS转ESM的兼容逻辑,且开发模式下SSR校验规则更宽松,不会触发该问题。
  • 你把Loader实例的初始化写在了setup顶层作用域,预渲染阶段会在Node.js服务端环境执行这段逻辑,而@googlemaps/js-api-loader是纯浏览器端依赖,内部依赖window等浏览器全局对象,服务端环境下拿到的模块导出结构和浏览器端不一致,就会出现gmaps.Loader is not a constructor的错误。
修复方案

核心原则是所有和谷歌地图加载、初始化相关的逻辑,必须只在浏览器端执行,不要让服务端/预渲染阶段加载该依赖,以下三种方案选其一即可:

方案1:动态导入+逻辑收拢到onMounted(最推荐,改动最小)

不要在组件顶层导入该依赖,把导入和实例化逻辑全部移到onMounted钩子内——onMounted本身就只会在浏览器端执行,完全不会被服务端预渲染逻辑触发:

// 删除顶层的import { Loader } 或者import * as gmaps代码
onMounted(async() => {
  // 客户端环境下才动态加载依赖
  const { Loader } = await import('@googlemaps/js-api-loader')
  const loader = new Loader({
      apiKey: config.googleMapsApiKey,
      version: 'weekly',
  });
  await loader.load()
  // 后续地图渲染逻辑
})

方案2:标记组件为仅客户端渲染+构建配置转译依赖

如果你不想写动态导入,可以先在nuxt.config.ts中添加配置,让构建工具正确转译该CommonJS依赖:

export default defineNuxtConfig({
  build: {
    transpile: ['@googlemaps/js-api-loader']
  },
  vite: {
    optimizeDeps: {
      include: ['@googlemaps/js-api-loader']
    }
  }
})

之后在使用地图组件的位置,用Nuxt内置的<ClientOnly>组件包裹,强制该组件只在客户端渲染,避免服务端执行相关逻辑:

<template>
  <ClientOnly>
    <DynamicLocations class="contact__map" :locations="locations" />
    <!-- 预渲染阶段显示的占位内容 -->
    <template #fallback>
      <div class="map-placeholder"></div>
    </template>
  </ClientOnly>
</template>

方案3:封装为仅客户端插件

如果你需要在全站多个位置复用地图加载器,可以把逻辑封装为Nuxt插件,给插件文件名加.client.ts后缀,Nuxt会自动识别该插件只在客户端加载,不会在服务端执行。
新建plugins/google-maps.client.ts:

import { Loader } from '@googlemaps/js-api-loader'

export default defineNuxtPlugin(() => {
  const config = useRuntimeConfig()
  const loader = new Loader({
    apiKey: config.public.googleMapsApiKey,
    version: 'weekly',
  })

  return {
    provide: {
      gmapsLoader: loader
    }
  }
})

之后在任意组件中可以直接调用,不会触发服务端报错:

const { $gmapsLoader } = useNuxtApp()
onMounted(async () => {
  await $gmapsLoader.load()
  // 后续地图逻辑
})

注意:不要尝试在服务端环境执行任何谷歌地图相关逻辑,该库没有做Node.js环境适配,强行在服务端导入执行后续还会出现找不到window、document等报错。

内容的提问来源于stack exchange,提问作者Matthew

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 20:01:02