繁体   English   中英

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

[英]Re-export global variables with ES6 modules

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

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

export default window.dataLayer;

然而,如所解释这里的“实现视图”一节中,上面的代码等同于:

const *default* = window.dataLayer; // *not* legal JavaScript
export { *default* as default };

因此,每个模块中的window.dataLayer数组将是原始window.dataLater数组的副本:当GTM引导时,异步地,从模块推送的事件将不会被看到,因为只有本地*default*会有那些事件。

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

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

/* 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 Container Snippet作为模块加载,您可能需要在调用代码段之前导入可能首先修改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系统的方式,这显然是使用全局变量同步运行的。

我想知道谷歌是否会很快用现代JavaScript更新这些东西,或者是否有更多模块化选项可用。

我要提一下,如果你不知道:

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM