私は、Googleログイン機能を備えた汎用のReactアプリケーションを作成しています。残念ながら、Googleには、クライアントとサーバーの両方で使用できる汎用Google API(gapi
)ライブラリはありません。汎用Reactアプリのグローバル変数、NodeがReferenceErrorを投げる
私が実際にやっているのは、サーバコードを実行して、変更を加えたときに自動的にコードを再コンパイルして、サーバを自動的に再起動させます(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
を作成し、 platform.js
がロードされたときにはgapi
です。ただし、これはクライアントにのみロードされるため、gapi
とgapiPromise
はサーバーに存在しません。
私はまた、Googleがgapi
を使用する準備ができたときに、ボタンのレンダリングを行うためにグローバルgapiPromise
変数を使用するコンポーネントリアクトサインインしている:
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
)、その後、私のサーバーのエントリ・ファイル(server.js
)でglobal.gapiPromise = false
を定義するが、その後ノードは文句:
/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パッケージを使用することはできませんサーバーを再始動してください。
これらの未定義のグローバル変数についてノードが不平を言うのを止めるにはどうすればよいですか?
ご返信いただきありがとうございます。しかし私はサーバ上の 'gapi'からコードを実行するつもりはないが、単にコンポーネント側を('
**クライアントライブラリ**なので**サーバー側で使用することはできません。 –