如何使ES6 Bundle中的jQuery可用于HTML中加载的外部脚本?

时间:2017-11-01 14:58:26

标签: javascript jquery ecmascript-6 babel es6-modules

在网站上,我将所有带有Gulp的javascript捆绑到一个捆绑文件中。这包括jQuery,我将其导入到需要它的所有JS文件中。

我直接在HTML中添加了Google跟踪代码管理器(GTM)。但是,某些自定义标记需要jQuery,根据浏览器控制台输出未定义。我认为jQuery不会暴露在捆绑包之外。

如何从捆绑中公开jQuery,以便GTM等外部脚本可以使用它?

1 个答案:

答案 0 :(得分:0)

解决方案

从jqfundamental' s jQuery Basics Guide获得了这个想法:

import $ from 'jquery';
// make jquery available to all imports using `window` to load jQuery
window.jQuery = window.$ = $;

使用这两行,通过import加载的jQuery版本(在我的情况下是我在Node package.json中指定的那个)将被分配给window对象,大多数jQuery插件都是以及GTM自定义标签加载jQuery。

我把这句话放在我的主要js文件之上。这样我确保所有导入的jQuery插件也可以通过window访问jQuery。

为什么会这样?

对于每个人都没有完全了解它:window对象的所有属性都是全局可用的,其密钥名称为:

window.foo = 'someValue';
console.log(foo); 
// outputs 'someValue' even if used in a different scope/file/module

如果这不起作用

检查插件代码的最后一行:某些插件从this.jQuery而不是window.jQuery加载jQuery。

通常,顶级JS脚本中的this指向window,因此上述方法有效。但是,在ES6模块中 - 因此捆绑代码在浏览器中运行 - thisundefined(请参阅此exploringjs table以供参考)。

除了调整插件代码以使用window.jQuery之外,我还没有找到一个好的解决方案。请参阅此related question(在撰写本文时尚未回答)。

此问题的原因

偶然发现了this issue,它很好地解释了这种行为的原因:jQuery代码包含对module被定义的条件测试和一个对象:

if ( typeof module === "object" && typeof module.exports === "object" ){
  // set jQuery in `module`
} else {
  // set jQuery in `window`
}

在Nodejs中,module即使在浏览器中也是一个对象,因此默认情况下jQuery不是全局可用的,而是仅在导入的当前范围内。