Names hosting the javascript library as optional

I am going to start creating a JS library that will have several modules. Suppose the library is called Library and the two modules are called One and Two. I would like end users to be able to call the library in two ways:

Library.One.somefunction(params) 

or

 somefunction(params) 

Basically, I want to give end users the ability to enable a namespace or not. Is there a good way to do this? Also, is there a good way to do this if I also want to provide a mini version of the library? This library is what I could do in Node.js; while I myself will use it, but I want to design it in such a way that in the future does not turn into a joint project.

Any links you can point me to would be great, thanks!

+4
source share
6 answers

well, I don’t know what you mean by “good way”.
First of all, the purpose of the namespace is to collect variables that are related to each other, and not to scatter them throughout the public namespace. Personally, I would not use such a thing, but you could iterate over the namespace objects and attach them to the window:

  for (var i in Namespace)
     if (Namespace.hasOwnProperty (i))
         window [i] = Namespace [i];
+1
source

If you are using Node.js, you can use the CommonJS system.

math.js (your library)

 exports.add = function() { for (var i = arguments.length; i--;) { sum += arguments[i]; } return sum; }; 

program.js (someone uses it ...)

 var MyMath = require('math'); console.log(MyMath.add(1, 2)); // 3 // ... in different ways var add = require('math').add; console.log(add(1, 2)); // 3 
+5
source

The basic idea of ​​creating a "namespace" is not necessarily the assignment of functions to the global scope, which is the window object:

 window.somefunction = Library.One.somefunction; 

You can write an include function that works similarly to other languages:

 var include = function (library, p) { if (!p) { for (var prop in library) { if (library.hasOwnProperty(prop)) { window[prop] = library[prop]; } } } else { window[p] = library[p]; } }; 

Then just do as needed:

 include(Library.One); 

Or use only certain functions:

 include(Library.One, 'somefunction'); 

Warnings

  • Executing functions without dot notation ( One.somefunction ) will cause the this keyword to refer to window , and not to Library.One . This is not a problem if you do not use this at all. If you have data to share between functions, you can do this using the closure area instead of this :

     var Library = {}; (function () { // I'm a closure, I have local scope var sharedData = "I'm shared but private to this scope"; Library.One = {}; Library.One.funcOne = function () { alert(sharedData); }; Library.One.funcTwo = function () { sharedData += "!"; }; }) (); 
  • Others recommend not making your methods global. This is due to the fact that when it is global, it is global for all files and, therefore, may conflict with other code. You can change the import function above to create a new object and assign everything to this object before returning it. Then files requiring shortcuts for specific libraries can do:

     (function () { var _ = include(Library.One); // This stays within this scope _.somefunction(); })(); 
+2
source

You can do this quite easily, but are you sure you want to make all methods global properties?

You can implement it like this (very simplified):

 (function( window, undefined ) { // Your code setting up namespaces var Library = {One:{},Two:{}}; // function for adding library code to both namespaces. // Could be modified to accept an Array of functions/names function addToLibraryOne( id, fn ) { window[id] = Library.One[id] = fn; } // add a function addToLibraryOne( "somefunction", function( params ) { // function code }); window.Library = Library; })( window ); 

I am wondering if you really want to pollute the global namespace in this way.

At least I would make the global properties an option, then only the function will add them if this option is selected.

0
source

I might be wrong about this (so it can get downvoted, but I want it to be appreciated), but I think you are setting a contradiction with the requirements

1) I want to use namespaces
2) I want to have access to namespace functionality without a namespace.

basically 2 - "I don't want a namespace."

To implement, you can simply define a bunch of functions on a global scale that path in the namespace, but then why is the namespace to start with?

0
source

Well, the second means that you also want functions and objects and everything in your modules to be in a global scope. Of course, of course, but so against best practices to be somewhat disgusting.

For the first part, simply declare the namespace in the library globally:

 var Library = {}; 

and then start populating it with your modules:

 Library.One = {}; Library.Two = {}; 

and then start adding functionality to these modules.

 (function($) { var $.froobString = function(s) { .... }; ...etc... })(Library.One); 

(Here I did it as a standalone executable anonymous function that runs in Library.One as $ .)

To convert all this to global, follow these steps:

 var convertToGlobals = function(module) { for (name in module) { window[name] = module[name]; } }; convertToGlobals(Library.One) 

But then I would advise you to do it.

0
source

Source: https://habr.com/ru/post/1336716/


All Articles