首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >AMD结构化web应用程序中的Mixpanel 2.2 -例如require.js

AMD结构化web应用程序中的Mixpanel 2.2 -例如require.js
EN

Stack Overflow用户
提问于 2013-07-19 00:27:06
回答 4查看 2.6K关注 0票数 7

我正在尝试在一个基于Backbone.js和require.js的单页面站点中使用Mixpanel事件跟踪。

看看Mixpanel提供的剪切和粘贴到常规网页的snippet,我可以看出他们已经推出了自己的异步加载机制,从独立的资源中拉入实际的Mixpanel API,做一些额外的工作来设置'people‘和其他属性,最后通过全局命名空间公开'mixpanel’对象。

我尝试为代码片段或独立API添加填充配置项,但两者都不能很好地工作。

通过我的研究,我发现了一个project on github,它做的正是我想要的,但是它已经有几年的历史了,并且是基于“旧的”mixpanel API的。在新版本中,Mixpanel对代码片段和API做了一些我无法理解的改动。

我希望有人能理解Mixpanel代码片段和/或AMD和require.js,并能帮我解决这个问题。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2013-09-24 03:05:49

有两件有趣的事情让这个问题变得奇怪:

  1. 混合面板库要求您在加载之前定义window.mixpanel。
  2. 混合面板库将window.mixpanel重新定义为其初始化进程的一部分。

因此,我们有两个选择:

选项1.放弃异步支持,并等待库被加载-

此方法的工作方式是创建一个预初始化模块来设置mixpanel库所需的window.mixpanel deps,然后将其指定为库本身的依赖项。然后,请求"mixpanel“将会阻塞,直到lib完全加载。

代码语言:javascript
运行
复制
<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 !==混合面板。这也意味着您必须防止在同步调用中出现竞争条件,比如get_distinct_id()。如果lib还没有装入,它将是未定义的。注意:我建议,如果你必须有异步支持,你应该通过window.mixpanel调用,而不是所有这些疯狂的调用。

代码语言:javascript
运行
复制
<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>
票数 13
EN

Stack Overflow用户

发布于 2013-07-29 15:18:26

以下解决方案适用于mixpanel api 2.2

使用以下填充程序添加mixpanel -

代码语言:javascript
运行
复制
path : {
    'mixpanel' : '//cdn.mxpnl.com/libs/mixpanel-2.2.min'
}

shim : {
    'mixpanel' : {
        exports : 'mixpanel'
    },
}

并使用以下要求模块,而不是mixpanel给出的代码片段-

代码语言:javascript
运行
复制
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;
});

我只需从mixpanel中获取代码片段,移除async mixpanel加载,并将其包装在requirejs模块定义中。

更改模块底部的"YOUR TOKEN“。

使用一个请求调用的示例--

代码语言:javascript
运行
复制
require([
    'mixpanel-snippet',
], function (mixpanel) {
        mixpanel.track("Landing Page with AMD SHIM");
});

编辑:第二个是稍加修改后的正确答案。mixpanel脚本的工作方式是,它需要在代码片段中的init调用在实际的mixpanel加载之前发生。诀窍是在初始化调用后需要mixpanel。我编辑了第二个答案,并删除了第一个答案和here's the gist

编辑:对@johanandren Requirejs评论的回答遵循AMD原则,脚本加载的顺序并不固定。如果你需要在使用mixpanel-snippet之前加载mixpanel,可以使用下面的hack。

代码语言:javascript
运行
复制
//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;

**它违反了AMD的异步加载功能,强制脚本阻止,即使在vanila mixpanel代码段中,加载也是异步的,无法保证初始api调用的可用性

票数 5
EN

Stack Overflow用户

发布于 2013-08-01 23:49:27

这对我很有效。将mixpanel片段放在名为mixpanel-snippet.js的js/lib目录中。

在您的app.js中,将以下填充程序添加到require.config:

代码语言:javascript
运行
复制
'mixpanel-snippet': {
  exports: 'mixpanel'
}

代码语言:javascript
运行
复制
require(['jquery', 'backbone', 'app/router', 'mixpanel'], function ($, Backbone, Router) {
    var router = new Router();
    Backbone.history.start();
    mixpanel.init(key);
    mixpanel.track("Landed on Start up Page");
});

我可以提供一个完整的app.js示例,如果它会有所帮助,但这应该是你的入门。如果有效,请让我知道。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17729068

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档