Dwi*_*ing 7 amd requirejs mixpanel
我试图在基于Backbone.js和require.js的单页面站点中使用Mixpanel事件跟踪.
看看Mixpanel为常规网页提供剪切和粘贴的片段,我可以告诉他们已经推出了自己的异步加载机制,从独立的资源中提取实际的Mixpanel API,做一些额外的工作来设置'人员'和其他属性,最后通过全局命名空间公开'mixpanel'对象.
我试图为片段或独立API添加shim配置条目,但都不能正常工作.
通过我的研究,我在github上找到了一个完全符合我想要的项目,但它已经存在了几年,并且基于"旧的"mixpanel API.在新版本中,Mixpanel对代码片段和API进行了一些非平凡的更改,我无法理解.
我希望有人理解Mixpanel片段和/或AMD和require.js,并且可以引导我完成这个.
Jos*_*mer 13
有两个有趣的事情使这个问题成为一个奇怪的问题:
开箱即用,mixpanel片段不支持get_distinct_id(以及任何调用,根据定义,同步),直到加载lib但是在加载mixpanel lib之前确实存在其他方法(例如track)排队.因此我们有两种选择:
选项1.删除异步支持并等待加载lib - Gist
此方法的工作原理是创建一个pre-init模块来设置mixpanel lib所需的window.mixpanel deps,然后将其指定为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>
Run Code Online (Sandbox Code Playgroud)
选项2.提供"已加载"回调以更新模块的属性.- 要点
如果您真的需要异步支持,则需要在加载mixpanel lib后更新存根的方法.我不建议这样做,因为(除其他原因外)它会在复制后产生window.mixpanel!== mixpanel.这也意味着您必须防止同步调用(例如get_distinct_id())上的竞争条件.如果尚未加载lib,则它将是未定义的.注意:我建议如果您必须具有异步支持,则应该通过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>
Run Code Online (Sandbox Code Playgroud)
以下解决方案适用于mixpanel api 2.2
使用以下垫片添加mixpanel -
path : {
'mixpanel' : '//cdn.mxpnl.com/libs/mixpanel-2.2.min'
}
shim : {
'mixpanel' : {
exports : 'mixpanel'
},
}
Run Code Online (Sandbox Code Playgroud)
并使用以下requirejs模块而不是mixpanel给出的片段 -
define('mixpanel-snippet', [], function(){
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
}
b.init("YOUR TOKEN");
require(['mixpanel'], function(mixpanel){});
return b;
});
Run Code Online (Sandbox Code Playgroud)
我只是从mixpanel中获取了片段,删除了异步mixpanel加载并将其包装在requirejs模块定义中.
更改模块底部的"您的令牌".
使用需求调用的示例 -
require([
'mixpanel-snippet',
], function (mixpanel) {
mixpanel.track("Landing Page with AMD SHIM");
});
Run Code Online (Sandbox Code Playgroud)
编辑:第二个是经过一点修改后的正确答案.mixpanel脚本的工作方式是它需要片段中的init调用在实际mixpanel加载之前发生.诀窍是在init调用后要求mixpanel.i编辑了第二个答案并删除了第一个答案,这里是要点
编辑:回答来自@johanandren的评论Requirejs遵循AMD原则,并且脚本将加载的顺序不固定.如果您需要在使用mixpanel-snippet之前加载mixpanel,可以使用以下hack.
//at the end of mixpanel-snippet code mentioned above force the script to block until mixpanel is loaded
b.init("YOUR TOKEN");
var wait = true;
require(['mixpanel'], function(mixpanel){wait = false;});
while(wait){}
return b;
Run Code Online (Sandbox Code Playgroud)
**它违反了AMD的Async加载功能,强制脚本加阻,即使在vanila mixpanel片段中,加载也是异步的,初始api调用的可用性无法保证
归档时间: |
|
查看次数: |
2508 次 |
最近记录: |