如何加载外部脚本并从 nextJS 的主包访问它

How to load an external script and access it from the main bundle in nextJS

我正在与 mercadopago 图书馆合作。有必要加载 mercadopago 脚本文件并创建 MercadoPago 对象的实例。问题是,nextJS 在包含 mercadopago 文件之前加载了主包,所以我得到了一个执行错误,因为对象没有定义。

我尝试了不同的方法,将脚本文件加载到带有普通标签和 Next/Script 对象的 Head 组件中,例如:

<script src="https://sdk.mercadopago.com/js/v2" strategy="beforeInteractive"/>

不管我做什么,next 总是在主包文件之后加载脚本。如果我设置一个 setTimeout 等待实例化它运行的 Mercadopago 对象,但显然这不是一个好的选择。解决这个问题的正确方法是什么?

在 next.js 脚本之前加载 _document.js 中的脚本,在 pages 目录中创建 _document.js 以按照您喜欢的方式扩展 html 文档。

import Document, { Html, Head, Main, NextScript } from "next/document";

export default class MyDocument extends Document {
  render(){
    return (
      <Html>
        <Head>      
           /*This is loads the script in head tag of your html document*/      
           <script src="https://sdk.mercadopago.com/js/v2" strategy="beforeInteractive"/>
        </Head>

        <body>
          /*your script can also go here before loading next scripts*/
          <Main />
          <NextScript />
        </body>
      </Html>
    )
  }
}

好的,我使用 Next/Script 组件上可用的 onLoad 方法解决了这个问题。我需要做的是将脚本包含移动到我自己的组件中,并在其中包含组件,添加 onLoad 道具并传递一个在加载后执行我的对象实例的函数。

这是我的代码:

const onload = () => {
     const controller = new Controller(props);
     setController(controller);
};
const pay = () => controller.load(props.disabled);
const attrs = {onClick: pay};
if (!controller || props.disabled) attrs.disabled = true;
return(
  <>
    <section className="mercadopago-checkout-pro-component">
        <div ref={refContainer} className="cho-container">
            <button  className="btn btn-secondary" {...attrs}>
                Pay
            </button>
        </div>
    </section>
    <Script src="https://sdk.mercadopago.com/js/v2" onLoad={onload}/>
   </>
);