javascript - 通用React应用程序中的全局变量,Node抛出ReferenceError

标签 javascript node.js reactjs

我正在创建一个具有 Google 登录功能的通用 React 应用程序。遗憾的是,Google 没有可在客户端和服务器上使用的通用 Google API ( gapi ) 库。

我在这里真正想做的是运行我的服务器代码,并让 Babel 在我进行更改时自动重新编译我的代码,并让它自动重新启动服务器(就像 nodemon 所做的那样,但有一个编译步骤)。我发现了一个名为 babel-watch 的 npm 包就可以做到这一点,但是它不与 webpack 集成。

在我的模板index.html 文件中,我在 HTML <head> 中有以下代码:

index.html

<script type="text/javascript">
  window.gapiPromise = new Promise(resolve => window.gapiLoadedCallback = () => resolve(gapi))
</script>
<script src="https://apis.google.com/js/platform:auth2.js?onload=gapiLoadedCallback" async defer></script>

上面创建了一个新的 Promise其解析值为 gapiplatform.js已加载。但是,由于这仅在客户端上加载,gapigapiPromise服务器上不存在。

我还有一个使用全局 gapiPromise 的 Google Sign In React 组件当 gapi 时执行按钮渲染的变量已准备好使用:

GoogleSignIn.jsx

import React from 'react'

// should only run on client
if (gapiPromise !== false) {
  gapiPromise.then(gapi => {
    gapi.auth2.init({
      client_id: '[removed]'
    })
  })
}

class GoogleSignIn extends React.Component {
  constructor(props) {
    super(props)
  }
  componentDidMount() {
    // should only run on client
    if (gapiPromise !== false) {
     gapiPromise.then(gapi => gapi.signin2.render('g-signin2', {
        'scope': 'email',
        'width': 160,
        'height': 50,
        'theme': 'light',
        'onsuccess': this.props.onSuccess,
        'onfailure': this.props.onFailure
      }))   
    }
  }
  render() {
    return (
      <div className="google-sign-in">
        <div id="g-signin2"></div>
      </div>
    )
  }
}

export default GoogleSignIn

这在客户端上工作得很好,但是当我尝试在服务器上渲染它时,Node 提示:

/Users/jreznik/Sites/my-app/dist/server.js:3568
  if (gapiPromise !== false) {
      ^

ReferenceError: gapiPromise is not defined
    at Object.defineProperty.value (/Users/jreznik/Sites/my-app/dist/server.js:3568:6)
    at __webpack_require__ (/Users/jreznik/Sites/my-app/dist/server.js:20:30)
    at Object.defineProperty.value (/Users/jreznik/Sites/my-app/dist/server.js:3408:22)
    at __webpack_require__ (/Users/jreznik/Sites/my-app/dist/server.js:20:30)
    at Object.defineProperty.value (/Users/jreznik/Sites/my-app/dist/server.js:3354:24)
    at __webpack_require__ (/Users/jreznik/Sites/my-app/dist/server.js:20:30)
    at Object.defineProperty.value (/Users/jreznik/Sites/my-app/dist/server.js:194:21)
    at __webpack_require__ (/Users/jreznik/Sites/my-app/dist/server.js:20:30)
    at Object.<anonymous> (/Users/jreznik/Sites/my-app/dist/server.js:59:16)
    at Object.<anonymous> (/Users/jreznik/Sites/my-app/dist/server.js:131:31)

我尝试过添加前缀 gapiPromise在此文件中包含 global. (即 global.gapiPromise ),然后定义 global.gapiPromise = false在我的服务器的入口文件( server.js )中,但是 Node 提示:

/Users/jreznik/Sites/my-app/dist/server.js:3569
      global.gapiPromise.then(function (gapi) {
                        ^

TypeError: Cannot read property 'then' of undefined

最后,我能够使用 webpack 的 DefinePlugin 让它工作。 :

webpack.server.config.js

...

plugins: [
  new webpack.DefinePlugin({
    'window': {},
    'gapiPromise': false
  })
]

...

但是如果我这样做,我就无法使用 babel-watch npm 包自动重新编译并重新启动服务器。

如何让 Node 停止提示这些未定义的全局变量?

最佳答案

它是一个客户端库,这意味着它只能与浏览器中的 DOM 一起使用。它实际上相当于window.gapiPromisewindow 对象表示浏览器中打开的窗口。

关于javascript - 通用React应用程序中的全局变量,Node抛出ReferenceError,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39864395/

相关文章:

node.js - Nodejs使用ajax根据第一个下拉列表选择的值填充下拉列表

javascript - Cloud 9 NPM 不再工作

javascript - 提取 URL 查询字符串 ES6

javascript - 为什么即使使用 onChange 监听器也无法更改 React 中的输入值

javascript - 我可以使用 javascript 延迟某些 div 的加载吗?

javascript - Chartjs - 如何更改圆环图的符号

node.js - 在 Mongoose Schema 中使用多个值的唯一文档

reactjs - 如何处理react中的404

javascript - 是否可以将github网页连接到SQL数据库?

javascript - 错误 - TypeError : React__namespace. useSyncExternalStore 不是函数