使用ES6模块重新导出全局变量

时间:2016-01-18 19:15:44

标签: javascript ecmascript-6

我将JS脚本迁移到ES6模块。客户端代码的常见模式是将跟踪信息推送到true对象上的全局数组。其中一个具体示例是GTM window数组。

我想将这些全局变量抽象为ES6模块,而不是指示linter使用window.dataLayer忽略它们,因为它使代码更容易理解。我的第一次尝试是创建像这样的垫片:

/* global dataLayer */

然而,正如"实施视图"中所解释的here部分,上面的代码相当于:

export default window.dataLayer;

因此,每个模块中的const *default* = window.dataLayer; // *not* legal JavaScript export { *default* as default }; 数组将是原始window.dataLayer数组的副本:当GTM引导异步时,从模块推送的事件不会被看到因为只有本地window.dataLater会有这些事件。

使用ES6模块处理像这些全局变量的推荐方法是什么,这不涉及使用代理等重量级解决方案?在模块化系统中有很多全局变量确实让人感觉很糟糕。

1 个答案:

答案 0 :(得分:3)

与您在问题中描述的内容相反,处理此问题的正确方法是:

/* data-layer.js */
window.dataLayer = [];
export default window.dataLayer;

...以及任何需要推送到“dataLayer”数组的模块,只需要:

import dataLayer from 'data-layer';

// ... some code I assume

dataLayer.push({
  'pageCategory': 'signup',
  'visitorType': 'high-value'
});

由于ES6导入会将只读引用传递给导出,因此它不是您要导入的数组的副本,而是在data-layer.js中创建和导出的数组。

但那时棘手的部分就是你必须修改Google跟踪代码管理器容器代码段才能在加载后立即运行,而是只在所有脚本之后运行可以修改dataLayer已经运行。

如果您正在将 GTM容器代码段作为模块加载,您可能需要先导入所有可能先修改dataLater的脚本(并确保该部分实际运行)调用代码段。

类似的东西:

/* gtm-container.js */
import 'this';
import 'that';
import otherThing from 'the-other-thing'; // lets assume it returns a promise
import dataLayer from 'data-layer'l

otherThing.then(value => {
   invokeSnippet()
})
.catch(err => {
   handleError(err);
});

function invokeSnippet() {
(function(w,d,s,i){dataLayer.push({'gtm.start':
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
'//www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer','GTM-XXXX')
}

但是,你知道这并不是解释如何做到这一点,只是一个想法,我不知道有什么不同的东西可以添加到dataLayer,因为你正在转向异步模块模式,你将有了解如何以异步方式运行所有这些脚本将改变您使用GTM系统的方式,该系统明确地编写为使用全局变量同步运行。

我想知道Google是否会尽快使用现代JavaScript更新这些内容,或者是否有更多模块化选项可用。

如果您不知道,我应该提及:

许多(大多数)ES6 / ES2015功能包括模块在今天(2016年1月)的浏览器中不可用,因此您需要某种构建或加载器来制作这些东西在浏览器中工作(比如webpack,browserify,stealjs,jspm,或者有babel或tracuer之类的东西)

http://stealjs.com/可能是最容易上手的。

相关问题