在Next.js中引入外部JS后调用函数报未定义错误该如何解决?
问题原因
- Next.js 打包时会将每个导入的JS文件作为独立模块处理,
query.js中定义的hello函数默认属于模块内部作用域,不会暴露到全局,其他模块直接调用自然会报未定义错误。 - 你在组件的渲染逻辑中直接调用
hello(),Next.js 服务端渲染阶段就会执行这段代码,而你导入的脚本默认会在服务端、客户端各执行一次,服务端环境不存在浏览器端的上下文,就算函数能访问也不符合你只在浏览器端处理数据的需求。
解决方案
方案1:ES模块导出引入(推荐)
首先修改query.js,对外暴露需要调用的函数:
console.log("script loaded!") export function hello(){ console.log("hello!") }
然后在index.js中导入函数,配合useEffect确保仅在浏览器端执行:
import { useEffect } from 'react' import { hello } from '../public/static/query.js' export default function Home() { useEffect(() => { // 此处代码仅会在客户端浏览器环境运行 hello() }, []) return ( /* 你的原有页面内容 */ <div></div> ) }
删除_app.js中原来的import '../public/static/query.js'语句即可。
方案2:全局挂载方式(适合不可修改的第三方脚本)
如果无法修改query.js的内容,或者需要脚本全局可用,先修改query.js将函数挂载到浏览器全局对象:
console.log("script loaded!") function hello(){ console.log("hello!") } window.hello = hello
然后使用Next.js官方的Script组件加载脚本,避免服务端执行:
import { useEffect } from 'react' import Script from 'next/script' export default function Home() { useEffect(() => { // 确保脚本加载完成后再调用 if(window.hello) window.hello() }, []) return ( <> <Script src="/static/query.js" strategy="beforeInteractive" /> {/* 你的原有页面内容 */} <div></div> </> ) }
同样删除_app.js中原来的脚本导入语句即可。
内容的提问来源于stack exchange,提问作者nama asliku
相关产品推荐
相关产品推荐

