我正在创建一个具有 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
其解析值为 gapi
当platform.js
已加载。但是,由于这仅在客户端上加载,gapi
和gapiPromise
服务器上不存在。
我还有一个使用全局 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.gapiPromise
。 window
对象表示浏览器中打开的窗口。
关于javascript - 通用React应用程序中的全局变量,Node抛出ReferenceError,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39864395/