首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用ES6模块再导出全局变量

用ES6模块再导出全局变量
EN

Stack Overflow用户
提问于 2016-01-18 19:15:44
回答 1查看 4.6K关注 0票数 3

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

我想将这些全局函数抽象到ES6模块中,而不是指示linter使用/* global dataLayer */忽略它们,因为它使代码更容易理解。我的第一次尝试是创建这样的shims:

代码语言:javascript
复制
export default window.dataLayer;

但是,正如“实现视图”一节中所解释的那样,上述代码相当于:

代码语言:javascript
复制
const *default* = window.dataLayer; // *not* legal JavaScript
export { *default* as default };

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

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

EN

回答 1

Stack Overflow用户

发布于 2016-01-19 02:27:33

与你在问题中所描述的相反,处理这个问题的正确方法是:

代码语言:javascript
复制
/* data-layer.js */
window.dataLayer = [];
export default window.dataLayer;

...and任何需要推进到"dataLayer“数组的模块,只需要如下所示:

代码语言:javascript
复制
import dataLayer from 'data-layer';

// ... some code I assume

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

因为ES6导入传递对导出的只读引用,所以它不是要导入的数组的副本,所以它是在数据层.‘s中创建和导出的数组。

但接下来的棘手之处在于,您将不得不修改Google容器片段,使其在加载后不立即运行,而是只在所有修改dataLayer的脚本运行之后才能运行。

如果要将GTM容器片段作为模块单独加载,则可能希望在调用代码段之前导入可能首先修改dataLater的所有脚本(并确保该部分实际运行)。

类似于:

代码语言:javascript
复制
/* 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系统的方式,这个系统显然是为了使用globals同步运行而编写的。

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

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

许多(大多数)ES6/ as 2015特性,包括模块,从现在(2016年1月)起都无法在浏览器中使用,因此您需要某种构建或加载程序来使这些功能在浏览器中工作(比如webpack、浏览器浏览器、浏览器浏览器、jspm,或者使用babel或tracuer之类的东西)。

http://stealjs.com/可能是最容易开始使用的。

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

https://stackoverflow.com/questions/34862340

复制
相关文章

相似问题

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