How do I make jQuery from a ES6 Bundle available to external scripts loaded in the HTML?

偶尔善良 提交于 2019-12-24 09:50:07

问题


On a website, I bundle all the javascript with Gulp into one bundle file. This includes jQuery, which I import into all the JS files that require it.

I include the Google Tag Manager (GTM) directly in the HTML. However, some of the custom tags require jQuery, which is undefined according to browser console output. I assume jQuery is not exposed outside the bundle.

How do I expose jQuery from the bundle so external scripts such as GTM can use it?


回答1:


Solution

Got the idea from jqfundamental's jQuery Basics Guide:

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

With these two lines, the jQuery version loaded via import (in my case the one I specified in my Node package.json) will be assigned to the window object, from which most jQuery plugins as well as GTM custom tags load jQuery.

I put this statement on top of my main js file. This way I make sure that all imported jQuery plugins can access jQuery via window, as well.


Why this works

For everyone not completely aware of it: All properties of the window object are globally available with their key name:

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

If this doesn't work

Check the last line of your plugin code: Some plugins load jQuery from this.jQuery instead of window.jQuery.

Usually, this in JS scripts on the top level points to window, so above approach works. However, in ES6 modules - and as such the bundle code is run in the browser - this is undefined (see this exploringjs table for reference).

I haven't found a good solution other than adjusting the plugin code to use window.jQuery. See this related question (unanswered at the time of writing).


Reason for this issue

Stumbled upon this issue which explains the reason for this behavior quite well: The jQuery code contains a conditional testing for module being defined and an object:

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

In Nodejs, module is an object even in the browser, thus jQuery is not globally available by default, but only in the current scope of the import.



来源:https://stackoverflow.com/questions/47057729/how-do-i-make-jquery-from-a-es6-bundle-available-to-external-scripts-loaded-in-t

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!