Allow user to define another alias for a JavsScript library

时间:2015-09-14 16:08:59

标签: javascript

I have created a JavaScript library, the code for which is as below.

Question: In case the developer using this library has already created a variable named xyz, then how would I allow the developer to define another alias for the library based on code mentioned here? Right now, if this happens, I am printing a helpful message in browser's console so developer is made aware of the duplicate name.

Library code

(function (window) {

    function define_library() {
     //code for JavaScript library that has been omitted
}
if (typeof (xyz) === 'undefined') {
        window.xyz = define_library();
    }
    else {
        console.log("'xyz' is already defined. Library/variable is already defined.");
    }
})(window);

May be the define_library method needs to be exposed as a public method so developer can use following code to create another alias for the library, but not sure of the best practice in such a situation.

Developer uses another alias for the library in his/her project

window.abc = define_library();

2 个答案:

答案 0 :(得分:3)

Someday, you'll be able to publish your library as a JavaScript module (new feature this year, part of ES6) and this won't be your problem anymore.

In the meantime, there are several flavors of Asynchronous Module Definition (AMD) libraries out there (such as RequireJS) that you can add support for.

if (typeof require !== "undefined") {
    // Do RequireJS stuff
} else if (typeof exports !== "undefined") {
    // Set your top-level library functions on exports
} else {
    // ...
}

If all else fails, jQuery's way of doing this (noConflict) is quite clever: It grabs the previous value of the global it's about to write, and gives you a way to set that value back. In your case, it might look like this:

(function(window) {
    var original_xyz = window.xyz;

    // ...your normal stuff...

    // A method that releases the symbol:
    window.xyz.noConflict = function() {
        window.xyz = original_xyz;
        return this;
    };

})(window);

Then someone using it:

<script src="your_library.js"></script>
<script>
var abc = xyz.noConflict();
</script>

The end result of the above is that xyz is the same as it was before your library was loaded, but the user got a reference to your library in abc.

Live Example of the noConflict bit:

// Here's something else defining xyz:
var xyz = "My xyz that isn't your library.";

// Your library (which would be a different script tag, but
// that doesn't matter)
(function(window) {
    var original_xyz = window.xyz;
  
    window.xyz = {
        // ...your normal stuff...
        sayHello: function() {
            snippet.log("Hello from library's sayHello");
        },
        // A method that releases the symbol:
        noConflict: function() {
            window.xyz = original_xyz;
            return this;
        }
    };
   
})(window);

// My getting your library as abc instead:
var abc = xyz.noConflict();

// My using abc and my original xyz:
abc.sayHello();
snippet.log("xyz = " + xyz);
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>

答案 1 :(得分:1)

You might do so by allow editing of our your JS code through the dev who uses it. In this case you could provide a return value, that might get stored into any variable.

var moduleGlobalName = 'xyz';

(function( global ) {
    global[moduleGlobalName] = function define_library() {
        // code for JavaScript library that has been omitted
    }
})( window, moduleGlobalName || 'xyz' );

But I would you advise to use AMD modules (as suggested in my comment above) and use an appropriate module loader like Require.js.