AMD 结构化网络应用程序中的 Mixpanel 2.2 - 例如需要.js [英] Mixpanel 2.2 within an AMD structured web-app - e.g. require.js

查看:23
本文介绍了AMD 结构化网络应用程序中的 Mixpanel 2.2 - 例如需要.js的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm attempting to make use of Mixpanel event tracking in a single page site based on Backbone.js and require.js.

查看 Mixpanel 提供的用于剪切和粘贴的代码段进入常规网页,我可以看出他们已经推出了自己的异步加载机制,该机制可以引入实际的 Mixpanel API来自一个独立的资源,做一些额外的工作来设置'people'和其他属性,最后通过全局命名空间暴露'mixpanel'对象.

Looking at the snippet that Mixpanel provide for cut-and-pasting into a regular webpage, I can tell they've rolled their own async loading mechanism that pulls in the actual Mixpanel API from a standalone resource, do some extra work to setup 'people' and other attributes, and finally expose the 'mixpanel' object through the global namespace.

我曾尝试为代码段或独立 API 添加 shim 配置条目,但都没有效果.

I've tried to add shim config entries for either the snippet or the standalone API but neither work well.

通过我的研究,我在 github 上发现了一个 项目,它完全符合我的要求,但它已经有几年的历史了并且基于旧"mixpanel API.在新版本中,Mixpanel 对代码片段和 API 进行了一些我无法理解的重大更改.

Through my research, I found a project on github that does exactly what I want, however it's a few years old and is based on the 'old' mixpanel API. In the new version, Mixpanel have made some non-trivial changes to the snippet and API that I just can't get my head around.

我希望有人理解 Mixpanel 代码段和/或 AMD 和 require.js 并且可以指导我完成这个.

I'm hoping somebody understands the Mixpanel snippet and/or AMD and require.js and can step me through this.

推荐答案

有两件有趣的事情让这成为一个奇怪的问题需要解决:

There are two funny things that makes this an odd problem to solve:

  1. mixpanel 库要求您在加载之前定义 window.mixpanel.
  2. mixpanel 库重新定义 window.mixpanel 作为其初始化过程的一部分.

开箱即用,mixpanel 片段在加载 lib 之前不支持 get_distinct_id(以及任何根据定义同步的调用),但在加载 mixpanel lib 之前会存根其他方法(例如 track)为了排队.因此我们有两个选择:

Out of the box, the mixpanel snippet doesn't support get_distinct_id (and any call that is, by definition, synchronous) until the lib is loaded but does stub out other methods (such as track) BEFORE loading the mixpanel lib for the sake of queueing. Therefore we have two options:

选项 1. 放弃异步支持并等待 lib 加载完毕 - Gist

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

This method works by creating a pre-init module to setup the window.mixpanel deps needed by the mixpanel lib and then specifying that as a dependency to the lib itself. Then requiring "mixpanel" will block until the lib is fully loaded.

<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())上的竞争条件.如果 lib 尚未加载,它将是未定义的.注意:我建议如果你必须有异步支持,你应该只通过 window.mixpanel 调用而不是所有这些疯狂.

If you REALLY want async support, you'll need to update your stub's methods once the mixpanel lib is loaded. I don't recommend this because (among other reasons) it results in window.mixpanel !== mixpanel after the copy. This also means you must protect against race conditions on synchronous calls like get_distinct_id(). If the lib hasn't loaded yet, it'll be undefined. NOTE: I recommend that if you must have async support, you should just call through window.mixpanel instead of all of this craziness.

<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>

这篇关于AMD 结构化网络应用程序中的 Mixpanel 2.2 - 例如需要.js的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆