Stop global jquery with plugin in requirejs

2019-05-26 21:58发布

问题:

I have jquery and jquery-cookie working together correctly below. I would like to make is so that jquery isn't global. Right now it is. Any method i've tried seems to break jquery-cookie.

require.config({
    paths: {
        "jquery": '../components/jquery/jquery',
        "jquery-cookie": "../components/jquery-cookie/jquery.cookie",
    },
    shim: {
        "jquery-cookie": {
            deps: ['jquery']
        }
    }
});

require(["jquery", "jquery-cookie"], function($) {
    console.log($().jquery); // 1.7.2
    console.log($.cookie("hello")); // null
});

The following changes will make jquery local and break cookie:

define("nc-jquery",['jquery'], function () {
    return jQuery.noConflict(true);
});

require(["nc-jquery", "jquery-cookie"], function($) {
    console.log($().jquery);
    console.log($.cookie("hello"));
});

回答1:

Both jquery and jquery-cookie are AMD compatible, so there is no need to do any shim config. As long as you have a path called 'jquery' defined (which you do), the jquery-cookie module will require it and load the dependency just fine without the global $. See this line in the jquery-cookie source code where it looks for a module called 'jquery':

if (typeof define === 'function' && define.amd) {
    // AMD. Register as anonymous module.
    define(['jquery'], factory);

And as as you showed in your original example, you can wrap jQuery as nc-query to eliminate the global $. The one additional thing you might need to do is create a 'map' entry for whatever library you want to automatically use it.

So then a modified version of your example would look something like this:

require.config({
    paths: {
        'jquery': '../components/jquery/jquery',
        'jquery-cookie': '../components/jquery-cookie/jquery.cookie'
    },
    map: {
        'jquery-cookie': { 'jquery': 'nc-jquery' }
    }
});

define('nc-jquery', ['jquery'], function (jq) {
    return jq.noConflict( true );
});

require(['nc-jquery', 'jquery-cookie'], function(myNonGlobaljQuery) {
    console.log(myNonGlobaljQuery().jquery);
    console.log(myNonGlobaljQuery.cookie("hello"));
});

It means that when jquery-cookie asks for 'jquery', you give it 'nc-jquery' instead. you can create as many of these as needed for whatever libraries you want to work this way. See the API docs for map.



回答2:

I found that this works, I just don't think it's the best solution.

require(["jquery", "jquery-cookie"], function() {
    var $ = jQuery.noConflict(true);
    console.log($().jquery);
    console.log($.cookie("hello"));
});

My explanation of this code and why it works is as follows. jquery-cookie uses the $ in it's code and with this $ is global for just enough time for both jquery and cookie to load. I make it local with noConflict allowing $ usage within this require.