Next.js+React(TypeScript)中如何加载外部JavaScript文件?
在Next.js + React(TypeScript)中正确引入IIFE格式的JavaScript模块
问题场景
使用Next.js和React(TypeScript)开发时,尝试通过import和require引入外部IIFE格式的JS文件(rtoken-3.0.0.min.js)均失败,无法获取到模块内容。
问题根源
你的JS文件是立即执行函数表达式(IIFE),它没有导出ES/CommonJS模块,而是直接将rtoken构造函数挂载到全局对象window.remise上,常规的import/require无法直接捕获这类全局挂载的变量。
正确引入方案
方案1:用Next.js官方Script组件加载(推荐)
Next.js提供的Script组件可精准控制外部脚本的加载时机,适合框架环境:
import Script from 'next/script'; import { useEffect, useState } from 'react'; export const Index = (props) => { const [tokenInstance, setTokenInstance] = useState(null); const initToken = () => { // 脚本加载完成后,全局window.remise.rtoken可直接使用 const TokenConstructor = window.remise.rtoken; const instance = new TokenConstructor(); instance.Init(); setTokenInstance(instance); console.log('token实例:', instance); }; return ( <> <Script src="../../../script/rtoken-3.0.0.min.js" onLoad={initToken} strategy="afterInteractive" // 可选策略:lazyOnload/afterInteractive/beforeInteractive /> </> ); };
方案2:声明全局类型+客户端组件中直接引入
适合自定义加载时机的场景,需为TypeScript补充全局类型声明:
- 创建类型声明文件(如
@types/rtoken.d.ts):
declare global { interface Window { remise: { rtoken: new () => { Init: () => void; Create: () => void; consumerID: string; SessionTimeout: number; // 根据实际暴露的方法/属性补充类型 }; }; } } export {};
- 在客户端组件中引入并使用:
import '../../../script/rtoken-3.0.0.min.js'; import { useEffect } from 'react'; export const Index = (props) => { useEffect(() => { // 确保在客户端环境执行(SSR中window不存在) if (window.remise?.rtoken) { const instance = new window.remise.rtoken(); instance.Init(); console.log('token实例:', instance); } }, []); return null; };
方案3:修改原JS文件为ES模块(若有权限)
如果可以修改原JS文件,将其转为标准ES模块导出:
// 修改后的rtoken-3.0.0.min.js var CONNECTION_TIMEOUT = 5000; function rtoken() { this.consumerID = ''; this.SessionTimeout = 60000; this.ConnectionAddress = ''; // ...原代码逻辑 } rtoken.prototype = { Init: function () { // ...原代码逻辑 }, Create: function () { // ...原代码逻辑 }, }; // ...原exJsonp、getUUID函数 export default rtoken;
之后即可在TS中直接导入:
import RToken from '../../../script/rtoken-3.0.0.min.js'; import { useEffect } from 'react'; export const Index = (props) => { useEffect(() => { const instance = new RToken(); instance.Init(); }, []); return null; };
注意事项
- 不要用
require或import * as xxx直接引入IIFE脚本,这类脚本无模块导出,导入后会得到空对象。 - Next.js SSR环境中不存在
window对象,必须确保初始化逻辑在客户端执行(通过useEffect、Script组件的onLoad或加载策略控制)。
内容的提问来源于stack exchange,提问作者tatsuya
相关产品推荐
相关产品推荐

