2016-10-05 8 views
0

私は、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です。ただし、これはクライアントにのみロードされるため、gapigapiPromiseはサーバーに存在しません。

私はまた、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パッケージを使用することはできませんサーバーを再始動してください。

これらの未定義のグローバル変数についてノードが不平を言うのを止めるにはどうすればよいですか?

答えて

0

クライアントライブラリです。つまり、ブラウザのDOMでのみ使用されます。実際にはwindow.gapiPromiseに相当します。 windowオブジェクトは、ブラウザの開いたウィンドウを表します。

+1

ご返信いただきありがとうございます。しかし私はサーバ上の 'gapi'からコードを実行するつもりはないが、単にコンポーネント側を('

'をレンダリングすべきである)レンダリングすると、クライアントは' gapiフルボタンを描画します。 –

+0

**クライアントライブラリ**なので**サーバー側で使用することはできません。 –

0

これを何時間も使いこなした後、この質問を投稿してから1時間後に解決策が見つかりました。私GoogleSignIn.jsxファイルから

は、私は、コード...

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

を移動...とテンプレートに:ノードが「doesnの理由

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

全くわかりませんcomponentDidMount()メソッドではgapiPromiseが余分に不平を言っていますが、そうではありません。また、私はにgapiPromiseをチェックするif文を変更:

if (typeof gapiPromise !== 'undefined') {

関連する問題