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

构建Next.js应用时出现ReferenceError: self is not defined的解决方法

解决Next.js构建时"ReferenceError: self is not defined"错误(moru-web-sdk相关)

在Next.js应用中使用moru-web-sdk时,开发模式(npm run dev)正常,但执行构建时触发ReferenceError: self is not defined错误。已尝试通过dynamic导入组件并设置ssr: false,但问题依旧。

问题原因

虽然使用dynamic({ ssr: false })可以避免组件在服务端渲染,但组件模块的**顶级代码(包括SDK的import语句)**在构建阶段仍会被Node.js环境执行。而moru-web-sdk内部直接使用了浏览器专属的全局变量self,Node.js环境中不存在该变量,因此抛出错误。

解决方案

将SDK的导入和初始化延迟到客户端环境运行时执行,避免Node.js在构建阶段处理SDK代码。以下是两种可行方案:

方案1:使用useEffect在组件挂载时加载SDK

修改pages/components/moru-sdk.js:

import { useEffect, useState } from 'react';

function MoruService() {
  const [checkout, setCheckout] = useState(null);

  useEffect(() => {
    // 仅在浏览器环境中加载并初始化SDK
    const initMoruCheckout = async () => {
      const { MoruCheckout } = await import('moru-web-sdk');
      const options = {
        access_key: "test_9425294388834bdface7d1b58fd538bf67627d9408fe4f2589820cf550a5003d",
        transaction_id: "1",
        additional_fields: {
          name: "Shubham Dhakal",
          email: "shubham@gmail.com",
        },
        callback_handler: {
          onSuccess: (response) => {
            console.log(response);
            alert("success");
          },
          onError: (error) => {
            console.log(error);
            alert("failure");
          },
          onClose: (error) => {
            console.log(error);
          },
        },
      };
      setCheckout(new MoruCheckout(options));
    };

    initMoruCheckout();
  }, []);

  const handleMoruPayment = () => {
    checkout?.open({ amount: 100 });
  };

  return (
    <>
      {/* 未初始化完成时禁用按钮 */}
      <button onClick={handleMoruPayment} disabled={!checkout}>Pay with Moru</button>
    </>
  );
}

export default MoruService;

方案2:点击支付时动态加载SDK

如果不需要提前初始化SDK,也可以在用户点击支付按钮时再加载:

function MoruService() {
  const handleMoruPayment = async () => {
    // 点击时才加载SDK
    const { MoruCheckout } = await import('moru-web-sdk');
    const options = {
      access_key: "test_9425294388834bdface7d1b58fd538bf67627d9408fe4f2589820cf550a5003d",
      transaction_id: "1",
      additional_fields: {
        name: "Shubham Dhakal",
        email: "shubham@gmail.com",
      },
      callback_handler: {
        onSuccess: (response) => {
          console.log(response);
          alert("success");
        },
        onError: (error) => {
          console.log(error);
          alert("failure");
        },
        onClose: (error) => {
          console.log(error);
        },
      },
    };
    const checkout = new MoruCheckout(options);
    checkout.open({ amount: 100 });
  };

  return (
    <>
      <button onClick={handleMoruPayment}>Pay with Moru</button>
    </>
  );
}

export default MoruService;

说明

两种方案都确保了SDK的代码只在浏览器环境中执行,避免了Node.js构建阶段对self变量的访问。同时保留原有的dynamic({ ssr: false })配置,确保组件本身不会在服务端渲染。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 22:15:39