Next.js 15 + Turbo生产环境__webpack_require__未定义问题求助
问题解决:Next.js 15 + Turbo生产环境__webpack_require__/global未定义错误
问题分析
你的问题核心在于HERE Maps JavaScript库与Next.js 15生产构建的Webpack优化逻辑冲突:
- 开发模式下Webpack保留了
__webpack_require__这类内部全局变量,库能正常访问;但生产构建会剔除这类非标准变量,导致库调用时抛出未定义错误。 - 手动设置
global: false会直接移除全局global对象映射,而HERE Maps库依赖该对象(在浏览器环境实际对应window),因此触发新的global未定义错误。
可行解决方案
方案1:改用CDN加载HERE Maps(推荐)
绕过Webpack打包冲突,直接在客户端通过CDN加载库文件,完全避免模块打包带来的变量问题:
修改地图组件代码:
import React, { useEffect, useRef, forwardRef, useImperativeHandle } from 'react'; interface MapProps { onMapReady?: (map: any, platform: any) => void; } const Map = forwardRef<HTMLDivElement, MapProps>(({ onMapReady }, ref) => { const mapRef = useRef<HTMLDivElement | null>(null); const map = useRef<any | null>(null); const platform = useRef<any | null>(null); const isLoaded = useRef(false); useImperativeHandle(ref, () => mapRef.current as any); useEffect(() => { if (isLoaded.current || !mapRef.current) return; // 加载核心地图库 const loadCore = () => { const script = document.createElement('script'); script.src = `https://js.api.here.com/v3/3.1/mapsjs-core.js`; script.async = true; script.onload = loadMapEvents; document.body.appendChild(script); return () => document.body.removeChild(script); }; // 加载地图交互模块 const loadMapEvents = () => { const script = document.createElement('script'); script.src = `https://js.api.here.com/v3/3.1/mapsjs-mapevents.js`; script.async = true; script.onload = initMap; document.body.appendChild(script); return () => document.body.removeChild(script); }; // 初始化地图 const initMap = () => { isLoaded.current = true; const H = window.H; platform.current = new H.service.Platform({ apikey: process.env.NEXT_PUBLIC_HERE_API_KEY! }); const defaultLayers = platform.current.createDefaultLayers(); const newMap = new H.Map( mapRef.current!, defaultLayers.vector.normal.map, { zoom: 14, center: { lat: 64.144, lng: -21.94 }, } ); new H.mapevents.Behavior(new H.mapevents.MapEvents(newMap)); map.current = newMap; onMapReady?.(newMap, platform.current); }; const cleanupCore = loadCore(); return () => { cleanupCore(); map.current?.dispose(); }; }, [onMapReady]); return ( <div style={{ width: '100%', height: '100%' }} className="w-full h-full" ref={mapRef} /> ); }); Map.displayName = "Map"; export default Map;
动态导入组件的代码保持不变即可。
方案2:配置Webpack提供全局变量映射
通过修改next.config.js,让Webpack在生产构建时为HERE Maps库提供所需的全局变量:
/** @type {import('next').NextConfig} */ const nextConfig = { webpack: (config, { isServer }) => { // 仅在客户端构建时处理全局变量映射 if (!isServer) { // 将global对象映射到window(浏览器环境的全局对象) config.plugins.push( new config.webpack.DefinePlugin({ global: 'window', }) ); // 设置Webpack的全局对象为window,避免内部变量丢失 config.output.globalObject = 'window'; } return config; }, }; export default nextConfig;
这个方案无需修改组件代码,但需要注意:部分HERE Maps版本可能仍存在Webpack特定变量依赖,若此方案无效,优先尝试方案1。
关键注意事项
- 动态导入的
ssr: false配置是正确的,确保地图组件仅在客户端加载,避免服务端渲染时的环境不兼容。 - 若使用方案1,可根据需求添加更多HERE Maps模块(如
mapsjs-ui)的CDN加载逻辑。
内容的提问来源于stack exchange,提问作者Hacxk
相关产品推荐
相关产品推荐

