Inertia.js SSR环境下Google Maps JS API Loader构造函数报错求助
解决Laravel+Inertia+Vue3 SSR中@googlemaps/js-api-loader的Loader未定义问题
问题诊断
出现TypeError: Loader is not a constructor的核心原因:
@googlemaps/js-api-loader是专为浏览器环境设计的模块,依赖window等浏览器全局对象,在SSR服务端渲染阶段执行导入时,模块无法正常初始化,导致Loader变为undefined。- 直接在组件顶层导入模块会让服务端渲染进程尝试加载该模块,触发环境不兼容问题。
解决方案
1. 仅在客户端环境初始化Loader
利用Vue3的onMounted钩子(仅在客户端执行),结合动态导入方式加载模块:
<script setup> import { onMounted } from 'vue'; onMounted(async () => { // 动态导入Loader,仅在客户端执行 const { Loader } = await import('@googlemaps/js-api-loader'); const loader = new Loader({ apiKey: '你的谷歌地图API密钥', version: 'weekly', libraries: ['places'] // 根据需求添加需要的库 }); loader.load().then(() => { // 初始化地图实例 new window.google.maps.Map(document.getElementById('map'), { center: { lat: -34.397, lng: 150.644 }, zoom: 8, }); }); }); </script> <template> <div id="map" style="width: 100%; height: 400px;"></div> </template>
2. 配置Inertia SSR排除客户端模块
在SSR配置文件(resources/js/ssr.js)中,将@googlemaps/js-api-loader标记为服务端忽略的外部模块,避免服务端尝试加载:
import { createSSRApp, h } from 'vue'; import { createInertiaApp } from '@inertiajs/vue3'; import createServer from '@inertiajs/vue3/server'; import { resolvePageComponent } from 'laravel-vite-plugin/inertia-helpers'; createServer((page) => createInertiaApp({ page, resolve: (name) => resolvePageComponent(`./Pages/${name}.vue`, import.meta.glob('./Pages/**/*.vue')), setup({ app, props, plugin }) { return createSSRApp({ render: () => h(app, props) }) .use(plugin); }, ssr: { // 告知SSR将该模块视为外部依赖,不尝试在服务端加载 externals: { '@googlemaps/js-api-loader': 'commonjs @googlemaps/js-api-loader' } } }) );
3. 验证依赖版本兼容性
确保@googlemaps/js-api-loader使用稳定版本,避免版本兼容问题,可执行以下命令更新:
npm install @googlemaps/js-api-loader@latest
验证步骤
- 重启Laravel开发服务器和Inertia SSR服务:
php artisan serve npm run ssr:watch - 访问包含地图的页面,检查服务端控制台是否再无
Loader相关错误 - 确认客户端地图正常渲染加载
内容的提问来源于stack exchange,提问作者Alex
相关产品推荐
相关产品推荐

