Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it a bad practice to use the requireJS module as a singleton?

I plan to use the following pattern to make use of the requireJS based module to act as a singleton. Please notice that classA returns an instance of type 'classA', whereas the rest of the classes classB, classC, and main return the type of the class from the module. All of these are classes based on the MooTools Class.

The idea is to use the classA as a globally available singleton, the methods are just fillers. Any thoughts if this is an acceptable pattern to use?

Will this come back to bite me at a later stage? I haven't tried to run r.js on the project yet, so I am a bit worried, and look for some advise.

    // classA.js     define([], function() {         var classA = new Class({              initialize: function (regionId) {                 // perform some Initialization.                 this.data = null;             },              doSomething: function(param) {                 // some thing.                 this.data = param;             }         };          return new classA();     });      // classB.js     define(["classA"], function(classA) {         var classB = new Class({              initialize: function (regionId) {                 // perform some Initialization.             },              doSomethingElse: function() {                 // some thing.                 classA.doSomething("Go back to Work Now!");             }         };          return classB;     });       // classC.js     define(["classA"], function(classA) {         var classB = new Class({              initialize: function (regionId) {                 // perform some Initialization.             },              doSomethingElse: function() {                 // some thing.                 classA.doSomething("Time to Play!");             }         };          return classC;     });       // main.js     define(["classA", "classB", "classC"], function(classA, classB, classC) {         var main = new Class({              initialize: function (regionId) {                 // perform some Initialization.                 this.b = new classB();                 this.c = new classC();             },              doEverything: function() {                 // some thing.                 this.b.doSomethingElse();                 classA.doSomething("Nap Time!");             }         };          return main;     }); 

Thanks much in advance...

like image 589
Karthik Avatar asked Mar 16 '12 07:03

Karthik


People also ask

Is RequireJS obsolete?

requirejs or other AMD based loaders are still good if you have some pretty old vanilla JS, they still work well. If you are developing some new UI/JS app you can use webpack.

What is the main purpose of the RequireJS framework?

RequireJS is a JavaScript library and file loader which manages the dependencies between JavaScript files and in modular programming. It also helps to improve the speed and quality of the code.

Is a module a singleton?

js modules can behave like Singletons, but they are not guaranteed to be always singleton. There are two reasons for this and both are mentioned in the official Node.


2 Answers

No, I cannot think of a reason against using singletons with require.js.

Your module definition should export the singleton. The way you do it is fine, since it's a singleton you might be also able to avoid the new. I use something like

define(function (require) {     var singleton = function () {         return {             ...         };     };     return singleton(); }); 

The first require to the module will load and export it. Some other module requiring your singleton will just reuse the already exported one.

like image 197
ggozad Avatar answered Sep 23 '22 07:09

ggozad


Will this come back to bite me at a later stage?

I started out with the pattern of the accepted answer here, but my single-page JavaScript app morphed into a main thread and a web worker because it was doing a lot of calculations and the page was not responsive.

As I moved some of the modules into the web worker, there was strange behavior. It took me a lot of time to figure it out, but I realized some of my requirejs modules (namely the singletons) were being loaded twice.

What I found out was that if a singleton module is required in the main thread and also in modules that run in a web worker, the singleton module will get loaded a second time in the web worker (and so it isn't really a singleton). One copy is in the main thread, the other in the web worker. If your singleton stores variables, you'll have two copies.

It all makes sense since the worker and main thread have separate address spaces (perhaps this is why I got a downvote?). I'm posting the answer here because someone might run into the same problem as there is no warning in requirejs.

The solution (in my case) was not to mix modules between the main and web worker thread. This can be a big design constraint that isn't necessarily a problem in environments such as Java or C#.

like image 41
Fuhrmanator Avatar answered Sep 25 '22 07:09

Fuhrmanator