Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Writing a library, what structure?

Tags:

javascript

I'm writting a library. Right now, I have everything written in a single .js file that goes like:

function doThis() {} var thisVar = 5; 

I was not sure if that was right, so I considered:

function Lib() {   this.doThis = function() {}   this.thisVar = 5; }  var lib = new Lib(); 

Then, on the main program files, I would have to call everything with "lib.", such as "lib.thisVar" or "lib.doThis();".

Any ideas on which would be better, or are they both acceptable? Thank you in advance.

like image 601
David Gomes Avatar asked Nov 28 '12 13:11

David Gomes


People also ask

What is the structure of a library?

The hierarchy consists of cabinets, drawers, folders, folder groups (this level is optional in usage), and within the folders are the documents; documents can only reside in the folders. Folder groups are an optional extra layer of division in the library structure.

Can I use TypeScript libraries from JavaScript code?

The short answer is definitely YES ! but you need some intermediate steps ! Please note that ,you can write plain old JavaScript in a TypeScript project without any problems since JavaScript is a subset of TypeScript ,you only need these steps if you are planning to use an external JavaScript library with TypeScript .


2 Answers

To avoid cluttering the global namespace, I use a structure like this:

var MyLib = {     vars: {         var1: 'value1',         var2: 'value2'     },     func1: function () {         return this.vars.var1;     },     func2: function () {         alert("This is func2");     } };  MyLib.func1(); MyLib.func2(); 

You will notice I placed all the variables into their own sub-object, this is done purely for easy reading and development.


EDIT 1:

Here is another method I use

var MyLib = (function MyLib() {     var _privateVars = {         "someVar": "This value made public by `someMethod`",         "privateVar": "Can't see this value"     };      // Return the constructor     return function MyLibConstructor() {         var _this = this; // Cache the `this` keyword          _this.someMethod = function () {             // Access a private variable             return _privateVars.someVar;         };          _this.someOtherMethod = function () {             // Some other functionality         };     }; }());  var myLib = new MyLib(); // invoke  console.log( myLib.someMethod() ); 

This structure utilizes JS Closures and a constructor function, so its easy to keep private variables private.

EDIT 2:

In addition, I've also used a different closure setup that does not return a constructor (e.g. var x = new MyLib();).

(function(window) {     var _private = {},         methods = {},         topic, init;      methods.set = function(value) {         // Set the property & value         _private[topic] = value;         return this;     };      // A simple get method     methods.get = function(callback) {         var response = null;          // Return the value of topic (property) in a callback         if (!!callback && typeof callback === 'function') {             if (_private.hasOwnProperty(topic)) {                 response = _private[topic];             }             callback.call(this, response);         }         return this;     };      // Init method setting the topic and returning the methods.     init = function(_topic) {         topic = _topic;          return methods;     };      // Exposure when being used in an AMD environment, e.g. RequireJS     if (typeof define === 'function' && define.amd) {         define(function() {             return init;         });         return;     }      // Exposure when being used with NodeJS     if ('undefined' !== typeof module && module.exports) {         module.exports = init;         return;     }      // Last-in-the-line exposure to the window, if it exists     window.myLib = init;      // This line either passes the `window` as an argument or     // an empty Object-literal if `window` is not defined. }(('undefined' !== typeof window) ? window : {})); 

And to see it in action:

myLib('something').set('made public, outside of the closure by the `get` method');  myLib('something').get(function(a){   console.log(a); }); 

Please also take a look at the way I am exposing myLib, taking into account where it's being run, and how it's being included.

EDIT 3 (7/2017):

As a full stack (w/Node.js) JavaScript engineer, and the advent of Browserify, I fully recommend the use of the Nodejs-style module pattern utilizing either Gulp or Grunt as a build system for compiling a multi-file (decoupled, smaller bits of code) into one library.

This model helps encourage a more functional approach, allowing developers to abstract more common functions within a library into separate files, making development a lot easier.

Oh, and use ES6!

// file: src/divideIntByFour.js  const divideIntByFour = (int) => {     return int / 4; };  module.exports = divideIntByFour; 

...As a siplified example

like image 175
honyovk Avatar answered Sep 23 '22 15:09

honyovk


Look at the JavaScript Module pattern.

http://www.adequatelygood.com/2010/3/JavaScript-Module-Pattern-In-Depth

You could consider making your library compatible with require.js, which is a framework for doing exactly this kind of thing.

http://requirejs.org

like image 45
Jim Blackler Avatar answered Sep 22 '22 15:09

Jim Blackler