これを解決するのが奇妙な問題になる 2 つの面白いことがあります。
- mixpanel ライブラリでは、ロードする前に window.mixpanel を定義する必要があります。
- mixpanel lib は、init プロセスの一部として window.mixpanel を再定義します。
すぐに使用できる mixpanel スニペットは、lib がロードされるまで get_distinct_id (および定義上、同期であるすべての呼び出し) をサポートしませんが、mixpanel lib をロードする前に他のメソッド (track など) をスタブアウトします。待ち行列。したがって、次の 2 つのオプションがあります。
オプション 1. 非同期サポートをドロップし、lib がロードされるまで待ちます - Gist
この方法は、mixpanel lib に必要な window.mixpanel deps をセットアップする pre-init モジュールを作成し、それを lib 自体への依存関係として指定することによって機能します。次に、「mixpanel」を要求すると、lib が完全にロードされるまでブロックされます。
<html>
<head>
<title>Mixpanel AMD Example - Sync</title>
<script type="text/javascript" src="http://requirejs.org/docs/release/2.1.8/minified/require.js"></script>
<script type="text/javascript">
requirejs.config({
paths : { 'mixpanel': "//cdn.mxpnl.com/libs/mixpanel-2.2.min" },
shim: {
'mixpanel': {
deps: ['mixpanel-preinit'],
exports: 'mixpanel'
}
}
});
define("mixpanel-preinit", function(require) {
// this is a stripped down version of the mixpanel snippet that removes the loading of the lib via external script tag and the stubs for queuing calls
var b=window.mixpanel=window.mixpanel||[];var i,g;b._i=[];b.init=function(a,e,d){function f(b,h){var a=h.split(".");2==a.length&&(b=b[a[0]],h=a[1]);b[h]=function(){b.push([h].concat(Array.prototype.slice.call(arguments,0)))}}"undefined"!==typeof d?c=b[d]=[]:d="mixpanel";b._i.push([a,e,d])};b.__SV=1.2;
b.init("YOUR TOKEN");
});
</script>
</head>
<body>
<script type="text/javascript">
require(['mixpanel'], function(mixpanel) {
mixpanel.track("my event", {prop1: "val1"});
console.log(mixpanel.get_distinct_id());
});
</script>
</body>
</html>
オプション 2. モジュールのプロパティを更新するために「読み込まれた」コールバックを提供します。-要点
本当に非同期サポートが必要な場合は、mixpanel ライブラリがロードされたら、スタブのメソッドを更新する必要があります。(他の理由の中でも)コピー後に window.mixpanel !== mixpanel になるため、これはお勧めしません。これは、get_distinct_id() などの同期呼び出しで競合状態から保護する必要があることも意味します。ライブラリがまだロードされていない場合は、未定義になります。注: 非同期サポートが必要な場合は、この狂気の代わりに window.mixpanel を介して呼び出すことをお勧めします。
<html>
<head>
<title>Mixpanel AMD Example - Async</title>
<script type="text/javascript" src="http://requirejs.org/docs/release/2.1.8/minified/require.js"></script>
<script type="text/javascript">
requirejs.config({
paths : { 'mixpanel-lib': "//cdn.mxpnl.com/libs/mixpanel-2.2.min" }
});
define("mixpanel", function(require) {
var b = window.mixpanel || [];
if (!b.__SV) { var i, g; window.mixpanel = b; b._i = []; b.init = function (a, e, d) { function f(b, h) { var a = h.split("."); 2 == a.length && (b = b[a[0]], h = a[1]); b[h] = function () { b.push([h].concat(Array.prototype.slice.call(arguments, 0))) } } var c = b; "undefined" !== typeof d ? c = b[d] = [] : d = "mixpanel"; c.people = c.people || []; c.toString = function (b) { var a = "mixpanel"; "mixpanel" !== d && (a += "." + d); b || (a += " (stub)"); return a }; c.people.toString = function () { return c.toString(1) + ".people (stub)" }; i = "disable track track_pageview track_links track_forms register register_once alias unregister identify name_tag set_config people.set people.set_once people.increment people.append people.track_charge people.clear_charges people.delete_user".split(" "); for (g = 0; g < i.length; g++) f(c, i[g]); b._i.push([a, e, d]) }; b.__SV = 1.2 }
// go ahead and start loading the mixpanel-lib
require(['mixpanel-lib']);
b.init("YOUR TOKEN", {loaded: function() {
// now that we know mixpanel is loaded, copy the prop references to our module def
for(var prop in window.mixpanel) {
b[prop] = window.mixpanel[prop];
}
}});
return b;
});
</script>
</head>
<body>
<script type="text/javascript">
require(['mixpanel'], function(mixpanel) {
mixpanel.track("my event", {prop1: "val1"});
console.log(mixpanel.get_distinct_id()); // probably undefined
});
</script>
</body>
</html>