在 React 组件中使用 index.html 中包含的脚本

Using included script in index.html in React components

我正在尝试为我的 React 组件使用我在 index.html 的脚本标签中加载的库中的变量。我已经正常加载它了:

<head>
  ...
  <script src="https://cdn.plaid.com/link/v2/stable/link-initialize.js"></script>
  <!-- gives me the 'Plaid' library -->
  ...
  <title>React App</title>
</head>

但是,当我尝试在我的 React 组件中访问 Plaid 时,它是未定义的。我很困惑,因为如果我在它之前放入调试器,我仍然可以访问它。例如,在我的 App.js 组件中,我有:

componentDidMount() {
  debugger // can access 'Plaid' here
  Plaid // throws error, 'Plaid' is undefined
}

为什么 Plaid 会抛出错误,即使我可以通过调试器访问它?

问题是 Webpack 文件是单独捆绑的,与所需的脚本分开。因此,当您尝试访问全局变量时,它并不存在。

如果你想使用 <script>s,你将不得不自己定制你的 Webpack 配置。这涉及弹出 create-react-app 并自行管理所有内容。 在执行此操作之前备份您的项目,因为弹出后就无法返回!首先运行:

npm run eject

弹出完成后,导航到 webpack.config.js 并向配置对象添加一个新键:

externals: {

}

externals的作用是从Plaid等CDN获取一个脚本声明的全局变量,并允许在项目中作为模块使用。因此,像这样配置它:

externals: {
    plaid: 'Plaid'
}

这从 CDN 获取全局变量 Plaid 并将其作为名为 plaid 的模块提供服务。导入后就可以使用Plaid了:

const Plaid = require('plaid'); //ES5
import Plaid from 'plaid'; //ES2015

(None 已经过测试,风险自负)。如果提供了 NPM 包,我更愿意通过 CDN 使用它。

我知道这已经晚了,但我在这里为那些在执行上述操作时遇到问题的未来用户回答这个问题。

例外的答案是 不是 集成 Plaid(或 <script> 标签中的任何外部依赖项)的最佳方式。尽可能弹出 React 应用程序 avoided

更好的解决方案是使用 React built in 访问脚本加载的全局变量的方式。您可以通过访问 window 对象 (window.NameOfYourObject) 来执行此操作。在这种情况下,它将是 window.Plaid.

在上述示例的上下文中,这看起来像

this.linkHandler = window.Plaid.create({
   clientName: 'plaid walkthrough demo',
   product: ['transactions'],
   key: 'YOUR KEY',
   env: 'sandbox',
   webhook: this.props.webhook,
   token: this.props.token,
   selectAccount: this.props.selectAccount,
   longtail: this.props.longtail,
   onLoad: this.handleLoad,
   onSuccess: this.handleSuccess,
   onExit: this.handleExit,
 });

把剧本放在脑袋里是可行的,但这也是不好的做法。最好使用类似 react-load-script.

的组件加载脚本