1

I'm not sure I explained myself correctly. I have a generic class ussed by lots of *.js files let´s said TestClass.

class TestClass {   

constructor(a,b) {
    this.a = a || 0;
    this.b = b || 0;        
}
// methods 
suma(a,b)
 {
    return a+b;
 }  
} 

What I need is to use this "classic" class from several *.js files builded using "module pattern"

//const {moduloTest} = require("scripts/testClass.js"); doesn´t work even using the answer in How do I include a JavaScript file in another JavaScript file?

//import{TestClass} from "scripts/testClass.js"; doesn´t work ( even with the extension *.mjs)

example file :

var MyNameSpace = {};
MyNameSpace = (function () {

  // global variables
  var object1 = new TestClass();

  // Private methods      
  function PrivateMethod () {
   console.log("result = ", object1.suma(3,4));
  }

  //   ..........................................................
  // public methods
  return {
    init: function () {},   
    anotherPublicMethod: function () {}      
  } 
}());  

new edition to show how I had already included the call to namespace in a very simple html code

<!DOCTYPE html>
<html lang="en" >

<head>
  <meta charset="UTF-8">
  <title> module pattern with testClass. </title>

</head>


<!--here the call.-->
<body onload="moduloTest.init();"> 
  <script  src="scripts/ClasePrueba.js"></script>
  <script  src="scripts/modulePattern.js"></script>  

</body>

</html>
jballes
  • 41
  • 5
  • How does the other file declare (or export) your `MyClass`, and how are all these files loaded? Probably you can just write `new MyClass` and it will work. – Bergi Nov 17 '18 at 20:29
  • Im not sure what you mean. Objects are obviously implemented with new, ...even though there was not explicit in the first post. Now there is... – jballes Nov 18 '18 at 19:59
  • Are you running the scripts in node.js, or are you including them in a html page? (Or something else)? – Bergi Nov 18 '18 at 20:01
  • yes, in an html page – jballes Nov 18 '18 at 20:05
  • Im afraid you will recomend me to left this classic style and use the literal object javascript style, ... but it means lots of work. this is why Im asking for this not complete "clean code" – jballes Nov 18 '18 at 20:11
  • No, you don't need to use object literals, you can you `class` just fine. I never said anything about that. – Bergi Nov 18 '18 at 20:32
  • If you just have multiple ` – Bergi Nov 18 '18 at 20:33
  • `moduloTest.init()` won't work, it needs to be `MyNameSpace.init()`. Or is this not the actual code that is contained in your js files? Also, do you get any error messages in your developer tools? – Bergi Nov 19 '18 at 09:37

1 Answers1

1

Interesting question. I had to spent a couple of minutes to figure out how make it work. Sorry for using the old module syntax, I was too lazy to configure webpack, thus I needed an enviroment which would run through VSCode & node. I presume that it would work with the new import / export syntax as well:

The 'Module' file, simplified to serve as minimal example:

module.exports = {
  MyNameSpace: (function() {
    //global variables
    var p1 = 0;

    // Private methods
    function private() {
      return 'whatever';
    }      

    // Public methods
    function public() {
      p1 += 1;
      return p1;
    }

    return {
      public: public
    };
  })()
};

The file where we import the 'Module':

// Destructurizing is recommended, otherwise we need to call 
// our methods like MyNameSpace.MyNameSpace.init() 

const { MyNameSpace } = require("./Module.js");

console.log(MyNameSpace) // public: [Function: public] <-- No private methods or vars!
console.log(MyNameSpace.public()); // 1
console.log(MyNameSpace.public()); // 2
console.log(MyNameSpace.public()); // 3

Edit A code showing how to attach TestClassto global object, so it is accessible by other scripts (no import/export or bundling required):

HTML The important part is that the script with shared class is loaded first and synchronously. Then, when attached to global object, it is accessible to all others.

<!DOCTYPE html>
<html lang="en" >
  <head>
    <meta charset="UTF-8">
    <title> module pattern with testClass. </title>
    <script src="./TestClass.js"></script>
</head>
<script>
  alert(window.testClass.suma(1,2))
</script>
<body>
</body>
</html>

JS

class TestClass {
  constructor(a, b) {
    this.a = a || 0;
    this.b = b || 0;
  }
  // methods
  suma(a, b) {
    return a + b;
  }
}

window.testClass = new TestClass();
HynekS
  • 2,738
  • 1
  • 19
  • 34
  • 1
    OP does not seem to be working in an environment that supports CommonJS modules. – Bergi Nov 18 '18 at 20:34
  • 1
    Ah, I didn't notice (or was edited?). In that case I would consider attaching `MyNameSpace` to the global `window` object. It would be reachable for other scripts while still taking benefit of module pattern private / public properties. – HynekS Nov 18 '18 at 21:44
  • @Bergi what Im trying to use is a simply solution, just before the commonJS specifications and NodeJs.Just what is called "revealing module pattern". Should I deduce from your answer that using revealing module pattern I can not call an external file as a class and use its methods? – jballes Nov 19 '18 at 09:32
  • @HynekS with the risk of being too insistent and boring, I have edited the question again to include the html and the way in which I call the namespace from there. Is that what you were referring to? – jballes Nov 19 '18 at 09:36
  • I updated my answer. But honestly, I am not sure what you exactli ask for – I have a feeling that you are trying to solve too many problems at once. – HynekS Nov 19 '18 at 11:18