简体   繁体   中英

requirejs loading same module twice

I'm using the single-page app template from https://github.com/volojs/create-template

I tried to make a simple example below.

Problem

ModuleA.js is being loaded twice, once directly from main.js and again from simulator.js which depends also on that module. This is causing two different references to an object (which I thought would only be one, like a singleton). I thought requirejs would not load the same module twice. Being (relatively) new to JavaScript I realize this may be naivete on my part. I'm trying to follow the template.

Here's a simplified version that demonstrates the problem:

www/index.html

<head>
...
    <script data-main="app" src="lib/require.js"></script>
</head>
...

www/app.js

// For any third party dependencies, like jQuery, place them in the lib folder.
// Configure loading modules from the lib directory,
// except for 'app' ones, which are in a sibling
// directory.

requirejs.config({
    baseUrl: 'lib',
    paths: {
        app: '../app'
    }
});

// Start loading the main app file. Put all of
// your application logic in there.
requirejs(['app/main']);

www/app/main.js

define(function (require) {
    var simulator = require('./simulator.js');
    var ModuleA = require('./ModuleA.js');

    ModuleA.init();
    ModuleA.displayList();
    ModuleA.update("joe", 99);
    ModuleA.displayList();

    simulator.start(); // should display the same list
});

www/app/ModuleA.js

define(function () {
    var theList = {};
    console.log("loading ModuleA");
    return {
        displayList: function () {
            console.log(Object.keys(theList));
        },
        init : function () {
            theList["fred"] = 10;
        },
        update : function (k, v) {
            theList[k] = v;
        }
    }
});

www/app/simulator.js

define(["./ModuleA"], function (ModuleA) {
  return {
    start: function () {
      ModuleA.displayList();
    }
  };
});

console output:

loading ModuleA
loading ModuleA
["fred"]
["fred", "joe"]
[]

The empty [] displayed on the last line is (likely) the second copy of the list due to the second loading of ModuleA .

The problem is the module references are not consistent. In main.js it requires ./ModuleA.js whereas in simulator.js it defines ./ModuleA (without the .js filetype).

Making those references identical corrects the behavior such that the module is only loaded once.

I guess I mixed the styles because of the many examples on the web. It kind of seems like a bug that it works this way, but maybe it's a feature?

If you want to share an instantiated singleton object using requireJS, you can do something like this for ModuleA:

define(function () {
  console.log("loading ModuleA");
  function myList(){
    this.theList = {}
  } 
  myList.prototype.displayList = function () { 
      console.log(Object.keys(this.theList));
  } 
  myList.prototype.init = function () { 
      this.theList["fred"] = 10;
  } 
  myList.prototype.update = function (k, v) { 
      this.theList[k] = v;
  } 
  return new myList();
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM