Используя require.js с FB SDK

Я хочу загрузить FB SDK с помощью require.js.

мой тестовый пример выглядит примерно так:

test.js

require([        
     'libs/facebook/fb'
     ], function(FB){
     FB.api("/me", function(){});
));

Я хотел бы, чтобы test.js запускался только после загрузки FB SDK и для него был готов FB.

Любые мысли о том, как это можно достичь? что должна иметь моя обертка (libs/facebook/fb.js)?

Ответ 1

Кажется, что FB API не является модулем AMD, поэтому он не определяет себя так, как это требует RequireJS. Вам нужно будет закрепить FB API, используя require.config. Я предполагаю, что test.js является script, который вы предоставили в качестве основного значения данных для RequireJS.

require.config({
    shim: {
        'facebook' : {
            exports: 'FB'
        }
    },

    paths: {
        'facebook' : 'libs/facebook/fb'
    }
});

require(['facebook'], function(FB){
    FB.api('/me', function(){});
});

Ответ 2

Или заверните код инициализации в модуле (образец использует Dojo):

define( 'facebook', 
    [ 'dojo/dom-construct', 
      'dojo/_base/window', 
      'https://connect.facebook.net/en_US/all/debug.js' ], // remove "/debug" in live env
    function( domConstruct, win ) 
    {

        // add Facebook div
        domConstruct.create( 'div', { id:'fb-root' }, win.body(), 'first' );

        // init the Facebook JS SDK
        FB.init( {
            appId: '1234567890', // App ID from the App Dashboard
            channelUrl: '//' + window.location.hostname + '/facebook-channel.html', // Channel File for x-domain communication
            status: true, // check the login status upon init?
            cookie: true, // set sessions cookies to allow your server to access the session?
            xfbml: true // parse XFBML tags on this page?
        } );


        // Additional initialization code such as adding Event Listeners goes here
        console.log( 'Facebook ready' );

        return FB;
    } 
);

Ответ 3

Вот документация от Facebook: https://developers.facebook.com/docs/javascript/howto/requirejs/

require.config({
  shim: {
    'facebook' : {
      export: 'FB'
    }
  },
  paths: {
    'facebook': '//connect.facebook.net/en_US/all'
  }
})
require(['fb']);

а затем добавьте модуль следующим образом:

define(['facebook'], function(){
  FB.init({
    appId      : 'YOUR_APP_ID',
    channelUrl : '//yourdomain.com/channel.html'
  });
  FB.getLoginStatus(function(response) {
    console.log(response);
  });
});

Ответ 4

Основываясь на voidstate и Ответы Dzulqarnain Nasir, вот код, который я использовал в своем проекте.

Часть, которая помогла мне больше всего в том, что FB.init(), по-видимому, асинхронна. При попытке объявить callback() (без FB.getLoginStatus), FB еще не был инициализирован, и я получал ошибки "An active access token must be used to query information about the current user.".

Конфигурация с настройками RequireJS

require.config({
    // paths: { 'facebookSDK': '//connect.facebook.net/en_US/all/debug' }, // development
    paths: { 'facebookSDK': '//connect.facebook.net/en_US/all' }, // production
    shim: { 'facebookSDK': { exports: 'FB' } }
});

Модуль AMD для инициализации SDK Facebook JS

define(['facebookSDK'], function (FB) {
    'use strict';

    return function (settings, callback) {
        var args = {
            appId: settings.appId,
            channelUrl: settings.channelUrl,
            status: true,
            cookie: true,
            xfbml: true
        };

        console.log('Calling FB.init:', args);
        FB.init(args);

        if (callback && typeof (callback) === "function") {
            // callback() // does not work, FB.init() is not yet finished
            FB.getLoginStatus(callback);
        }            
    };

});

Это все еще не совсем удовлетворяет желаемому использованию исходного вопроса.

Код OP может быть переписан как:

require(['libs/facebook/fb'], // where fb.js holds my above Module
   function(FBinit){
     FBinit({
       appId: appId, 
       channelUrl: channelUrl
     }, function(){
       FB.api("/me", function(){});
     });
   }
);

Это не совсем так, как чистая оригинальная концепция OP, но это лучшее, что я мог бы выяснить. Если у кого-нибудь есть, я бы хотел получить некоторые отзывы или советы о том, как улучшить мой подход. Я все еще очень новичок в RequireJS.